refactor: tileset

This commit is contained in:
cha0s 2019-03-25 23:05:22 -05:00
parent 77042bfa8c
commit 26fa5e4589
2 changed files with 63 additions and 43 deletions

View File

@ -26,9 +26,13 @@ export class TilesRenderer {
const position = [0, 0];
for (let i = 0; i < slice.length; ++i) {
const index = slice[i];
const sprite = new Sprite(this.tileset.subimages[index]);
sprite.position = position;
container.addChild(sprite);
// Lookup subimage.
const subimage = this.tileset.subimage(index);
if (subimage) {
const sprite = new Sprite(subimage);
sprite.position = position;
container.addChild(sprite);
}
// Only adds, please.
position[0] += tileSize[0];
if (rowWidth === position[0]) {

View File

@ -1,5 +1,7 @@
import {compose} from '@avocado/core';
import {Vector} from '@avocado/math';
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', {
@ -7,13 +9,12 @@ const decorate = compose(
}),
);
class TilesetBase {
export class Tileset extends decorate(Resource) {
constructor(image) {
this.image = image;
this._rowWidth = 0;
constructor() {
super();
this._image = undefined;
this.subimages = [];
this._tilesCount = 0;
}
destroy() {
@ -23,53 +24,68 @@ class TilesetBase {
this.subimages = [];
}
get rowWidth() {
return this._rowWidth;
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;
});
}
set tileIndex(index) {
get image() {
return this._image;
}
set image(image) {
this._image = image
this.recalculateSubimages();
}
recalculateSubimages() {
const image = this._image;
const tileSize = this.tileSize;
const x = index % this._rowWidth;
const y = Math.floor(index / this._rowWidth)
const sourceRectangle = [
x * tileSize[0],
y * tileSize[1],
tileSize[0],
tileSize[1],
];
this.sourceRectangle = sourceRectangle;
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];
}
}
get tilesCount() {
return this._tilesCount;
subimage(index) {
return this.subimages[index];
}
}
export class Tileset extends decorate(TilesetBase) {
get tileSize() {
return super.tileSize;
}
set tileSize(tileSize) {
const image = this.image;
const grid = Vector.div(image.size, tileSize);
this.destroy();
for (let y = 0; y < grid[1]; ++y) {
for (let x = 0; x < grid[0]; ++x) {
const subimage = image.subimage([
x * tileSize[0],
y * tileSize[1],
tileSize[0],
tileSize[1],
]);
this.subimages.push(subimage);
}
}
this._tilesCount = Vector.area(grid);
this._rowWidth = grid[0];
super.tileSize = tileSize;
this.recalculateSubimages();
}
toJSON() {
return {
tileSize: this.tileSize,
imageUri: this.image.uri,
}
}
}