feat: tile entities

This commit is contained in:
cha0s 2019-06-12 22:22:22 -05:00
parent 0984263edb
commit 7b61569a2f
3 changed files with 133 additions and 0 deletions

View File

@ -29,6 +29,7 @@ export class Layer extends decorate(class {}) {
super();
this.entityList = new EntityList();
this.index = -1;
this.tileEntities = {};
this.tileGeometry = [];
this.tiles = new Tiles();
// Listeners.
@ -56,6 +57,16 @@ export class Layer extends decorate(class {}) {
this.entityList.addEntity(entity);
}
addTileEntity(entity, index) {
if (!this.tileEntities[index]) {
this.tileEntities[index] = [];
}
if (-1 !== this.tileEntities[index].indexOf(entity)) {
return;
}
this.tileEntities[index].push(entity);
}
addTileGeometry() {
const tileset = this.tileset;
if (!tileset) {
@ -115,6 +126,21 @@ export class Layer extends decorate(class {}) {
return this;
}
hasTileEntityWithUriAt(tilePosition, uri) {
const tileEntities = this.tileEntitiesAt(tilePosition);
if (0 === tileEntities.length) {
return false;
}
const entitiesWithUri = tileEntities.filter((entity) => {
return entity.uri === uri;
});
return entitiesWithUri.length > 0;
}
indexAt(position) {
return this.tiles.indexAt(position);
}
onEntityAddedToLayer(entity) {
entity.setIntoLayer(this);
this.emit('entityAdded', entity)
@ -190,6 +216,17 @@ export class Layer extends decorate(class {}) {
this.entityList.removeEntity(entity);
}
removeTileEntity(entity, index) {
if (!this.tileEntities[index]) {
return;
}
const entityIndex = this.tileEntities[index].indexOf(entity);
if (-1 === entityIndex) {
return;
}
this.tileEntities[index].splice(entityIndex, 1);
}
removeTileGeometry() {
// ... tag geometry in world for removal?
}
@ -206,6 +243,14 @@ export class Layer extends decorate(class {}) {
return this.tiles.tileAt(position);
}
tileEntitiesAt(tilePosition) {
const index = this.indexAt(tilePosition);
if (!this.tileEntities[index]) {
return [];
}
return this.tileEntities[index];
}
toJSON() {
return {
tilesetUri: this.tilesetUri,

View File

@ -43,14 +43,22 @@ export class Layered extends Trait {
if (!tileset) {
return;
}
const oldTile = Vector.copy(this._tile);
this._tile = Vector.div(
this.entity.position,
tileset.tileSize,
);
if (!Vector.equals(oldTile, this._tile)) {
this.entity.emit('tileChanged', oldTile, this._tile);
}
const oldTileOffset = Vector.copy(this._tileOffset);
this._tileOffset = Vector.mod(
this.entity.position,
tileset.tileSize,
);
if (!Vector.equals(oldTileOffset, this._tileOffset)) {
this.entity.emit('tileOffsetChanged', oldTileOffset, this._tileOffset);
}
}
listeners() {
@ -83,6 +91,7 @@ export class Layered extends Trait {
setIntoLayer: (layer) => {
this.entity.layer = layer;
layer.on('tilesetChanged', this.onLayerTilesetChanged, this);
this.setCurrentTileFromLayer();
this.entity.emit('addedToLayer');
},

View File

@ -0,0 +1,79 @@
import {compose, Property} from '@avocado/core';
import {StateProperty, Trait} from '@avocado/entity';
import {Vector} from '@avocado/math';
const decorate = compose(
StateProperty('tileIndex', {
track: true,
}),
);
export class TileEntity extends decorate(Trait) {
static defaultState() {
return {
tileIndex: 0,
};
}
static type() {
return 'tile-entity';
}
destroy() {
this.removeTileEntity(this.entity.tileIndex);
}
addTileEntity(tileIndex) {
const layer = this.entity.layer;
if (!layer) {
return;
}
layer.addTileEntity(this.entity, tileIndex);
}
removeTileEntity(tileIndex) {
const layer = this.entity.layer;
if (!layer) {
return;
}
layer.removeTileEntity(this.entity, tileIndex);
}
setTileIndex() {
if (!this.entity.layer) {
return;
}
this.entity.tileIndex = this.entity.layer.indexAt(
Vector.floor(this.entity.tile)
);
}
listeners() {
return {
addedToLayer: (layer) => {
this.setTileIndex();
},
removedFromLayer: (layer) => {
layer.removeTileEntity(this.entity, Vector.floor(this.entity.tile));
},
tileChanged: () => {
this.setTileIndex();
},
tileIndexChanged: (oldTileIndex, newTileIndex) => {
this.removeTileEntity(oldTileIndex);
this.addTileEntity(newTileIndex);
},
traitAdded: (type) => {
this.setTileIndex();
},
};
}
}