86 lines
1.8 KiB
JavaScript
86 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.appliedMovement = [0, 0];
|
|
}
|
|
|
|
methods() {
|
|
return {
|
|
|
|
moveFor: (vector, duration) => {
|
|
let resolve;
|
|
const promise = new TickingPromise(_resolve => resolve = _resolve);
|
|
promise.ticker = (elapsed) => {
|
|
duration -= elapsed;
|
|
if (duration <= 0) {
|
|
return resolve();
|
|
}
|
|
this.entity.requestMovement(Vector.normalize(vector));
|
|
}
|
|
return promise;
|
|
},
|
|
|
|
applyMovement: (vector) => {
|
|
this.appliedMovement = Vector.add(this.appliedMovement, vector);
|
|
},
|
|
|
|
forceMovement: (movement) => {
|
|
this.entity.x += movement[0];
|
|
this.entity.y += movement[1];
|
|
},
|
|
|
|
requestMovement: (vector) => {
|
|
if (!this.isMobile) {
|
|
return;
|
|
}
|
|
this.entity.applyMovement(Vector.scale(
|
|
Vector.normalize(vector),
|
|
this.speed
|
|
));
|
|
this.entity.emit('movementRequest', this.appliedMovement);
|
|
},
|
|
|
|
}
|
|
}
|
|
|
|
tick(elapsed) {
|
|
if (Vector.isZero(this.appliedMovement)) {
|
|
return;
|
|
}
|
|
if (this.entity.is('physical')) {
|
|
this.entity.applyImpulse(this.appliedMovement);
|
|
}
|
|
else {
|
|
const appliedMovement = Vector.scale(
|
|
this.appliedMovement,
|
|
elapsed
|
|
);
|
|
this.entity.forceMovement(appliedMovement);
|
|
}
|
|
this.appliedMovement = [0, 0];
|
|
}
|
|
|
|
}
|