]> git.r.bdr.sh - rbdr/sumo/blobdiff - lib/factories/sumo.js
Add Grab System (#9)
[rbdr/sumo] / lib / factories / sumo.js
index ea5a71c753ace339f301377cd2cc2526b0b1d3f3..7b50f8ae50493ce087d8d8f570e23a12c08f7a9a 100644 (file)
@@ -10,6 +10,9 @@ import CoupledEntitiesComponent from '../components/coupled_entities';
 import DashComponent from '../components/dash';
 import ElasticComponent from '../components/elastic';
 import ForceComponent from '../components/force';
+import GrabAreaComponent from '../components/grab_area';
+import GrabbableComponent from '../components/grabbable';
+import GrabComponent from '../components/grab';
 import MaxVelocityComponent from '../components/max_velocity';
 import PositionComponent from '@serpentity/components.position';
 import PixiContainerComponent from '../components/pixi_container';
@@ -80,10 +83,10 @@ export default {
     // PHYSICS
 
     const frictionAir = 0.02;
-    const friction = 1;
-    const frictionStatic = 1;
-    const restitution = 0.9;
-    const density = 1;
+    const friction = 0.01;
+    const frictionStatic = 0.01;
+    const restitution = 1;
+    const density = 1.5;
 
     const body = Bodies.circle(position.x / Config.meterSize, position.y / Config.meterSize, radius / Config.meterSize, {
       label: 'Sumo body',
@@ -96,6 +99,18 @@ export default {
     });
     entity.addComponent(new BodyComponent({ body }));
 
+    // GRAB
+
+    const areaSizeFactor = 2; // Multiplier vs the radius
+    const area = Bodies.circle(position.x / Config.meterSize, position.y / Config.meterSize, (radius * areaSizeFactor) / Config.meterSize, {
+      label: 'Sumo Grab Area',
+      isSensor: true
+    });
+
+    entity.addComponent(new GrabAreaComponent({ area }));
+    entity.addComponent(new GrabComponent({ body }));
+    entity.addComponent(new GrabbableComponent({ body }));
+
     if (engine) {
       engine.addEntity(entity);
     }
@@ -235,6 +250,16 @@ export default {
             component: DashComponent,
             property: 'dashing'
           }
+        },
+        {
+          source: {
+            type: 'keyboard',
+            index: 88 // X
+          },
+          target: {
+            component: GrabComponent,
+            property: 'grabbing'
+          }
         }
       ]
     }));
@@ -296,6 +321,90 @@ export default {
       engine.addEntity(entity);
     }
 
+    return entity;
+  },
+
+  /**
+   * Creates a static arena entity
+   *
+   * @function createArena
+   * @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
+   */
+  createArena(engine, config = {}) {
+
+    const entity = new Entity();
+
+    // POSITION
+
+    entity.addComponent(new PositionComponent(config.position));
+    const position = entity.getComponent(PositionComponent);
+
+    // RENDERING
+
+    const radius = 300;
+
+    const container = config.container || {
+      container: PixiFactory.createArena({ radius })
+    };
+    container.container.position.x = position.x;
+    container.container.position.y = position.y;
+    entity.addComponent(new PixiContainerComponent(container));
+
+    if (engine) {
+      engine.addEntity(entity);
+    }
+
+    return entity;
+  },
+
+  /**
+   * Creates an invisible block
+   *
+   * @function createInvisibleBlock
+   * @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
+   */
+  createInvisibleBlock(engine, config = {}) {
+
+    const entity = new Entity();
+
+    // POSITION
+
+    entity.addComponent(new PositionComponent(config.position));
+    const position = entity.getComponent(PositionComponent);
+
+    // PHYSICS
+
+    const friction = 0;
+    const frictionStatic = 0;
+    const restitution = 1;
+
+    const body = Bodies.rectangle(position.x / Config.meterSize,
+      position.y / Config.meterSize,
+      config.width / Config.meterSize,
+      config.height / Config.meterSize,
+      {
+        isStatic: true,
+        label: 'Invisible Block',
+        friction,
+        restitution,
+        frictionStatic
+      });
+    entity.addComponent(new BodyComponent({ body }));
+
+    if (engine) {
+      engine.addEntity(entity);
+    }
+
     return entity;
   }
 };