avocado-old/packages/topdown/tileset.js
2019-03-25 23:05:22 -05:00

92 lines
1.9 KiB
JavaScript

import {compose} from '@avocado/core';
import {hasGraphics, Image} from '@avocado/graphics';
import {Rectangle, Vector} from '@avocado/math';
import {Resource} from '@avocado/resource';
const decorate = compose(
Vector.Mixin('tileSize', 'tileWidth', 'tileHeight', {
default: [0, 0],
}),
);
export class Tileset extends decorate(Resource) {
constructor() {
super();
this._image = undefined;
this.subimages = [];
}
destroy() {
this.subimages.forEach((sprite) => {
sprite.destroy();
});
this.subimages = [];
}
fromJSON(json) {
let promise;
if (json.tileSize) {
this.tileSize = json.tileSize;
}
if (hasGraphics && json.imageUri) {
promise = Image.load(json.imageUri).then((image) => {
this.image = image;
});
}
return Promise.resolve(promise).then(() => {
return this;
});
}
get image() {
return this._image;
}
set image(image) {
this._image = image
this.recalculateSubimages();
}
recalculateSubimages() {
const image = this._image;
const tileSize = this.tileSize;
if (!image || Vector.isZero(tileSize)) {
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];
}
}
subimage(index) {
return this.subimages[index];
}
get tileSize() {
return super.tileSize;
}
set tileSize(tileSize) {
super.tileSize = tileSize;
this.recalculateSubimages();
}
toJSON() {
return {
tileSize: this.tileSize,
imageUri: this.image.uri,
}
}
}