avocado-old/packages/topdown/tileset.js

109 lines
2.2 KiB
JavaScript
Raw Permalink Normal View History

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(
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
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 = [];
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) {
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() {
return super.image;
2019-03-25 19:03:34 -05:00
}
2019-03-25 23:05:22 -05:00
set image(image) {
this.recalculateSubimages(image);
super.image = image;
2019-03-25 19:03:34 -05:00
}
recalculateSubimages(image) {
if (!image) {
return;
}
2019-03-25 23:05:22 -05:00
const tileSize = this.tileSize;
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;
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
}
}