refactor: Abstract physics

This commit is contained in:
cha0s 2019-03-24 01:16:24 -05:00
parent 5bdff7ce71
commit f3d8f55689
5 changed files with 68 additions and 20 deletions

View File

@ -40,8 +40,10 @@ export class Physical extends decorate(Trait) {
set world(world) {
this._world = world;
if (world) {
this._body = world.createBodyForEntity(this.entity);
world.addBody(this._body);
const body = world.createBody(this.entity.shape);
world.associateBodyWithEntity(body, this.entity);
world.addBody(body);
this._body = body;
}
}

View File

@ -0,0 +1,18 @@
import {compose, virtualize} from '@avocado/core';
const decorate = compose(
virtualize([
'applyForce',
'applyImpulse',
]),
);
class AbstractBodyBase {
constructor(shape) {
this.shape = shape;
}
}
export class AbstractBody extends decorate(AbstractBodyBase) {}

View File

@ -0,0 +1,34 @@
import {compose, virtualize} from '@avocado/core';
const decorate = compose(
virtualize([
'addBody',
'createBody',
]),
);
class AbstractWorldBase {
constructor() {
this.entities = new Map();
}
associateBodyWithEntity(body, entity) {
this.entities.set(body, entity);
body.position = entity.position;
}
removeBody(body) {
this.entities.delete(body);
}
tick(elapsed) {
// Propagate position updates.
for (const entity of this.entities.values()) {
entity.position = entity.body.position;
}
}
}
export class AbstractWorld extends decorate(AbstractWorldBase) {}

View File

@ -1,9 +1,11 @@
import * as I from 'immutable';
import {compose} from '@avocado/core';
import {compose, virtualize} from '@avocado/core';
import {Rectangle, Vector} from '@avocado/math';
import {EventEmitter} from '@avocado/mixins';
import {AbstractBody} from '../abstract/body';
const decorate = compose(
EventEmitter,
Vector.Mixin('position', 'x', 'y', {
@ -12,13 +14,13 @@ const decorate = compose(
}),
);
class BodyBase {
export class Body extends decorate(AbstractBody) {
constructor(shape) {
super(shape);
this.force = [0, 0];
this.impulse = [0, 0];
this.contacts = I.Set();
this.shape = shape;
}
get aabb() {
@ -34,6 +36,3 @@ class BodyBase {
}
}
export class Body extends decorate(BodyBase) {}

View File

@ -4,12 +4,13 @@ import {arrayUnique} from '@avocado/core';
import {Rectangle, QuadTree, Vector} from '@avocado/math';
import {Body} from './body';
import {AbstractWorld} from '../abstract/world';
export class World {
export class World extends AbstractWorld {
constructor() {
super();
this.bodies = [];
this.entities = new Map();
this.quadTree = new QuadTree();
this.quadTreeNodes = new Map();
}
@ -46,19 +47,16 @@ export class World {
}
}
createBodyForEntity(entity) {
const body = new Body(entity.shape);
body.position = entity.position;
this.entities.set(body, entity);
return body;
createBody(shape) {
return new Body(shape);
}
removeBody(body) {
super.removeBody(body);
const index = this.bodies.indexOf(body);
if (-1 === index) {
return;
}
this.entities.delete(body);
this.removeQuadTreeNodes(body);
this.bodies.splice(index, 1);
}
@ -185,10 +183,7 @@ export class World {
body.force = [0, 0];
body.impulse = [0, 0];
}
// Propagate position updates.
for (const entity of this.entities.values()) {
entity.position = entity.body.position;
}
super.tick(elapsed);
}
}