]> git.r.bdr.sh - rbdr/sumo/blobdiff - lib/factories/sumo.js
Add Naive Game Rules (#11)
[rbdr/sumo] / lib / factories / sumo.js
index 7b50f8ae50493ce087d8d8f570e23a12c08f7a9a..009ba8cbbad903be63b37934743d69af4d36da05 100644 (file)
@@ -14,8 +14,11 @@ import GrabAreaComponent from '../components/grab_area';
 import GrabbableComponent from '../components/grabbable';
 import GrabComponent from '../components/grab';
 import MaxVelocityComponent from '../components/max_velocity';
+import PointsColliderComponent from '../components/points_collider';
+import PointsComponent from '../components/points';
 import PositionComponent from '@serpentity/components.position';
 import PixiContainerComponent from '../components/pixi_container';
+import WinnerComponent from '../components/winner';
 
 import PixiFactory from '../factories/pixi';
 import Config from '../config';
@@ -71,9 +74,12 @@ export default {
     // RENDERING
 
     const radius = 25;
+    const pixiConfig = Object.assign({
+      radius
+    }, config.pixi);
 
     const container = config.container || {
-      container: PixiFactory.createSumo({ radius })
+      container: PixiFactory.createSumo(pixiConfig)
     };
     container.container.position.x = position.x;
     container.container.position.y = position.y;
@@ -195,74 +201,304 @@ export default {
 
     const entity = this.createSumo(null, config);
 
-    entity.addComponent(new ControlMapComponent({
-      map: [
-        {
-          source: {
-            type: 'keyboard',
-            index: 37 // left arrow
+    entity.addComponent(new ControlMapComponent(config.controlMap));
+
+    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. Has contrrol scheme defaults for
+   * player 1
+   *
+   * @function createPlayer1Sumo
+   * @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
+   */
+  createPlayer1Sumo(engine, config = {}) {
+
+    const playerConfig = Object.assign({
+      controlMap: {
+        map: [
+          {
+            source: {
+              type: 'keyboard',
+              index: 65 // a
+            },
+            target: {
+              component: ForceComponent,
+              property: 'x',
+              value: (value) => -Number(value)
+            }
           },
-          target: {
-            component: ForceComponent,
-            property: 'x',
-            value: (value) => -Number(value)
-          }
-        },
-        {
-          source: {
-            type: 'keyboard',
-            index: 39 // right arrow
+          {
+            source: {
+              type: 'keyboard',
+              index: 68 // d
+            },
+            target: {
+              component: ForceComponent,
+              property: 'x',
+              value: (value) => Number(value)
+            }
           },
-          target: {
-            component: ForceComponent,
-            property: 'x',
-            value: (value) => Number(value)
-          }
-        },
-        {
-          source: {
-            type: 'keyboard',
-            index: 38 // up arrow
+          {
+            source: {
+              type: 'keyboard',
+              index: 87 // w
+            },
+            target: {
+              component: ForceComponent,
+              property: 'y',
+              value: (value) => -Number(value)
+            }
           },
-          target: {
-            component: ForceComponent,
-            property: 'y',
-            value: (value) => -Number(value)
-          }
-        },
-        {
-          source: {
-            type: 'keyboard',
-            index: 40 // down arrow
+          {
+            source: {
+              type: 'keyboard',
+              index: 83 // s
+            },
+            target: {
+              component: ForceComponent,
+              property: 'y',
+              value: (value) => Number(value)
+            }
           },
-          target: {
-            component: ForceComponent,
-            property: 'y',
-            value: (value) => Number(value)
-          }
-        },
-        {
-          source: {
-            type: 'keyboard',
-            index: 90 // Z
+          {
+            source: {
+              type: 'keyboard',
+              index: 90 // Z
+            },
+            target: {
+              component: DashComponent,
+              property: 'dashing'
+            }
+          },
+          {
+            source: {
+              type: 'keyboard',
+              index: 88 // X
+            },
+            target: {
+              component: GrabComponent,
+              property: 'grabbing'
+            }
+          },
+          {
+            source: {
+              type: 'gamepad',
+              gamepadNumber: 0,
+              gamepadInputSource: 'axes',
+              index: 0 // left stick horizontal
+            },
+            target: {
+              component: ForceComponent,
+              property: 'x',
+              value: (value) => Number(value)
+            }
           },
-          target: {
-            component: DashComponent,
-            property: 'dashing'
+          {
+            source: {
+              type: 'gamepad',
+              gamepadNumber: 0,
+              gamepadInputSource: 'axes',
+              index: 1 // left stick vertical
+            },
+            target: {
+              component: ForceComponent,
+              property: 'y',
+              value: (value) => Number(value)
+            }
+          },
+          {
+            source: {
+              type: 'gamepad',
+              gamepadNumber: 0,
+              gamepadInputSource: 'buttons',
+              index: 2 // left face button
+            },
+            target: {
+              component: DashComponent,
+              property: 'dashing',
+              value: (value) => value.value
+            }
+          },
+          {
+            source: {
+              type: 'gamepad',
+              gamepadNumber: 0,
+              gamepadInputSource: 'buttons',
+              index: 0 // bottom face button
+            },
+            target: {
+              component: GrabComponent,
+              property: 'grabbing',
+              value: (value) => value.value
+            }
           }
-        },
-        {
-          source: {
-            type: 'keyboard',
-            index: 88 // X
+        ]
+      }
+    }, config);
+
+    const entity = this.createControllableSumo(null, playerConfig);
+
+    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. Has contrrol scheme defaults for
+   * player 2
+   *
+   * @function createPlayer2Sumo
+   * @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
+   */
+  createPlayer2Sumo(engine, config = {}) {
+
+    const playerConfig = Object.assign({
+      pixi: {
+        color: 0xeaacac
+      },
+      controlMap: {
+        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)
+            }
           },
-          target: {
-            component: GrabComponent,
-            property: 'grabbing'
+          {
+            source: {
+              type: 'keyboard',
+              index: 188 // ,
+            },
+            target: {
+              component: DashComponent,
+              property: 'dashing'
+            }
+          },
+          {
+            source: {
+              type: 'keyboard',
+              index: 190 // .
+            },
+            target: {
+              component: GrabComponent,
+              property: 'grabbing'
+            }
+          },
+          {
+            source: {
+              type: 'gamepad',
+              gamepadNumber: 1,
+              gamepadInputSource: 'axes',
+              index: 0 // left stick horizontal
+            },
+            target: {
+              component: ForceComponent,
+              property: 'x',
+              value: (value) => Number(value)
+            }
+          },
+          {
+            source: {
+              type: 'gamepad',
+              gamepadNumber: 1,
+              gamepadInputSource: 'axes',
+              index: 1 // left stick vertical
+            },
+            target: {
+              component: ForceComponent,
+              property: 'y',
+              value: (value) => Number(value)
+            }
+          },
+          {
+            source: {
+              type: 'gamepad',
+              gamepadNumber: 1,
+              gamepadInputSource: 'buttons',
+              index: 2 // left face button
+            },
+            target: {
+              component: DashComponent,
+              property: 'dashing',
+              value: (value) => value.value
+            }
+          },
+          {
+            source: {
+              type: 'gamepad',
+              gamepadNumber: 1,
+              gamepadInputSource: 'buttons',
+              index: 0 // bottom face button
+            },
+            target: {
+              component: GrabComponent,
+              property: 'grabbing',
+              value: (value) => value.value
+            }
           }
-        }
-      ]
-    }));
+        ]
+      }
+    }, config);
+
+    const entity = this.createControllableSumo(null, playerConfig);
 
     if (engine) {
       engine.addEntity(entity);
@@ -387,14 +623,17 @@ export default {
     const friction = 0;
     const frictionStatic = 0;
     const restitution = 1;
+    const label = config.label || 'Invisible Block';
+    const isSensor = !!(config.isSensor);
 
     const body = Bodies.rectangle(position.x / Config.meterSize,
       position.y / Config.meterSize,
       config.width / Config.meterSize,
       config.height / Config.meterSize,
       {
+        isSensor,
         isStatic: true,
-        label: 'Invisible Block',
+        label,
         friction,
         restitution,
         frictionStatic
@@ -405,6 +644,61 @@ export default {
       engine.addEntity(entity);
     }
 
+    return entity;
+  },
+
+  /**
+   * Creates an invisible block that accumulates points if certain
+   * entity collids with it
+   *
+   * @function createPointsCollider
+   * @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
+   */
+  createPointsCollider(engine, config = {}) {
+
+    const entity = this.createInvisibleBlock(null, Object.assign({
+      isSensor: true,
+      label: 'Points Detector'
+    }, config));
+
+    // Points Collider
+
+    entity.addComponent(new PointsColliderComponent(config));
+
+    if (engine) {
+      engine.addEntity(entity);
+    }
+
+    return entity;
+  },
+
+  /**
+   * Creates an entity representing the game state
+   *
+   * @function createGameState
+   * @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
+   */
+  createGameState(engine, config = {}) {
+
+    const entity = new Entity();
+
+    entity.addComponent(new PointsComponent(config));
+    entity.addComponent(new WinnerComponent(config));
+
+    if (engine) {
+      engine.addEntity(entity);
+    }
+
     return entity;
   }
 };