64 lines
1.5 KiB
JavaScript
64 lines
1.5 KiB
JavaScript
import {Engine, Events, World as MatterWorld} from 'matter-js';
|
|
|
|
import {Body} from './body';
|
|
import {AbstractWorld} from '../abstract/world';
|
|
|
|
export class World extends AbstractWorld {
|
|
|
|
constructor() {
|
|
super();
|
|
const world = MatterWorld.create({
|
|
gravity: {
|
|
x: 0,
|
|
y: 0,
|
|
scale: 0,
|
|
},
|
|
});
|
|
this.engine = Engine.create({
|
|
world,
|
|
});
|
|
this.handleCollisions('collisionStart');
|
|
this.handleCollisions('collisionEnd');
|
|
this.lastElapsed = undefined;
|
|
}
|
|
|
|
addBody(body) {
|
|
MatterWorld.add(this.engine.world, body.matterBody);
|
|
}
|
|
|
|
createBody(shape) {
|
|
return new Body(shape);
|
|
}
|
|
|
|
handleCollisions(eventName) {
|
|
Events.on(this.engine, eventName, (event) => {
|
|
event.pairs.forEach((pair) => {
|
|
const {bodyA, bodyB} = pair;
|
|
const entityA = this.entities.get(Body.lookupBody(bodyA));
|
|
const entityB = this.entities.get(Body.lookupBody(bodyB));
|
|
if (entityA && entityB) {
|
|
entityA.emit(eventName, entityB);
|
|
entityB.emit(eventName, entityA);
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
removeBody(body) {
|
|
super.removeBody(body);
|
|
MatterWorld.remove(this.engine.world, body.matterBody);
|
|
}
|
|
|
|
tick(elapsed) {
|
|
// Milliseconds.
|
|
elapsed = elapsed * 1000;
|
|
const correction = this.lastElapsed ? elapsed / this.lastElapsed : 1;
|
|
// Update simulation.
|
|
Engine.update(this.engine, elapsed, correction)
|
|
this.lastElapsed = elapsed;
|
|
// Propagate.
|
|
super.tick(elapsed);
|
|
}
|
|
|
|
}
|