feat: room size & bounds
This commit is contained in:
parent
31e7f7a26a
commit
f90357c35a
|
@ -1,7 +1,9 @@
|
|||
import * as I from 'immutable';
|
||||
|
||||
import {compose} from '@avocado/core';
|
||||
import {Vector} from '@avocado/math';
|
||||
import {EventEmitter, Property} from '@avocado/mixins';
|
||||
import {RectangleShape} from '@avocado/physics';
|
||||
|
||||
import {Layers} from './layers';
|
||||
|
||||
|
@ -10,24 +12,36 @@ const decorate = compose(
|
|||
Property('world', {
|
||||
track: true,
|
||||
}),
|
||||
Vector.Mixin('size', 'width', 'height', {
|
||||
default: [0, 0],
|
||||
})
|
||||
);
|
||||
|
||||
export class Room extends decorate(class {}) {
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
this.bounds = [];
|
||||
this.layers = new Layers();
|
||||
this._state = I.Map();
|
||||
// Listeners.
|
||||
this.onEntityAddedToRoom = this.onEntityAddedToRoom.bind(this);
|
||||
this.onEntityRemovedFromRoom = this.onEntityRemovedFromRoom.bind(this);
|
||||
this.onWorldChanged = this.onWorldChanged.bind(this);
|
||||
this.layers.on('entityAdded', this.onEntityAddedToRoom);
|
||||
this.layers.on('entityRemoved', this.onEntityRemovedFromRoom);
|
||||
this.onSizeChanged = this.onSizeChanged.bind(this);
|
||||
this.on('sizeChanged', this.onSizeChanged);
|
||||
this.onWorldChanged = this.onWorldChanged.bind(this);
|
||||
this.on('worldChanged', this.onWorldChanged);
|
||||
}
|
||||
|
||||
acceptStateChange(change) {
|
||||
if (change.width) {
|
||||
this.width = change.width;
|
||||
}
|
||||
if (change.height) {
|
||||
this.height = change.height;
|
||||
}
|
||||
if (change.layers) {
|
||||
this.layers.acceptStateChange(change.layers);
|
||||
}
|
||||
|
@ -52,6 +66,9 @@ export class Room extends decorate(class {}) {
|
|||
if (json.layers) {
|
||||
this.layers.fromJSON(json.layers);
|
||||
}
|
||||
if (json.size) {
|
||||
this.size = json.size;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
|
@ -72,26 +89,75 @@ export class Room extends decorate(class {}) {
|
|||
this.emit('entityRemoved', entity);
|
||||
}
|
||||
|
||||
onSizeChanged() {
|
||||
this.updateBounds();
|
||||
}
|
||||
|
||||
onWorldChanged() {
|
||||
const world = this.world;
|
||||
for (const {layer} of this.layers) {
|
||||
for (const entity of layer.entityList) {
|
||||
if (entity.is('physical')) {
|
||||
entity.world = this.world;
|
||||
entity.world = world;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Update bounds.
|
||||
this.updateBounds();
|
||||
}
|
||||
|
||||
removeEntityFromLayer(entity, layerIndex = 0) {
|
||||
this.layers.removeEntityFromLayer(entity, layerIndex);
|
||||
}
|
||||
|
||||
updateBounds() {
|
||||
const world = this.world;
|
||||
if (!world) {
|
||||
return;
|
||||
}
|
||||
for (const bound of this.bounds) {
|
||||
world.removeBody(bound);
|
||||
}
|
||||
if (Vector.isZero(this.size)) {
|
||||
return;
|
||||
}
|
||||
console.log(this.size);
|
||||
this.bounds = [
|
||||
// Top.
|
||||
world.createBody((new RectangleShape()).fromJSON({
|
||||
position: [this.width / 2, -8],
|
||||
size: [this.width, 16],
|
||||
})),
|
||||
// Right.
|
||||
world.createBody((new RectangleShape()).fromJSON({
|
||||
position: [this.width + 8, this.height / 2],
|
||||
size: [16, this.height],
|
||||
})),
|
||||
// Bottom.
|
||||
world.createBody((new RectangleShape()).fromJSON({
|
||||
position: [this.width / 2, this.height + 8],
|
||||
size: [this.width, 16],
|
||||
})),
|
||||
// Left.
|
||||
world.createBody((new RectangleShape()).fromJSON({
|
||||
position: [-8, this.height / 2],
|
||||
size: [16, this.height],
|
||||
})),
|
||||
];
|
||||
this.bounds.forEach((bound) => {
|
||||
bound.static = true;
|
||||
world.addBody(bound);
|
||||
});
|
||||
}
|
||||
|
||||
get state() {
|
||||
return this._state;
|
||||
}
|
||||
|
||||
tick(elapsed) {
|
||||
this.layers.tick(elapsed);
|
||||
this._state = this._state.set('height', this.height);
|
||||
this._state = this._state.set('width', this.width);
|
||||
this._state = this._state.set('layers', this.layers.state);
|
||||
if (this.world) {
|
||||
this.world.tick(elapsed);
|
||||
|
|
Loading…
Reference in New Issue
Block a user