import {compose} from '@avocado/core'; import {Vector} from '@avocado/math'; import {EventEmitter} from '@avocado/mixins'; import {Trait} from '../trait'; const decorate = compose( EventEmitter, Vector.Mixin('_position', 'x', 'y', { track: true, }), ); // < 16768 will pack into 1 short per axe and give +/- 0.25 precision. class PositionedBase extends Trait { static defaultState() { return { x: 0, y: 0, }; } initialize() { this.on('_positionChanged', (oldPosition, newPosition) => { const x = Math.floor(newPosition[0]) * 4; const y = Math.floor(newPosition[1]) * 4; this.state = this.state.withMutations((state) => { state.set('x', x).set('y', y); }); this.entity.emit('positionChanged', oldPosition, newPosition); }); const x = this.state.get('x') / 4; const y = this.state.get('y') / 4; this._position = [x, y]; } get position() { return this._position; } set position(position) { this._position = position; } transformPatchValue(key, value) { if (-1 !== ['x', 'y'].indexOf(key)) { return value / 4; } super.transformPatchValue(key, value); } get x() { return this.x; } set x(x) { this.x = x; } get y() { return this.y; } set y(y) { this.y = y; } } export class Positioned extends decorate(PositionedBase) {}