avocado-old/packages/topdown/traits/layered.trait.js
2020-06-23 11:19:59 -05:00

125 lines
2.5 KiB
JavaScript

import {Trait} from '@avocado/entity';
import {Vector} from '@avocado/math';
export default class Layered extends Trait {
static behaviorTypes() {
return {
layer: {
type: 'layer',
label: 'Layer',
},
removeFromLayer: {
type: 'void',
label: 'Remove from layer.',
},
setIntoLayer: {
type: 'void',
label: 'Set into layer $1.',
args: [
['layer', {
type: 'layer',
}],
],
},
};
}
static type() {
return 'layered';
}
constructor(entity, params, state) {
super(entity, params, state);
this.entity.layer = null;
this._tile = [0, 0];
this._tileOffset = [0, 0];
this.setCurrentTileFromLayer();
}
destroy() {
this.entity.removeFromLayer();
}
get tile() {
return this._tile;
}
get tileOffset() {
return this._tileOffset;
}
onLayerTilesetChanged() {
this.setCurrentTileFromLayer();
}
setCurrentTileFromLayer() {
const layer = this.entity.layer;
if (!layer) {
return;
}
if (!this.entity.is('positioned')) {
return;
}
const tileset = layer.tileset;
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() {
return {
positionChanged: () => {
this.setCurrentTileFromLayer();
},
traitAdded: () => {
this.setCurrentTileFromLayer();
},
}
}
methods() {
return {
removeFromLayer: () => {
const layer = this.entity.layer;
if (!layer) {
return;
}
layer.off('tilesetChanged', this.onLayerTilesetChanged);
this.entity.layer = null;
this.entity.emit('removedFromLayer', layer);
},
setIntoLayer: (layer) => {
this.entity.layer = layer;
layer.on('tilesetChanged', this.onLayerTilesetChanged, this);
this.setCurrentTileFromLayer();
this.entity.emit('addedToLayer');
},
};
}
}