import {compose, TickingPromise} from '@avocado/core'; import {Vector} from '@avocado/math'; import {StateProperty, Trait} from '../trait'; const decorate = compose( StateProperty('isMobile'), StateProperty('speed'), ) export class Mobile extends decorate(Trait) { static defaultState() { return { isMobile: true, speed: 0, }; } static type() { return 'mobile'; } constructor(entity, params, state) { super(entity, params, state); this.requestedMovement = [0, 0]; } methods() { return { moveFor: (duration) => { const direction = Math.floor(Math.random() * 4); let resolve; const promise = new TickingPromise(_resolve => resolve = _resolve); promise.ticker = (elapsed) => { duration -= elapsed; if (duration <= 0) { return resolve(); } this.entity.requestMovement(Vector.fromDirection(direction)); } return promise; }, applyMovement: (movement) => { this.entity.x += movement[0]; this.entity.y += movement[1]; }, requestMovement: (vector) => { if (!this.isMobile) { return; } this.requestedMovement = Vector.scale( Vector.normalize(vector), this.speed ); this.entity.emit('movementRequest', this.requestedMovement); }, } } tick(elapsed) { if (Vector.isZero(this.requestedMovement)) { return; } if (this.entity.is('physical')) { this.entity.applyImpulse(this.requestedMovement); } else { const requestedMovement = Vector.scale( this.requestedMovement, elapsed ); this.entity.applyMovement(requestedMovement); } this.requestedMovement = [0, 0]; } }