avocado-old/packages/physics/matter/world.js

88 lines
2.3 KiB
JavaScript
Raw Normal View History

2020-04-19 21:02:11 -05:00
import {Body as MatterBody, Engine, Events, World as MatterWorld} from 'matter-js';
import {Vector} from '@avocado/math';
2019-03-24 03:24:35 -05:00
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,
});
2019-03-27 18:38:12 -05:00
this.handleCollisions('collisionStart');
this.handleCollisions('collisionEnd');
this.elapsedRemainder = 0;
2019-03-24 03:24:35 -05:00
}
addBody(body) {
MatterWorld.add(this.engine.world, body.matterBody);
}
createBody(shape) {
2019-05-04 13:31:16 -05:00
return new Body(this, shape);
2019-03-24 03:24:35 -05:00
}
2019-03-27 18:38:12 -05:00
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));
2019-06-05 20:20:02 -05:00
if (
entityA && entityA.is('collider')
&& entityB && entityB.is('collider')
) {
if (entityA.collidesWith(entityB)) {
entityA.emit(eventName, entityB);
}
if (entityB.collidesWith(entityA)) {
entityB.emit(eventName, entityA);
}
2019-03-27 18:38:12 -05:00
}
});
});
}
2019-03-24 03:24:35 -05:00
removeBody(body) {
super.removeBody(body);
MatterWorld.remove(this.engine.world, body.matterBody);
2019-03-24 03:24:35 -05:00
}
tick(elapsed) {
// Update simulation.
elapsed += this.elapsedRemainder;
const stepTime = this.stepTime;
2019-05-04 13:15:34 -05:00
const stepTimeInMs = stepTime * 1000;
while (elapsed >= stepTime) {
2020-04-19 21:02:11 -05:00
// Apply impulses.
let it = this.entities.entries();
for (let value = it.next(); value.done !== true; value = it.next()) {
const body = value.value[0];
const [x, y] = Vector.scale(body.impulse, stepTime);
MatterBody.translate(body.matterBody, {x, y});
}
Engine.update(this.engine, stepTimeInMs);
elapsed -= stepTime;
}
this.elapsedRemainder = elapsed;
2020-04-19 21:02:11 -05:00
// Reset impulses.
const it = this.entities.entries();
for (let value = it.next(); value.done !== true; value = it.next()) {
value.value[0].impulse = [0, 0];
}
2019-03-24 03:24:35 -05:00
// Propagate.
super.tick(elapsed);
}
}