refactor: Abstract physics
This commit is contained in:
parent
5bdff7ce71
commit
f3d8f55689
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
18
packages/physics/abstract/body.js
Normal file
18
packages/physics/abstract/body.js
Normal 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) {}
|
34
packages/physics/abstract/world.js
Normal file
34
packages/physics/abstract/world.js
Normal 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) {}
|
|
@ -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) {}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user