import {compose} from '@avocado/core'; import {ShapeView} from '@avocado/graphics'; import {Vector} from '@avocado/math'; import {shapeFromJSON} from '@avocado/physics'; import {StateProperty, Trait} from '../trait'; const decorate = compose( ); export class Physical extends decorate(Trait) { static defaultParams() { return { shape: undefined, }; } initialize() { this._body = undefined; this._shape = shapeFromJSON(this.params.get('shape')); this._shapeView = undefined; this._world = undefined; } destroy() { if (this._world) { this._world.removeBody(this._body); } } get body() { return this._body; } get shape() { return this._shape; } set world(world) { this._world = world; if (world) { const body = world.createBody(this.entity.shape); world.associateBodyWithEntity(body, this.entity); world.addBody(body); this._body = body; } } listeners() { return { addedToList: () => { this.entity.world = this.entity.list.world; }, positionChanged: () => { if (this._body) { this._body.position = this.entity.position; } }, traitAdded: (type) => { if (!this._shapeView && this.entity.container) { this._shapeView = new ShapeView(this.entity.shape); this._shapeView.zIndex = 100; this.entity.container.addChild(this._shapeView); } } }; } methods() { return { applyForce: (force) => { if (this._world) { this._body.applyForce(force); } }, applyImpulse: (impulse) => { if (this._world) { this._body.applyImpulse(impulse); } }, } } }