2019-05-16 19:42:03 -05:00
|
|
|
import {compose, EventEmitter, Property} from '@avocado/core';
|
2019-03-25 23:05:22 -05:00
|
|
|
import {hasGraphics, Image} from '@avocado/graphics';
|
|
|
|
import {Rectangle, Vector} from '@avocado/math';
|
2019-04-12 20:16:31 -05:00
|
|
|
import {shapeFromJSON} from '@avocado/physics';
|
2019-03-25 23:05:22 -05:00
|
|
|
import {Resource} from '@avocado/resource';
|
2019-03-25 19:03:34 -05:00
|
|
|
|
|
|
|
const decorate = compose(
|
2019-05-16 19:42:03 -05:00
|
|
|
EventEmitter,
|
|
|
|
Property('image', {
|
|
|
|
track: true,
|
|
|
|
}),
|
2019-03-25 19:03:34 -05:00
|
|
|
Vector.Mixin('tileSize', 'tileWidth', 'tileHeight', {
|
|
|
|
default: [0, 0],
|
|
|
|
}),
|
|
|
|
);
|
|
|
|
|
2019-03-25 23:05:22 -05:00
|
|
|
export class Tileset extends decorate(Resource) {
|
2019-03-25 19:03:34 -05:00
|
|
|
|
2019-05-16 19:42:35 -05:00
|
|
|
constructor(json) {
|
2019-03-25 23:05:22 -05:00
|
|
|
super();
|
2019-04-12 20:16:31 -05:00
|
|
|
this._geometry = {};
|
2019-03-25 19:03:34 -05:00
|
|
|
this.subimages = [];
|
2019-05-16 19:42:35 -05:00
|
|
|
if ('undefined' !== typeof json) {
|
|
|
|
this.fromJSON(json);
|
|
|
|
}
|
2019-03-25 19:03:34 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
destroy() {
|
2019-04-14 16:10:24 -05:00
|
|
|
this.subimages.forEach((subimage) => {
|
|
|
|
subimage.destroy();
|
2019-03-25 19:03:34 -05:00
|
|
|
});
|
|
|
|
this.subimages = [];
|
|
|
|
}
|
|
|
|
|
2019-03-25 23:05:22 -05:00
|
|
|
fromJSON(json) {
|
|
|
|
let promise;
|
2019-04-12 20:16:31 -05:00
|
|
|
if (json.geometry) {
|
|
|
|
for (const i in json.geometry) {
|
|
|
|
const shapeJSON = json.geometry[i];
|
|
|
|
this._geometry[i] = shapeFromJSON(shapeJSON);
|
|
|
|
}
|
|
|
|
}
|
2019-03-25 23:05:22 -05:00
|
|
|
if (json.tileSize) {
|
|
|
|
this.tileSize = json.tileSize;
|
|
|
|
}
|
|
|
|
if (hasGraphics && json.imageUri) {
|
2019-05-16 19:42:03 -05:00
|
|
|
Image.load(json.imageUri).then((image) => {
|
2019-03-25 23:05:22 -05:00
|
|
|
this.image = image;
|
|
|
|
});
|
|
|
|
}
|
2019-03-25 19:03:34 -05:00
|
|
|
}
|
|
|
|
|
2019-04-12 20:16:31 -05:00
|
|
|
geometry(index) {
|
|
|
|
return this._geometry[index];
|
|
|
|
}
|
|
|
|
|
2019-03-25 23:05:22 -05:00
|
|
|
get image() {
|
2019-05-16 19:42:03 -05:00
|
|
|
return super.image;
|
2019-03-25 19:03:34 -05:00
|
|
|
}
|
|
|
|
|
2019-03-25 23:05:22 -05:00
|
|
|
set image(image) {
|
2019-05-16 19:42:03 -05:00
|
|
|
this.recalculateSubimages(image);
|
|
|
|
super.image = image;
|
2019-03-25 19:03:34 -05:00
|
|
|
}
|
|
|
|
|
2019-05-16 19:42:03 -05:00
|
|
|
recalculateSubimages(image) {
|
|
|
|
if (!image) {
|
|
|
|
return;
|
|
|
|
}
|
2019-03-25 23:05:22 -05:00
|
|
|
const tileSize = this.tileSize;
|
2019-05-16 19:42:03 -05:00
|
|
|
if (Vector.isZero(tileSize)) {
|
2019-03-25 23:05:22 -05:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
this.destroy();
|
|
|
|
const grid = Vector.div(image.size, tileSize);
|
|
|
|
const rectangle = Rectangle.compose([0, 0], tileSize);
|
|
|
|
for (let j = 0; j < grid[1]; ++j) {
|
|
|
|
for (let i = 0; i < grid[0]; ++i) {
|
|
|
|
const subimage = image.subimage(rectangle);
|
|
|
|
this.subimages.push(subimage);
|
|
|
|
rectangle[0] += tileSize[0];
|
|
|
|
}
|
|
|
|
rectangle[0] = 0;
|
|
|
|
rectangle[1] += tileSize[1];
|
|
|
|
}
|
|
|
|
}
|
2019-03-25 19:03:34 -05:00
|
|
|
|
2019-03-25 23:05:22 -05:00
|
|
|
subimage(index) {
|
|
|
|
return this.subimages[index];
|
|
|
|
}
|
2019-03-25 19:03:34 -05:00
|
|
|
|
|
|
|
get tileSize() {
|
|
|
|
return super.tileSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
set tileSize(tileSize) {
|
|
|
|
super.tileSize = tileSize;
|
2019-05-16 19:42:03 -05:00
|
|
|
this.recalculateSubimages(this.image);
|
2019-03-25 23:05:22 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
toJSON() {
|
|
|
|
return {
|
|
|
|
tileSize: this.tileSize,
|
|
|
|
imageUri: this.image.uri,
|
|
|
|
}
|
2019-03-25 19:03:34 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|