feat: re-render on layer tile data change
This commit is contained in:
parent
4825bd2494
commit
9a153dd90d
|
@ -1,4 +1,5 @@
|
|||
import {Container, Sprite} from '@avocado/graphics';
|
||||
import {Vector} from '@avocado/math';
|
||||
import {Layer, Tileset, TilesRenderer} from '@avocado/topdown';
|
||||
|
||||
export class LayerView extends Container {
|
||||
|
@ -18,6 +19,9 @@ export class LayerView extends Container {
|
|||
for (const entity of layer.entityList) {
|
||||
this.onEntityAdded(entity);
|
||||
}
|
||||
// Watch tile data change.
|
||||
this.onTileDataChanged = this.onTileDataChanged.bind(this);
|
||||
layer.on('tileDataChanged', this.onTileDataChanged);
|
||||
// Watch tileset URI change.
|
||||
this.onTilesetUriChanged = this.onTilesetUriChanged.bind(this);
|
||||
layer.on('tilesetUriChanged', this.onTilesetUriChanged);
|
||||
|
@ -46,6 +50,10 @@ export class LayerView extends Container {
|
|||
}
|
||||
}
|
||||
|
||||
onTileDataChanged() {
|
||||
this.render();
|
||||
}
|
||||
|
||||
onTilesetUriChanged() {
|
||||
if (!this.layer.tilesetUri) {
|
||||
return;
|
||||
|
@ -55,13 +63,26 @@ export class LayerView extends Container {
|
|||
});
|
||||
}
|
||||
|
||||
set tileset(tileset) {
|
||||
this._tileset = tileset;
|
||||
const tilesRenderer = new TilesRenderer(this.layer.tiles, tileset);
|
||||
render() {
|
||||
this.layerContainer.removeAllChildren();
|
||||
if (!this._renderer) {
|
||||
return;
|
||||
}
|
||||
if (!this._tileset) {
|
||||
return;
|
||||
}
|
||||
if (Vector.isZero(this.layer.tiles.size)) {
|
||||
return;
|
||||
}
|
||||
const tilesRenderer = new TilesRenderer(this.layer.tiles, this._tileset);
|
||||
const chunk = tilesRenderer.renderChunk(this._renderer);
|
||||
const tilesSprite = new Sprite(chunk);
|
||||
this.layerContainer.removeAllChildren();
|
||||
this.layerContainer.addChild(tilesSprite);
|
||||
}
|
||||
|
||||
set tileset(tileset) {
|
||||
this._tileset = tileset;
|
||||
this.render();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,6 +24,8 @@ export class Layer extends decorate(class {}) {
|
|||
this.onEntityRemovedFromLayer = this.onEntityRemovedFromLayer.bind(this);
|
||||
this.entityList.on('entityAdded', this.onEntityAddedToLayer);
|
||||
this.entityList.on('entityRemoved', this.onEntityRemovedFromLayer);
|
||||
this.onTileDataChanged = this.onTileDataChanged.bind(this);
|
||||
this.tiles.on('dataChanged', this.onTileDataChanged);
|
||||
}
|
||||
|
||||
acceptStateChange(change) {
|
||||
|
@ -81,10 +83,18 @@ export class Layer extends decorate(class {}) {
|
|||
this.emit('entityRemoved', entity);
|
||||
}
|
||||
|
||||
onTileDataChanged() {
|
||||
this.emit('tileDataChanged');
|
||||
}
|
||||
|
||||
removeEntity(entity) {
|
||||
this.entityList.removeEntity(entity);
|
||||
}
|
||||
|
||||
setTileAt(x, y, tile) {
|
||||
this.tiles.setTileAt(x, y, tile);
|
||||
}
|
||||
|
||||
get state() {
|
||||
return this._state;
|
||||
}
|
||||
|
|
|
@ -2,8 +2,10 @@ import * as I from 'immutable';
|
|||
|
||||
import {compose} from '@avocado/core';
|
||||
import {Rectangle, Vector} from '@avocado/math';
|
||||
import {EventEmitter} from '@avocado/mixins';
|
||||
|
||||
const decorate = compose(
|
||||
EventEmitter,
|
||||
Vector.Mixin('size', 'width', 'height', {
|
||||
default: [0, 0],
|
||||
}),
|
||||
|
@ -13,6 +15,7 @@ export class Tiles extends decorate(class {}) {
|
|||
|
||||
constructor() {
|
||||
super();
|
||||
this.data = I.List();
|
||||
this._sizeState = I.List();
|
||||
this._state = I.Map();
|
||||
}
|
||||
|
@ -22,7 +25,14 @@ export class Tiles extends decorate(class {}) {
|
|||
this.size = change.size;
|
||||
}
|
||||
if (change.data) {
|
||||
this.data = change.data;
|
||||
const oldData = this.data;
|
||||
for (const i in change.data) {
|
||||
const index = parseInt(i);
|
||||
this.data = this.data.set(index, change.data[i]);
|
||||
}
|
||||
if (oldData !== this.data) {
|
||||
this.emit('dataChanged');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -31,7 +41,7 @@ export class Tiles extends decorate(class {}) {
|
|||
this.size = json.size;
|
||||
}
|
||||
if (json.data) {
|
||||
this.data = json.data;
|
||||
this.data = I.fromJS(json.data);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
@ -41,11 +51,16 @@ export class Tiles extends decorate(class {}) {
|
|||
}
|
||||
|
||||
setTileAt(x, y, tile) {
|
||||
const index = y * this.width + x;
|
||||
if (index < 0 || index >= this.data.length) {
|
||||
const oldTile = this.tileAt(x, y);
|
||||
if (oldTile === tile) {
|
||||
return;
|
||||
}
|
||||
this.data[index] = tile;
|
||||
const index = y * this.width + x;
|
||||
if (index < 0 || index >= this.data.size) {
|
||||
return;
|
||||
}
|
||||
this.data = this.data.set(index, tile);
|
||||
this.emit('dataChanged');
|
||||
}
|
||||
|
||||
slice(rectangle) {
|
||||
|
@ -66,7 +81,7 @@ export class Tiles extends decorate(class {}) {
|
|||
const slice = new Array(sliceWidth * sliceHeight);
|
||||
for (let j = 0; j < sliceHeight; ++j) {
|
||||
for (let i = 0; i < sliceWidth; ++i) {
|
||||
slice[sliceRow + x] = this.data[dataRow + x];
|
||||
slice[sliceRow + x] = this.data.get(dataRow + x);
|
||||
x++;
|
||||
}
|
||||
sliceRow += sliceWidth;
|
||||
|
@ -88,13 +103,13 @@ export class Tiles extends decorate(class {}) {
|
|||
}
|
||||
|
||||
tileAt(x, y) {
|
||||
return this.data[y * this.width + x];
|
||||
return this.data.get(y * this.width + x);
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
return {
|
||||
size: [...this.size],
|
||||
data: [...this.data],
|
||||
data: [...this.data.toJS()],
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user