2019-04-14 16:33:26 -05:00
|
|
|
import {compose} from '@avocado/core';
|
2019-04-19 21:21:41 -05:00
|
|
|
import {Stage} from '@avocado/graphics';
|
2019-04-14 16:33:26 -05:00
|
|
|
import {EventEmitter, Property} from '@avocado/mixins';
|
2019-04-19 21:21:41 -05:00
|
|
|
import {World} from '@avocado/physics/matter/world';
|
|
|
|
import {Room, RoomView} from '@avocado/topdown';
|
|
|
|
|
|
|
|
import {WorldTime} from '../common/world-time';
|
2019-04-14 16:33:26 -05:00
|
|
|
|
|
|
|
const decorate = compose(
|
|
|
|
EventEmitter,
|
2019-04-14 16:46:22 -05:00
|
|
|
Property('isDebugging', {
|
|
|
|
track: true,
|
|
|
|
}),
|
2019-04-14 16:33:26 -05:00
|
|
|
Property('selfEntity', {
|
|
|
|
track: true,
|
|
|
|
}),
|
2019-04-19 19:48:53 -05:00
|
|
|
Property('selfEntityUuid', {
|
|
|
|
track: true,
|
|
|
|
}),
|
2019-04-14 16:33:26 -05:00
|
|
|
);
|
|
|
|
|
2019-04-19 20:01:06 -05:00
|
|
|
export class App extends decorate(class {}) {
|
|
|
|
|
2019-04-19 21:21:41 -05:00
|
|
|
constructor() {
|
|
|
|
super();
|
|
|
|
const config = this.readConfig();
|
|
|
|
// Physics.
|
|
|
|
this.world = config.doPhysicsSimulation ? new World() : undefined;
|
|
|
|
// Room.
|
|
|
|
this.room = new Room();
|
|
|
|
this.room.world = this.world;
|
|
|
|
// Graphics stage.
|
|
|
|
this.stage = new Stage(config.visibleSize, config.visibleScale);
|
|
|
|
// World time.
|
|
|
|
this.worldTime = new WorldTime();
|
|
|
|
// Room view.
|
|
|
|
const roomView = new RoomView(this.room, this.stage.renderer);
|
|
|
|
this.stage.addChild(roomView);
|
|
|
|
// Listen for new entities.
|
|
|
|
this.room.on('entityAdded', this.onRoomEntityAdded, this);
|
|
|
|
}
|
|
|
|
|
|
|
|
injectStageIntoDom(node) {
|
|
|
|
// Lol, Apple...
|
|
|
|
node.addEventListener('touchmove', (event) => {
|
|
|
|
event.preventDefault();
|
|
|
|
});
|
|
|
|
this.stage.addToDom(node);
|
|
|
|
}
|
|
|
|
|
|
|
|
onRoomEntityAdded(entity) {
|
|
|
|
// Traits that shouldn't be on client.
|
|
|
|
const noClientTraits = [
|
|
|
|
'behaved',
|
|
|
|
'informed',
|
|
|
|
];
|
|
|
|
// If there's no physics, then remove physical trait.
|
|
|
|
if (!this.room.world) {
|
|
|
|
noClientTraits.push('physical');
|
|
|
|
}
|
|
|
|
// Traits that only make sense for our self entity on the client.
|
|
|
|
const selfEntityOnlyTraits = [
|
|
|
|
'controllable',
|
|
|
|
'followed',
|
|
|
|
];
|
|
|
|
const nixedTraits = selfEntityOnlyTraits.concat(noClientTraits);
|
|
|
|
for (let i = 0; i < nixedTraits.length; ++i) {
|
|
|
|
const type = nixedTraits[i];
|
|
|
|
if (entity.is(type)) {
|
|
|
|
entity.removeTrait(type);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Client only traits.
|
|
|
|
const clientOnlyTraits = [
|
|
|
|
'staged',
|
|
|
|
];
|
|
|
|
for (let i = 0; i < clientOnlyTraits.length; ++i) {
|
|
|
|
const type = clientOnlyTraits[i];
|
|
|
|
entity.addTrait(type);
|
|
|
|
}
|
|
|
|
entity.stage = this.stage;
|
|
|
|
// Set self entity.
|
|
|
|
if (this.selfEntityUuid) {
|
|
|
|
if (entity === this.room.findEntity(this.selfEntityUuid)) {
|
|
|
|
this.selfEntity = entity;
|
|
|
|
this.selfEntityUuid = undefined;
|
|
|
|
// Add back our self entity traits.
|
|
|
|
for (const type of selfEntityOnlyTraits) {
|
|
|
|
entity.addTrait(type);
|
|
|
|
}
|
|
|
|
const {camera} = entity;
|
|
|
|
this.stage.camera = camera;
|
|
|
|
// Avoid the initial 'lerp.
|
|
|
|
camera.realPosition = camera.position;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-04-19 20:01:06 -05:00
|
|
|
// Stub for now!
|
|
|
|
readConfig() {
|
|
|
|
return {
|
2019-04-19 21:21:41 -05:00
|
|
|
doPhysicsSimulation: true,
|
2019-04-19 20:01:06 -05:00
|
|
|
visibleScale: [2, 2],
|
|
|
|
visibleSize: [320, 180],
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|