diff options
| author | Rubén Beltrán del Río <ben@nsovocal.com> | 2018-04-21 17:45:38 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-04-21 17:45:38 -0500 |
| commit | 493ec31cb19b4211c703762d14a4e6232c4c2143 (patch) | |
| tree | c0c33fab8f2fb040dc714ab76f0eb5479f001b2e /lib/factories | |
| parent | 0616b3f00653c66b5e34814653e33413b9ec034e (diff) | |
Physics Engine (#4)
* Add matter-js as a dependency
* Add body component
* Fix renderable node doc
* Add the physics node type
* Correct typo in physics enabled node types
* Update docs on render system
* Add physics system
* Update changelog
* Add physics engine to main app
* Tweak the gravity of the world
* Add body to sumo factory
* Add angle component
* Add angle to entity
* Add angle to the nodes
* Pass angle between systems
* Set default angle to 0
* Split systems and nodes
* Fix indentaion in physics world control
* Add third sumo entity
* Adjust values for constriants and physics
* Correct docs in new nodes
* Update built-in docs
Diffstat (limited to 'lib/factories')
| -rw-r--r-- | lib/factories/pixi.js | 16 | ||||
| -rw-r--r-- | lib/factories/sumo.js | 102 |
2 files changed, 111 insertions, 7 deletions
diff --git a/lib/factories/pixi.js b/lib/factories/pixi.js index e3c1b5a..851a074 100644 --- a/lib/factories/pixi.js +++ b/lib/factories/pixi.js @@ -16,9 +16,9 @@ export default { * @memberof PixiFactory * @return {external:CreateJs.Container} the created container */ - createSumo() { + createSumo(config) { - const radius = 25; + const radius = config.radius; // The body const body = new Graphics(); @@ -61,6 +61,18 @@ export default { body.addChild(rightPupil); return body; + }, + + /** + * Creates an empty graphic + * + * @function createEmptyGraphic + * @memberof PixiFactory + * @return {external:CreateJs.Container} the created container + */ + createEmptyGraphic(config) { + + return new Graphics(); } }; diff --git a/lib/factories/sumo.js b/lib/factories/sumo.js index b0e5416..d1f31f0 100644 --- a/lib/factories/sumo.js +++ b/lib/factories/sumo.js @@ -1,9 +1,18 @@ +import { Bodies, Constraint } from 'matter-js'; import { Entity } from '@serpentity/serpentity'; +import AngleComponent from '../components/angle'; +import BodyComponent from '../components/body'; +import CoupledEntitiesComponent from '../components/coupled_entities'; import PositionComponent from '@serpentity/components.position'; import PixiContainerComponent from '../components/pixi_container'; import PixiFactory from '../factories/pixi'; +const internals = { + kNoEntityError: 'Entity Not Found: This method requires entityA and entityB to be set in the config.', + kEntityHasNoBodyError: 'Entity Has No Body: This method requires entities have a BodyComponent.' +}; + /** * Factory object that contains many methods to create prefab entities. * @@ -28,20 +37,103 @@ export default { const entity = new Entity(); + // POSITION + entity.addComponent(new PositionComponent(config.position)); + const position = entity.getComponent(PositionComponent); + + entity.addComponent(new AngleComponent(config.angle)); + const angle = entity.getComponent(AngleComponent); + + // RENDERING + + const radius = 25; const container = config.container || { - container: PixiFactory.createSumo() + container: PixiFactory.createSumo({ radius }) }; - - // Match the symbol position with the entity position on init - // Otherwise it's up to systems - const position = entity.getComponent(PositionComponent); container.container.position.x = position.x; container.container.position.y = position.y; + container.container.rotation = angle.angle; + entity.addComponent(new PixiContainerComponent(container)); + + // PHYSICS + + const frictionAir = 0.00001; + const friction = 0.00001; + const restitution = 0.9; + const density = 0.5; + + const body = Bodies.circle(position.x, position.y, radius, { + angle: angle.angle, + density, + frictionAir, + friction, + restitution + }); + entity.addComponent(new BodyComponent({ body })); + + if (engine) { + engine.addEntity(entity); + } + + return entity; + }, + + /** + * Creates a rubber band entity and adds it to the engine. + * + * @function createRubberBand + * @memberof SumoFactory + * @param {external:Serpentity} [engine] the serpentity engine to attach + * to. If not sent, it will not be attached. + * @param {object} [config] the config to override the entity, it + * must include entityA and entityB which will be tied by it. If they + * are not sent or don't have a physics body, this will throw. + * @return {external:Serpentity.Entity} the created entity + */ + createRubberBand(engine, config = {}) { + + const entity = new Entity(); + + if (!config.entityA || !config.entityB) { + throw new Error(internals.kNoEntityError); + } + + if (!config.entityA.hasComponent(BodyComponent) || !config.entityB.hasComponent(BodyComponent)) { + throw new Error(internals.kEntityHasNoBodyError); + } + // RENDERING + + const container = config.container || { + container: PixiFactory.createEmptyGraphic() + }; entity.addComponent(new PixiContainerComponent(container)); + // PHYSICS + + const bodyA = config.entityA.getComponent(BodyComponent).body; + const bodyB = config.entityB.getComponent(BodyComponent).body; + const damping = 0.01; + const length = 100; + const stiffness = 0.0001; + const angularStiffness = 0.0001; + + const body = Constraint.create({ + bodyA, + bodyB, + damping, + length, + stiffness, + angularStiffness + }); + entity.addComponent(new BodyComponent({ body })); + + entity.addComponent(new CoupledEntitiesComponent({ + coupledEntities: [config.entityA, config.entityB] + })); + if (engine) { engine.addEntity(entity); } |