feat: tile entities
This commit is contained in:
parent
0984263edb
commit
7b61569a2f
|
@ -29,6 +29,7 @@ export class Layer extends decorate(class {}) {
|
||||||
super();
|
super();
|
||||||
this.entityList = new EntityList();
|
this.entityList = new EntityList();
|
||||||
this.index = -1;
|
this.index = -1;
|
||||||
|
this.tileEntities = {};
|
||||||
this.tileGeometry = [];
|
this.tileGeometry = [];
|
||||||
this.tiles = new Tiles();
|
this.tiles = new Tiles();
|
||||||
// Listeners.
|
// Listeners.
|
||||||
|
@ -56,6 +57,16 @@ export class Layer extends decorate(class {}) {
|
||||||
this.entityList.addEntity(entity);
|
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() {
|
addTileGeometry() {
|
||||||
const tileset = this.tileset;
|
const tileset = this.tileset;
|
||||||
if (!tileset) {
|
if (!tileset) {
|
||||||
|
@ -115,6 +126,21 @@ export class Layer extends decorate(class {}) {
|
||||||
return this;
|
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) {
|
onEntityAddedToLayer(entity) {
|
||||||
entity.setIntoLayer(this);
|
entity.setIntoLayer(this);
|
||||||
this.emit('entityAdded', entity)
|
this.emit('entityAdded', entity)
|
||||||
|
@ -190,6 +216,17 @@ export class Layer extends decorate(class {}) {
|
||||||
this.entityList.removeEntity(entity);
|
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() {
|
removeTileGeometry() {
|
||||||
// ... tag geometry in world for removal?
|
// ... tag geometry in world for removal?
|
||||||
}
|
}
|
||||||
|
@ -206,6 +243,14 @@ export class Layer extends decorate(class {}) {
|
||||||
return this.tiles.tileAt(position);
|
return this.tiles.tileAt(position);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
tileEntitiesAt(tilePosition) {
|
||||||
|
const index = this.indexAt(tilePosition);
|
||||||
|
if (!this.tileEntities[index]) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return this.tileEntities[index];
|
||||||
|
}
|
||||||
|
|
||||||
toJSON() {
|
toJSON() {
|
||||||
return {
|
return {
|
||||||
tilesetUri: this.tilesetUri,
|
tilesetUri: this.tilesetUri,
|
||||||
|
|
|
@ -43,14 +43,22 @@ export class Layered extends Trait {
|
||||||
if (!tileset) {
|
if (!tileset) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const oldTile = Vector.copy(this._tile);
|
||||||
this._tile = Vector.div(
|
this._tile = Vector.div(
|
||||||
this.entity.position,
|
this.entity.position,
|
||||||
tileset.tileSize,
|
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._tileOffset = Vector.mod(
|
||||||
this.entity.position,
|
this.entity.position,
|
||||||
tileset.tileSize,
|
tileset.tileSize,
|
||||||
);
|
);
|
||||||
|
if (!Vector.equals(oldTileOffset, this._tileOffset)) {
|
||||||
|
this.entity.emit('tileOffsetChanged', oldTileOffset, this._tileOffset);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
listeners() {
|
listeners() {
|
||||||
|
@ -83,6 +91,7 @@ export class Layered extends Trait {
|
||||||
setIntoLayer: (layer) => {
|
setIntoLayer: (layer) => {
|
||||||
this.entity.layer = layer;
|
this.entity.layer = layer;
|
||||||
layer.on('tilesetChanged', this.onLayerTilesetChanged, this);
|
layer.on('tilesetChanged', this.onLayerTilesetChanged, this);
|
||||||
|
this.setCurrentTileFromLayer();
|
||||||
this.entity.emit('addedToLayer');
|
this.entity.emit('addedToLayer');
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
79
packages/topdown/traits/tile-entity.trait.js
Normal file
79
packages/topdown/traits/tile-entity.trait.js
Normal 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();
|
||||||
|
},
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user