diff options
| author | Rubén Beltrán del Río <ben@nsovocal.com> | 2018-04-23 05:13:08 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-04-23 05:13:08 -0500 |
| commit | 7ade6f8d96825386bf2e89dea51f9297cbac8e9c (patch) | |
| tree | 1e0c95625250c6fc41c7c8722ed81f4a3246ce6c /lib/factories | |
| parent | f45bcde17fe0a8849e647ac843106fb51d2e8971 (diff) | |
Add control via keyboard (#6)
* Correct angle documentation
* Correct body component doc
* Add a config module with px 2 meters
* Create component to map input
* Add components for mappable actions
* Add component for elastic manipulation
* Add node to modify physics
* Add controllable node
* Add dasher node
* Add control mapper system
* Add component to limit velocity
* Add node for limiting velocity
* Add systems to move and dash
* Use meters in physics systems
* Correct documentation in render system
* Add elastic manipulation system
* Update factories to use new components
* Update main app to use new systems
* Ignore dist dir
* Also ignore cache
* Ignore personal configuration files
* Add system to reduce velocity
* Add changelog
Diffstat (limited to 'lib/factories')
| -rw-r--r-- | lib/factories/pixi.js | 28 | ||||
| -rw-r--r-- | lib/factories/sumo.js | 178 |
2 files changed, 196 insertions, 10 deletions
diff --git a/lib/factories/pixi.js b/lib/factories/pixi.js index 851a074..839e593 100644 --- a/lib/factories/pixi.js +++ b/lib/factories/pixi.js @@ -73,6 +73,34 @@ export default { createEmptyGraphic(config) { return new Graphics(); + }, + + /** + * Creates a harness graphic + * + * @function createHarness + * @memberof PixiFactory + * @return {external:CreateJs.Container} the created container + */ + createHarness(config) { + + const radius = config.radius; + + const lineThickness = 10; + + // The body + const body = new Graphics(); + body.lineStyle(lineThickness, 0xe1e1e1, 1) + .drawCircle(0, 0, radius); + + const center = new Graphics(); + center.beginFill(0xf1f1f1) + .drawCircle(0, 0, radius - lineThickness / 2) + .endFill(); + + body.addChild(center); + + return body; } }; diff --git a/lib/factories/sumo.js b/lib/factories/sumo.js index d1f31f0..ea5a71c 100644 --- a/lib/factories/sumo.js +++ b/lib/factories/sumo.js @@ -1,12 +1,21 @@ import { Bodies, Constraint } from 'matter-js'; import { Entity } from '@serpentity/serpentity'; +// Components + import AngleComponent from '../components/angle'; import BodyComponent from '../components/body'; +import ControlMapComponent from '../components/control_map'; import CoupledEntitiesComponent from '../components/coupled_entities'; +import DashComponent from '../components/dash'; +import ElasticComponent from '../components/elastic'; +import ForceComponent from '../components/force'; +import MaxVelocityComponent from '../components/max_velocity'; import PositionComponent from '@serpentity/components.position'; import PixiContainerComponent from '../components/pixi_container'; + import PixiFactory from '../factories/pixi'; +import Config from '../config'; const internals = { kNoEntityError: 'Entity Not Found: This method requires entityA and entityB to be set in the config.', @@ -45,6 +54,17 @@ export default { entity.addComponent(new AngleComponent(config.angle)); const angle = entity.getComponent(AngleComponent); + entity.addComponent(new ForceComponent(config.force)); + + config.maxVelocity = { + maxVelocity: 12 + }; + entity.addComponent(new MaxVelocityComponent(config.maxVelocity)); + + // CONTROLS & ABILITIES + + entity.addComponent(new DashComponent(config.dash)); + // RENDERING const radius = 25; @@ -59,15 +79,18 @@ export default { // PHYSICS - const frictionAir = 0.00001; - const friction = 0.00001; + const frictionAir = 0.02; + const friction = 1; + const frictionStatic = 1; const restitution = 0.9; - const density = 0.5; + const density = 1; - const body = Bodies.circle(position.x, position.y, radius, { + const body = Bodies.circle(position.x / Config.meterSize, position.y / Config.meterSize, radius / Config.meterSize, { + label: 'Sumo body', angle: angle.angle, density, frictionAir, + frictionStatic, friction, restitution }); @@ -115,18 +138,16 @@ export default { 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 damping = 0; + const length = 100 / Config.meterSize; + const stiffness = 0.001; const body = Constraint.create({ bodyA, bodyB, damping, length, - stiffness, - angularStiffness + stiffness }); entity.addComponent(new BodyComponent({ body })); @@ -134,6 +155,143 @@ export default { coupledEntities: [config.entityA, config.entityB] })); + entity.addComponent(new ElasticComponent()); + + if (engine) { + engine.addEntity(entity); + } + + return entity; + }, + + /** + * Creates a controllable sumo entity and adds it to the engine. Can override + * position in the config object + * + * @function createControllableSumo + * @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, accepts + * the key `position` as an object with an x and y property. + * @return {external:Serpentity.Entity} the created entity + */ + createControllableSumo(engine, config = {}) { + + const entity = this.createSumo(null, config); + + entity.addComponent(new ControlMapComponent({ + map: [ + { + source: { + type: 'keyboard', + index: 37 // left arrow + }, + target: { + component: ForceComponent, + property: 'x', + value: (value) => -Number(value) + } + }, + { + source: { + type: 'keyboard', + index: 39 // right arrow + }, + target: { + component: ForceComponent, + property: 'x', + value: (value) => Number(value) + } + }, + { + source: { + type: 'keyboard', + index: 38 // up arrow + }, + target: { + component: ForceComponent, + property: 'y', + value: (value) => -Number(value) + } + }, + { + source: { + type: 'keyboard', + index: 40 // down arrow + }, + target: { + component: ForceComponent, + property: 'y', + value: (value) => Number(value) + } + }, + { + source: { + type: 'keyboard', + index: 90 // Z + }, + target: { + component: DashComponent, + property: 'dashing' + } + } + ] + })); + + if (engine) { + engine.addEntity(entity); + } + + return entity; + }, + + /** + * Creates a static harness entity + * + * @function createHarness + * @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, accepts + * the key `position` as an object with an x and y property. + * @return {external:Serpentity.Entity} the created entity + */ + createHarness(engine, config = {}) { + + const entity = new Entity(); + + // POSITION + + entity.addComponent(new PositionComponent(config.position)); + const position = entity.getComponent(PositionComponent); + + // RENDERING + + const radius = 15; + + const container = config.container || { + container: PixiFactory.createHarness({ radius }) + }; + container.container.position.x = position.x; + container.container.position.y = position.y; + entity.addComponent(new PixiContainerComponent(container)); + + // PHYSICS + + const friction = 0; + const frictionStatic = 0; + const restitution = 1; + + const body = Bodies.circle(position.x / Config.meterSize, position.y / Config.meterSize, radius / Config.meterSize, { + isStatic: true, + label: 'Harness body', + friction, + restitution, + frictionStatic + }); + entity.addComponent(new BodyComponent({ body })); + if (engine) { engine.addEntity(entity); } |