avocado-old/packages/entity/traits/mobile.trait.js
2019-05-26 12:01:58 -05:00

83 lines
1.8 KiB
JavaScript

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 = this.entity.direction;
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];
}
}