- This CHANGELOG
- A README
- A CONTRIBUTING guide
+- Pixi powered renderer system
+- Matter-js powered physics system
[Unreleased]: https://github.com/rbdr/sumo/compare/master...develop
+## Classes
+
+<dl>
+<dt><a href="#AngleComponent">AngleComponent</a> ⇐ <code>external:Serpentity.Component</code></dt>
+<dd></dd>
+<dt><a href="#BodyComponent">BodyComponent</a> ⇐ <code>external:Serpentity.Component</code></dt>
+<dd></dd>
+<dt><a href="#CoupledEntitiesComponent">CoupledEntitiesComponent</a> ⇐ <code>external:Serpentity.Component</code></dt>
+<dd></dd>
+<dt><a href="#PixiContainerComponent">PixiContainerComponent</a> ⇐ <code>external:Serpentity.Component</code></dt>
+<dd></dd>
+<dt><a href="#PhysicalWithAttributesNode">PhysicalWithAttributesNode</a> ⇐ <code>external:Serpentity.Node</code></dt>
+<dd></dd>
+<dt><a href="#PhysicalNode">PhysicalNode</a> ⇐ <code>external:Serpentity.Node</code></dt>
+<dd></dd>
+<dt><a href="#RenderableCoupleNode">RenderableCoupleNode</a> ⇐ <code>external:Serpentity.Node</code></dt>
+<dd></dd>
+<dt><a href="#RenderableWithAttributesNode">RenderableWithAttributesNode</a> ⇐ <code>external:Serpentity.Node</code></dt>
+<dd></dd>
+<dt><a href="#RenderableNode">RenderableNode</a> ⇐ <code>external:Serpentity.Node</code></dt>
+<dd></dd>
+<dt><a href="#Sumo">Sumo</a></dt>
+<dd></dd>
+<dt><a href="#AttributesToRenderableSystem">AttributesToRenderableSystem</a> ⇐ <code>external:Serpentity.System</code></dt>
+<dd></dd>
+<dt><a href="#CreateCouplingLineSystem">CreateCouplingLineSystem</a> ⇐ <code>external:Serpentity.System</code></dt>
+<dd></dd>
+<dt><a href="#PhysicsToAttributesSystem">PhysicsToAttributesSystem</a> ⇐ <code>external:Serpentity.System</code></dt>
+<dd></dd>
+<dt><a href="#PhysicsWorldControlSystem">PhysicsWorldControlSystem</a> ⇐ <code>external:Serpentity.System</code></dt>
+<dd></dd>
+<dt><a href="#RenderSystem">RenderSystem</a> ⇐ <code>external:Serpentity.System</code></dt>
+<dd></dd>
+</dl>
+
+## Members
+
+<dl>
+<dt><a href="#PixiFactory">PixiFactory</a> : <code>object</code></dt>
+<dd><p>Factory object that contains many methods to create prefab pixi
+objects</p>
+</dd>
+<dt><a href="#SumoFactory">SumoFactory</a> : <code>object</code></dt>
+<dd><p>Factory object that contains many methods to create prefab entities.</p>
+</dd>
+</dl>
+
+<a name="AngleComponent"></a>
+
+## AngleComponent ⇐ <code>external:Serpentity.Component</code>
+**Kind**: global class
+**Extends**: <code>external:Serpentity.Component</code>
+<a name="new_AngleComponent_new"></a>
+
+### new AngleComponent(config)
+Component that stores an angle
+
+
+| Param | Type | Description |
+| --- | --- | --- |
+| config | <code>object</code> | a configuration object to extend. |
+
+<a name="BodyComponent"></a>
+
+## BodyComponent ⇐ <code>external:Serpentity.Component</code>
+**Kind**: global class
+**Extends**: <code>external:Serpentity.Component</code>
+<a name="new_BodyComponent_new"></a>
+
+### new BodyComponent(config)
+Component that stores a body for physics calculation
+
+
+| Param | Type | Description |
+| --- | --- | --- |
+| config | <code>object</code> | a configuration object to extend. |
+
+<a name="CoupledEntitiesComponent"></a>
+
+## CoupledEntitiesComponent ⇐ <code>external:Serpentity.Component</code>
+**Kind**: global class
+**Extends**: <code>external:Serpentity.Component</code>
+<a name="new_CoupledEntitiesComponent_new"></a>
+
+### new CoupledEntitiesComponent(config)
+Component that stores a number of entities coupled to this one.
+
+
+| Param | Type | Description |
+| --- | --- | --- |
+| config | <code>object</code> | a configuration object to extend. |
+
+<a name="PixiContainerComponent"></a>
+
+## PixiContainerComponent ⇐ <code>external:Serpentity.Component</code>
+**Kind**: global class
+**Extends**: <code>external:Serpentity.Component</code>
+
+* [PixiContainerComponent](#PixiContainerComponent) ⇐ <code>external:Serpentity.Component</code>
+ * [new PixiContainerComponent(config)](#new_PixiContainerComponent_new)
+ * [.container](#PixiContainerComponent+container)
+
+<a name="new_PixiContainerComponent_new"></a>
+
+### new PixiContainerComponent(config)
+Component that stores a pixi container
+
+
+| Param | Type | Description |
+| --- | --- | --- |
+| config | <code>object</code> | a configuration object to extend. |
+
+<a name="PixiContainerComponent+container"></a>
+
+### pixiContainerComponent.container
+The properthy that holds the pixi container
+
+**Kind**: instance property of [<code>PixiContainerComponent</code>](#PixiContainerComponent)
+**Properties**
+
+| Name | Type |
+| --- | --- |
+| container | <code>external:PixiJs.Container</code> |
+
+<a name="PhysicalWithAttributesNode"></a>
+
+## PhysicalWithAttributesNode ⇐ <code>external:Serpentity.Node</code>
+**Kind**: global class
+**Extends**: <code>external:Serpentity.Node</code>
+
+* [PhysicalWithAttributesNode](#PhysicalWithAttributesNode) ⇐ <code>external:Serpentity.Node</code>
+ * [new PhysicalWithAttributesNode()](#new_PhysicalWithAttributesNode_new)
+ * [.types](#PhysicalWithAttributesNode.types)
+
+<a name="new_PhysicalWithAttributesNode_new"></a>
+
+### new PhysicalWithAttributesNode()
+Node identifying an entity that can interact with physics and has
+components updated from its values
+
+<a name="PhysicalWithAttributesNode.types"></a>
+
+### PhysicalWithAttributesNode.types
+Holds the types that are used to identify an entity with a physics
+object and external attributes
+
+**Kind**: static property of [<code>PhysicalWithAttributesNode</code>](#PhysicalWithAttributesNode)
+**Properties**
+
+| Name | Type |
+| --- | --- |
+| types | <code>object</code> |
+
+<a name="PhysicalNode"></a>
+
+## PhysicalNode ⇐ <code>external:Serpentity.Node</code>
+**Kind**: global class
+**Extends**: <code>external:Serpentity.Node</code>
+
+* [PhysicalNode](#PhysicalNode) ⇐ <code>external:Serpentity.Node</code>
+ * [new PhysicalNode()](#new_PhysicalNode_new)
+ * [.types](#PhysicalNode.types)
+
+<a name="new_PhysicalNode_new"></a>
+
+### new PhysicalNode()
+Node identifying an entity that can interact with physics
+
+<a name="PhysicalNode.types"></a>
+
+### PhysicalNode.types
+Holds the types that are used to identify an entity with a physical
+body
+
+**Kind**: static property of [<code>PhysicalNode</code>](#PhysicalNode)
+**Properties**
+
+| Name | Type |
+| --- | --- |
+| types | <code>object</code> |
+
+<a name="RenderableCoupleNode"></a>
+
+## RenderableCoupleNode ⇐ <code>external:Serpentity.Node</code>
+**Kind**: global class
+**Extends**: <code>external:Serpentity.Node</code>
+
+* [RenderableCoupleNode](#RenderableCoupleNode) ⇐ <code>external:Serpentity.Node</code>
+ * [new RenderableCoupleNode()](#new_RenderableCoupleNode_new)
+ * [.types](#RenderableCoupleNode.types)
+
+<a name="new_RenderableCoupleNode_new"></a>
+
+### new RenderableCoupleNode()
+Node identifying an entity that has coupled entities and can be
+rendered
+
+<a name="RenderableCoupleNode.types"></a>
+
+### RenderableCoupleNode.types
+Holds the types that are used to identify a renderable couple
+
+**Kind**: static property of [<code>RenderableCoupleNode</code>](#RenderableCoupleNode)
+**Properties**
+
+| Name | Type |
+| --- | --- |
+| types | <code>object</code> |
+
+<a name="RenderableWithAttributesNode"></a>
+
+## RenderableWithAttributesNode ⇐ <code>external:Serpentity.Node</code>
+**Kind**: global class
+**Extends**: <code>external:Serpentity.Node</code>
+
+* [RenderableWithAttributesNode](#RenderableWithAttributesNode) ⇐ <code>external:Serpentity.Node</code>
+ * [new RenderableWithAttributesNode()](#new_RenderableWithAttributesNode_new)
+ * [.types](#RenderableWithAttributesNode.types)
+
+<a name="new_RenderableWithAttributesNode_new"></a>
+
+### new RenderableWithAttributesNode()
+Node identifying a renderable entity, should have position and a
+symbol to render
+
+<a name="RenderableWithAttributesNode.types"></a>
+
+### RenderableWithAttributesNode.types
+Holds the types that are used to identify a renderable with external
+attributes
+
+**Kind**: static property of [<code>RenderableWithAttributesNode</code>](#RenderableWithAttributesNode)
+**Properties**
+
+| Name | Type |
+| --- | --- |
+| types | <code>object</code> |
+
+<a name="RenderableNode"></a>
+
+## RenderableNode ⇐ <code>external:Serpentity.Node</code>
+**Kind**: global class
+**Extends**: <code>external:Serpentity.Node</code>
+
+* [RenderableNode](#RenderableNode) ⇐ <code>external:Serpentity.Node</code>
+ * [new RenderableNode()](#new_RenderableNode_new)
+ * [.types](#RenderableNode.types)
+
+<a name="new_RenderableNode_new"></a>
+
+### new RenderableNode()
+Node identifying a renderable entity, should have a pixi renderable
+
+<a name="RenderableNode.types"></a>
+
+### RenderableNode.types
+Holds the types that are used to identify a renderable entity
+
+**Kind**: static property of [<code>RenderableNode</code>](#RenderableNode)
+**Properties**
+
+| Name | Type |
+| --- | --- |
+| types | <code>object</code> |
+
<a name="Sumo"></a>
## Sumo
Pauses the loop
**Kind**: instance method of [<code>Sumo</code>](#Sumo)
+<a name="AttributesToRenderableSystem"></a>
+
+## AttributesToRenderableSystem ⇐ <code>external:Serpentity.System</code>
+**Kind**: global class
+**Extends**: <code>external:Serpentity.System</code>
+
+* [AttributesToRenderableSystem](#AttributesToRenderableSystem) ⇐ <code>external:Serpentity.System</code>
+ * [new AttributesToRenderableSystem(config)](#new_AttributesToRenderableSystem_new)
+ * [.added(engine)](#AttributesToRenderableSystem+added)
+ * [.removed()](#AttributesToRenderableSystem+removed)
+ * [.update(currentFrameDuration)](#AttributesToRenderableSystem+update)
+
+<a name="new_AttributesToRenderableSystem_new"></a>
+
+### new AttributesToRenderableSystem(config)
+Updates the renderables based on their attribuets
+
+
+| Param | Type | Description |
+| --- | --- | --- |
+| config | <code>object</code> | a configuration object to extend. |
+
+<a name="AttributesToRenderableSystem+added"></a>
+
+### attributesToRenderableSystem.added(engine)
+Initializes system when added. Requests renderable nodes and
+attaches to event listeners to add / remove them to pixi stage
+
+**Kind**: instance method of [<code>AttributesToRenderableSystem</code>](#AttributesToRenderableSystem)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| engine | <code>external:Serpentity.Engine</code> | the serpentity engine to which we are getting added |
+
+<a name="AttributesToRenderableSystem+removed"></a>
+
+### attributesToRenderableSystem.removed()
+Clears system resources when removed.
+
+**Kind**: instance method of [<code>AttributesToRenderableSystem</code>](#AttributesToRenderableSystem)
+<a name="AttributesToRenderableSystem+update"></a>
+
+### attributesToRenderableSystem.update(currentFrameDuration)
+Runs on every update of the loop. Updates the graphics so they're
+rendered correctly
+
+**Kind**: instance method of [<code>AttributesToRenderableSystem</code>](#AttributesToRenderableSystem)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| currentFrameDuration | <code>Number</code> | the duration of the current frame |
+
+<a name="CreateCouplingLineSystem"></a>
+
+## CreateCouplingLineSystem ⇐ <code>external:Serpentity.System</code>
+**Kind**: global class
+**Extends**: <code>external:Serpentity.System</code>
+
+* [CreateCouplingLineSystem](#CreateCouplingLineSystem) ⇐ <code>external:Serpentity.System</code>
+ * [new CreateCouplingLineSystem(config)](#new_CreateCouplingLineSystem_new)
+ * [.added(engine)](#CreateCouplingLineSystem+added)
+ * [.removed()](#CreateCouplingLineSystem+removed)
+ * [.update(currentFrameDuration)](#CreateCouplingLineSystem+update)
+
+<a name="new_CreateCouplingLineSystem_new"></a>
+
+### new CreateCouplingLineSystem(config)
+Renders renderable objects using pixi
+
+
+| Param | Type | Description |
+| --- | --- | --- |
+| config | <code>object</code> | a configuration object to extend. |
+
+<a name="CreateCouplingLineSystem+added"></a>
+
+### createCouplingLineSystem.added(engine)
+Initializes system when added. Requests renderable nodes and
+
+**Kind**: instance method of [<code>CreateCouplingLineSystem</code>](#CreateCouplingLineSystem)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| engine | <code>external:Serpentity.Engine</code> | the serpentity engine to which we are getting added |
+
+<a name="CreateCouplingLineSystem+removed"></a>
+
+### createCouplingLineSystem.removed()
+Clears system resources when removed.
+
+**Kind**: instance method of [<code>CreateCouplingLineSystem</code>](#CreateCouplingLineSystem)
+<a name="CreateCouplingLineSystem+update"></a>
+
+### createCouplingLineSystem.update(currentFrameDuration)
+Runs on every update of the loop. Does nothing.
+
+**Kind**: instance method of [<code>CreateCouplingLineSystem</code>](#CreateCouplingLineSystem)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| currentFrameDuration | <code>Number</code> | the duration of the current frame |
+
+<a name="PhysicsToAttributesSystem"></a>
+
+## PhysicsToAttributesSystem ⇐ <code>external:Serpentity.System</code>
+**Kind**: global class
+**Extends**: <code>external:Serpentity.System</code>
+
+* [PhysicsToAttributesSystem](#PhysicsToAttributesSystem) ⇐ <code>external:Serpentity.System</code>
+ * [new PhysicsToAttributesSystem(config)](#new_PhysicsToAttributesSystem_new)
+ * [.added(engine)](#PhysicsToAttributesSystem+added)
+ * [.removed()](#PhysicsToAttributesSystem+removed)
+ * [.update(currentFrameDuration)](#PhysicsToAttributesSystem+update)
+
+<a name="new_PhysicsToAttributesSystem_new"></a>
+
+### new PhysicsToAttributesSystem(config)
+Distribuets physics data to the related components
+
+
+| Param | Type | Description |
+| --- | --- | --- |
+| config | <code>object</code> | a configuration object to extend. |
+
+<a name="PhysicsToAttributesSystem+added"></a>
+
+### physicsToAttributesSystem.added(engine)
+Initializes system when added. Requests physics nodes
+
+**Kind**: instance method of [<code>PhysicsToAttributesSystem</code>](#PhysicsToAttributesSystem)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| engine | <code>external:Serpentity.Engine</code> | the serpentity engine to which we are getting added |
+
+<a name="PhysicsToAttributesSystem+removed"></a>
+
+### physicsToAttributesSystem.removed()
+Clears system resources when removed.
+
+**Kind**: instance method of [<code>PhysicsToAttributesSystem</code>](#PhysicsToAttributesSystem)
+<a name="PhysicsToAttributesSystem+update"></a>
+
+### physicsToAttributesSystem.update(currentFrameDuration)
+Runs on every update of the loop. Updates the other components
+based on physics
+
+**Kind**: instance method of [<code>PhysicsToAttributesSystem</code>](#PhysicsToAttributesSystem)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| currentFrameDuration | <code>Number</code> | the duration of the current frame |
+
+<a name="PhysicsWorldControlSystem"></a>
+
+## PhysicsWorldControlSystem ⇐ <code>external:Serpentity.System</code>
+**Kind**: global class
+**Extends**: <code>external:Serpentity.System</code>
+
+* [PhysicsWorldControlSystem](#PhysicsWorldControlSystem) ⇐ <code>external:Serpentity.System</code>
+ * [new PhysicsWorldControlSystem(config)](#new_PhysicsWorldControlSystem_new)
+ * [.added(engine)](#PhysicsWorldControlSystem+added)
+ * [.removed()](#PhysicsWorldControlSystem+removed)
+ * [.update(currentFrameDuration)](#PhysicsWorldControlSystem+update)
+
+<a name="new_PhysicsWorldControlSystem_new"></a>
+
+### new PhysicsWorldControlSystem(config)
+Adds and removes objects to the physics world and calls update
+
+
+| Param | Type | Description |
+| --- | --- | --- |
+| config | <code>object</code> | a configuration object to extend. |
+
+<a name="PhysicsWorldControlSystem+added"></a>
+
+### physicsWorldControlSystem.added(engine)
+Initializes system when added. Requests physics nodes and
+attaches to event listeners to add / remove them to pixi stage
+
+**Kind**: instance method of [<code>PhysicsWorldControlSystem</code>](#PhysicsWorldControlSystem)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| engine | <code>external:Serpentity.Engine</code> | the serpentity engine to which we are getting added |
+
+<a name="PhysicsWorldControlSystem+removed"></a>
+
+### physicsWorldControlSystem.removed()
+Clears system resources when removed.
+
+**Kind**: instance method of [<code>PhysicsWorldControlSystem</code>](#PhysicsWorldControlSystem)
+<a name="PhysicsWorldControlSystem+update"></a>
+
+### physicsWorldControlSystem.update(currentFrameDuration)
+Runs on every update of the loop. Updates the physics
+
+**Kind**: instance method of [<code>PhysicsWorldControlSystem</code>](#PhysicsWorldControlSystem)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| currentFrameDuration | <code>Number</code> | the duration of the current frame |
+
+<a name="RenderSystem"></a>
+
+## RenderSystem ⇐ <code>external:Serpentity.System</code>
+**Kind**: global class
+**Extends**: <code>external:Serpentity.System</code>
+
+* [RenderSystem](#RenderSystem) ⇐ <code>external:Serpentity.System</code>
+ * [new RenderSystem(config)](#new_RenderSystem_new)
+ * [.added(engine)](#RenderSystem+added)
+ * [.removed()](#RenderSystem+removed)
+ * [.update(currentFrameDuration)](#RenderSystem+update)
+
+<a name="new_RenderSystem_new"></a>
+
+### new RenderSystem(config)
+Renders renderable objects using pixi
+
+
+| Param | Type | Description |
+| --- | --- | --- |
+| config | <code>object</code> | a configuration object to extend. |
+
+<a name="RenderSystem+added"></a>
+
+### renderSystem.added(engine)
+Initializes system when added. Requests renderable nodes and
+attaches to event listeners to add / remove them to pixi stage
+
+**Kind**: instance method of [<code>RenderSystem</code>](#RenderSystem)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| engine | <code>external:Serpentity.Engine</code> | the serpentity engine to which we are getting added |
+
+<a name="RenderSystem+removed"></a>
+
+### renderSystem.removed()
+Clears system resources when removed.
+
+**Kind**: instance method of [<code>RenderSystem</code>](#RenderSystem)
+<a name="RenderSystem+update"></a>
+
+### renderSystem.update(currentFrameDuration)
+Runs on every update of the loop. Does nothing.
+
+**Kind**: instance method of [<code>RenderSystem</code>](#RenderSystem)
+
+| Param | Type | Description |
+| --- | --- | --- |
+| currentFrameDuration | <code>Number</code> | the duration of the current frame |
+
+<a name="PixiFactory"></a>
+
+## PixiFactory : <code>object</code>
+Factory object that contains many methods to create prefab pixi
+objects
+
+**Kind**: global variable
+
+* [PixiFactory](#PixiFactory) : <code>object</code>
+ * [.createSumo()](#PixiFactory.createSumo) ⇒ <code>external:CreateJs.Container</code>
+ * [.createEmptyGraphic()](#PixiFactory.createEmptyGraphic) ⇒ <code>external:CreateJs.Container</code>
+
+<a name="PixiFactory.createSumo"></a>
+
+### PixiFactory.createSumo() ⇒ <code>external:CreateJs.Container</code>
+Creates a sumo container
+
+**Kind**: static method of [<code>PixiFactory</code>](#PixiFactory)
+**Returns**: <code>external:CreateJs.Container</code> - the created container
+<a name="PixiFactory.createEmptyGraphic"></a>
+
+### PixiFactory.createEmptyGraphic() ⇒ <code>external:CreateJs.Container</code>
+Creates an empty graphic
+
+**Kind**: static method of [<code>PixiFactory</code>](#PixiFactory)
+**Returns**: <code>external:CreateJs.Container</code> - the created container
+<a name="SumoFactory"></a>
+
+## SumoFactory : <code>object</code>
+Factory object that contains many methods to create prefab entities.
+
+**Kind**: global variable
+
+* [SumoFactory](#SumoFactory) : <code>object</code>
+ * [.createSumo([engine], [config])](#SumoFactory.createSumo) ⇒ <code>external:Serpentity.Entity</code>
+ * [.createRubberBand([engine], [config])](#SumoFactory.createRubberBand) ⇒ <code>external:Serpentity.Entity</code>
+
+<a name="SumoFactory.createSumo"></a>
+
+### SumoFactory.createSumo([engine], [config]) ⇒ <code>external:Serpentity.Entity</code>
+Creates a sumo entity and adds it to the engine. Can override
+position in the config object
+
+**Kind**: static method of [<code>SumoFactory</code>](#SumoFactory)
+**Returns**: <code>external:Serpentity.Entity</code> - the created entity
+
+| Param | Type | Description |
+| --- | --- | --- |
+| [engine] | <code>external:Serpentity</code> | the serpentity engine to attach to. If not sent, it will not be attached. |
+| [config] | <code>object</code> | the config to override the entity, accepts the key `position` as an object with an x and y property. |
+
+<a name="SumoFactory.createRubberBand"></a>
+
+### SumoFactory.createRubberBand([engine], [config]) ⇒ <code>external:Serpentity.Entity</code>
+Creates a rubber band entity and adds it to the engine.
+
+**Kind**: static method of [<code>SumoFactory</code>](#SumoFactory)
+**Returns**: <code>external:Serpentity.Entity</code> - the created entity
+
+| Param | Type | Description |
+| --- | --- | --- |
+| [engine] | <code>external:Serpentity</code> | the serpentity engine to attach to. If not sent, it will not be attached. |
+| [config] | <code>object</code> | 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. |
+
--- /dev/null
+import { Component } from '@serpentity/serpentity';
+
+/**
+ * Component that stores an angle
+ *
+ * @extends {external:Serpentity.Component}
+ * @class AngleComponent
+ * @param {object} config a configuration object to extend.
+ */
+export default class AngleComponent extends Component {
+ constructor(config) {
+
+ super(config);
+
+ /**
+ * The properthy that holds the pixi container
+ *
+ * @property {external:MatterJs.Angle} angle
+ * @instance
+ * @memberof AngleComponent
+ */
+ this.angle = this.angle || 0;
+ }
+};
+
--- /dev/null
+import { Component } from '@serpentity/serpentity';
+
+/**
+ * Component that stores a body for physics calculation
+ *
+ * @extends {external:Serpentity.Component}
+ * @class BodyComponent
+ * @param {object} config a configuration object to extend.
+ */
+export default class BodyComponent extends Component {
+ constructor(config) {
+
+ super(config);
+
+ /**
+ * The properthy that holds the pixi container
+ *
+ * @property {external:MatterJs.Body} body
+ * @instance
+ * @memberof BodyComponent
+ */
+ this.body = this.body || null;
+ }
+};
+
--- /dev/null
+import { Component } from '@serpentity/serpentity';
+
+/**
+ * Component that stores a number of entities coupled to this one.
+ *
+ * @extends {external:Serpentity.Component}
+ * @class CoupledEntitiesComponent
+ * @param {object} config a configuration object to extend.
+ */
+export default class CoupledEntitiesComponent extends Component {
+ constructor(config) {
+
+ super(config);
+
+ /**
+ * An array of coupled entities
+ *
+ * @property {Array<external:Serpentity.Entity>} coupledEntities
+ * @instance
+ * @memberof CoupledEntitiesComponent
+ */
+ this.coupledEntities = this.coupledEntities || [];
+ }
+};
+
* @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();
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();
}
};
+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.
*
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);
}
--- /dev/null
+import { Node } from '@serpentity/serpentity';
+
+import BodyComponent from '../components/body';
+
+/**
+ * Node identifying an entity that can interact with physics
+ *
+ * @extends {external:Serpentity.Node}
+ * @class PhysicalNode
+ */
+export default class PhysicalNode extends Node {
+
+};
+
+/**
+ * Holds the types that are used to identify an entity with a physical
+ * body
+ *
+ * @property {object} types
+ * @name types
+ * @memberof PhysicalNode
+ */
+PhysicalNode.types = {
+ body: BodyComponent
+};
+
--- /dev/null
+import { Node } from '@serpentity/serpentity';
+
+import AngleComponent from '../components/angle';
+import BodyComponent from '../components/body';
+import PositionComponent from '@serpentity/components.position';
+
+/**
+ * Node identifying an entity that can interact with physics and has
+ * components updated from its values
+ *
+ * @extends {external:Serpentity.Node}
+ * @class PhysicalWithAttributesNode
+ */
+export default class PhysicalWithAttributesNode extends Node {
+
+};
+
+/**
+ * Holds the types that are used to identify an entity with a physics
+ * object and external attributes
+ *
+ * @property {object} types
+ * @name types
+ * @memberof PhysicalWithAttributesNode
+ */
+PhysicalWithAttributesNode.types = {
+ angle: AngleComponent,
+ position: PositionComponent,
+ body: BodyComponent
+};
+
import { Node } from '@serpentity/serpentity';
import PixiContainerComponent from '../components/pixi_container';
-import PositionComponent from '@serpentity/components.position';
/**
- * Node identifying a renderable entity, should have position and a
- * symbol to render
+ * Node identifying a renderable entity, should have a pixi renderable
*
* @extends {external:Serpentity.Node}
* @class RenderableNode
};
/**
- * Holds the types that are used to identify a wave entity
+ * Holds the types that are used to identify a renderable entity
*
* @property {object} types
* @name types
- * @memberof WaveNode
+ * @memberof RenderableNode
*/
RenderableNode.types = {
- position: PositionComponent,
container: PixiContainerComponent
};
--- /dev/null
+import { Node } from '@serpentity/serpentity';
+
+import CoupledEntitiesComponent from '../components/coupled_entities';
+import PixiContainerComponent from '../components/pixi_container';
+
+/**
+ * Node identifying an entity that has coupled entities and can be
+ * rendered
+ *
+ * @extends {external:Serpentity.Node}
+ * @class RenderableCoupleNode
+ */
+export default class RenderableCoupleNode extends Node {
+
+};
+
+/**
+ * Holds the types that are used to identify a renderable couple
+ *
+ * @property {object} types
+ * @name types
+ * @memberof RenderableCoupleNode
+ */
+RenderableCoupleNode.types = {
+ coupledEntities: CoupledEntitiesComponent,
+ container: PixiContainerComponent
+};
+
--- /dev/null
+import { Node } from '@serpentity/serpentity';
+
+import AngleComponent from '../components/angle';
+import PixiContainerComponent from '../components/pixi_container';
+import PositionComponent from '@serpentity/components.position';
+
+/**
+ * Node identifying a renderable entity, should have position and a
+ * symbol to render
+ *
+ * @extends {external:Serpentity.Node}
+ * @class RenderableWithAttributesNode
+ */
+export default class RenderableWithAttributesNode extends Node {
+
+};
+
+/**
+ * Holds the types that are used to identify a renderable with external
+ * attributes
+ *
+ * @property {object} types
+ * @name types
+ * @memberof RenderableWithAttributesNode
+ */
+RenderableWithAttributesNode.types = {
+ angle: AngleComponent,
+ position: PositionComponent,
+ container: PixiContainerComponent
+};
+import PhysicsWorldControlSystem from './systems/physics_world_control';
+import PhysicsToAttributesSystem from './systems/physics_to_attributes';
+import CreateCouplingLineSystem from './systems/create_coupling_line';
import RenderSystem from './systems/render';
+import AttributesToRenderableSystem from './systems/attributes_to_renderable';
import SumoFactory from './factories/sumo';
import Serpentity from '@serpentity/serpentity';
import { Application } from 'pixi.js';
+import { Engine } from 'matter-js';
/* global window document */
// Initialization functions
this._initializeCanvas();
+ this._initializeMatter();
this._initializePixi();
this._initializeSystems();
this._initializeEntities();
window.addEventListener('resize', this._resizeCanvas.bind(this));
}
+ // Initialize MatterJs
+
+ _initializeMatter() {
+
+ this._matterJs = Engine.create();
+
+ this._matterJs.world.gravity.y = 0;
+ }
+
// Initialize Pixi
_initializePixi() {
_initializeSystems() {
+ this._engine.addSystem(new PhysicsWorldControlSystem({
+ engine: this._matterJs
+ }));
+
+ this._engine.addSystem(new PhysicsToAttributesSystem());
+
+ this._engine.addSystem(new AttributesToRenderableSystem());
+
+ this._engine.addSystem(new CreateCouplingLineSystem());
+
this._engine.addSystem(new RenderSystem({
application: this._pixi
}));
_initializeEntities() {
- SumoFactory.createSumo(this._engine, {
+ const entityA = SumoFactory.createSumo(null, {
position: {
x: 50,
y: 50
}
});
- SumoFactory.createSumo(this._engine, {
+ const entityB = SumoFactory.createSumo(null, {
position: {
x: 309,
y: 112
}
});
+
+ const entityC = SumoFactory.createSumo(null, {
+ position: {
+ x: 500,
+ y: 78
+ }
+ });
+
+ SumoFactory.createRubberBand(this._engine, {
+ entityA,
+ entityB
+ });
+
+ SumoFactory.createRubberBand(this._engine, {
+ entityA: entityC,
+ entityB
+ });
+
+ // To keep the coupling behind, we'll manually add the sumos later
+
+ this._engine.addEntity(entityA);
+ this._engine.addEntity(entityB);
+ this._engine.addEntity(entityC);
}
};
--- /dev/null
+import { System } from '@serpentity/serpentity';
+
+import RenderableWithAttributesNode from '../nodes/renderable_with_attributes';
+
+/**
+ * Updates the renderables based on their attribuets
+ *
+ * @extends {external:Serpentity.System}
+ * @class AttributesToRenderableSystem
+ * @param {object} config a configuration object to extend.
+ */
+export default class AttributesToRenderableSystem extends System {
+
+ constructor(config = {}) {
+
+ super();
+
+ /**
+ * The node collection of renderable entities
+ *
+ * @property {external:Serpentity.NodeCollection} renderables
+ * @instance
+ * @memberof AttributesToRenderableSystem
+ */
+ this.renderables = null;
+ }
+
+ /**
+ * Initializes system when added. Requests renderable nodes and
+ * attaches to event listeners to add / remove them to pixi stage
+ *
+ * @function added
+ * @memberof AttributesToRenderableSystem
+ * @instance
+ * @param {external:Serpentity.Engine} engine the serpentity engine to
+ * which we are getting added
+ */
+ added(engine) {
+
+ this.renderables = engine.getNodes(RenderableWithAttributesNode);
+ }
+
+ /**
+ * Clears system resources when removed.
+ *
+ * @function removed
+ * @instance
+ * @memberof AttributesToRenderableSystem
+ */
+ removed() {
+
+ this.renderables = null;
+ }
+
+ /**
+ * Runs on every update of the loop. Updates the graphics so they're
+ * rendered correctly
+ *
+ * @function update
+ * @instance
+ * @param {Number} currentFrameDuration the duration of the current
+ * frame
+ * @memberof AttributesToRenderableSystem
+ */
+ update(currentFrameDuration) {
+
+ for (const renderable of this.renderables) {
+ renderable.container.container.position.x = renderable.position.x;
+ renderable.container.container.position.y = renderable.position.y;
+ renderable.container.container.rotation = renderable.angle.angle;
+ }
+ }
+};
--- /dev/null
+import { System } from '@serpentity/serpentity';
+import { Graphics } from 'pixi.js';
+
+import PositionComponent from '@serpentity/components.position';
+
+import RenderableCoupleNode from '../nodes/renderable_couple';
+
+/**
+ * Renders renderable objects using pixi
+ *
+ * @extends {external:Serpentity.System}
+ * @class CreateCouplingLineSystem
+ * @param {object} config a configuration object to extend.
+ */
+export default class CreateCouplingLineSystem extends System {
+
+ constructor(config = {}) {
+
+ super();
+
+ /**
+ * The node collection of coupled entities entities
+ *
+ * @property {external:Serpentity.NodeCollection} coupledEntities
+ * @instance
+ * @memberof CreateCouplingLineSystem
+ */
+ this.coupledEntities = null;
+ }
+
+ /**
+ * Initializes system when added. Requests renderable nodes and
+ *
+ * @function added
+ * @memberof CreateCouplingLineSystem
+ * @instance
+ * @param {external:Serpentity.Engine} engine the serpentity engine to
+ * which we are getting added
+ */
+ added(engine) {
+
+ this.coupledEntities = engine.getNodes(RenderableCoupleNode);
+ }
+
+ /**
+ * Clears system resources when removed.
+ *
+ * @function removed
+ * @instance
+ * @memberof CreateCouplingLineSystem
+ */
+ removed() {
+
+ this.coupledEntities = null;
+ }
+
+ /**
+ * Runs on every update of the loop. Does nothing.
+ *
+ * @function update
+ * @instance
+ * @param {Number} currentFrameDuration the duration of the current
+ * frame
+ * @memberof CreateCouplingLineSystem
+ */
+ update(currentFrameDuration) {
+
+ for (const rootEntity of this.coupledEntities) {
+
+ const rootGraphic = rootEntity.container.container;
+ rootGraphic.removeChildren();
+
+ let lineGraphic = new Graphics();
+ lineGraphic = lineGraphic.lineStyle(5, 0xffffff, 0.9);
+
+ let initialPosition = false;
+
+ for (const coupledEntity of rootEntity.coupledEntities.coupledEntities) {
+ if (coupledEntity.hasComponent(PositionComponent)) {
+
+ const position = coupledEntity.getComponent(PositionComponent);
+
+ if (!initialPosition) {
+ lineGraphic = lineGraphic.moveTo(position.x, position.y);
+ initialPosition = true;
+ continue;
+ }
+ lineGraphic = lineGraphic.lineTo(position.x, position.y);
+ }
+ }
+
+ rootGraphic.addChild(lineGraphic);
+ }
+ }
+};
+
--- /dev/null
+import { System } from '@serpentity/serpentity';
+
+import PhysicalWithAttributesNode from '../nodes/physical_with_attributes';
+
+/**
+ * Distribuets physics data to the related components
+ *
+ * @extends {external:Serpentity.System}
+ * @class PhysicsToAttributesSystem
+ * @param {object} config a configuration object to extend.
+ */
+export default class PhysicsToAttributesSystem extends System {
+
+ constructor(config = {}) {
+
+ super();
+
+ /**
+ * The node collection of physics entities
+ *
+ * @property {external:Serpentity.NodeCollection} physicalEntities
+ * @instance
+ * @memberof PhysicsToAttributesSystem
+ */
+ this.physicalEntities = null;
+ }
+
+ /**
+ * Initializes system when added. Requests physics nodes
+ *
+ * @function added
+ * @memberof PhysicsToAttributesSystem
+ * @instance
+ * @param {external:Serpentity.Engine} engine the serpentity engine to
+ * which we are getting added
+ */
+ added(engine) {
+
+ this.physicalEntities = engine.getNodes(PhysicalWithAttributesNode);
+ }
+
+ /**
+ * Clears system resources when removed.
+ *
+ * @function removed
+ * @instance
+ * @memberof PhysicsToAttributesSystem
+ */
+ removed() {
+
+ this.physicalEntities = null;
+ }
+
+ /**
+ * Runs on every update of the loop. Updates the other components
+ * based on physics
+ *
+ * @function update
+ * @instance
+ * @param {Number} currentFrameDuration the duration of the current
+ * frame
+ * @memberof PhysicsToAttributesSystem
+ */
+ update(currentFrameDuration) {
+
+ for (const physicalEntity of this.physicalEntities) {
+ physicalEntity.position.x = physicalEntity.body.body.position.x;
+ physicalEntity.position.y = physicalEntity.body.body.position.y;
+ physicalEntity.angle.angle = physicalEntity.body.body.angle;
+ }
+ }
+};
--- /dev/null
+import { System } from '@serpentity/serpentity';
+import { Engine, World } from 'matter-js';
+
+import PhysicalNode from '../nodes/physical';
+
+const internals = {
+ kNoEngine: 'No matter js physics engine found. Make sure you set the `engine` key in the config object when initializing.'
+};
+
+/**
+ * Adds and removes objects to the physics world and calls update
+ *
+ * @extends {external:Serpentity.System}
+ * @class PhysicsWorldControlSystem
+ * @param {object} config a configuration object to extend.
+ */
+export default class PhysicsWorldControlSystem extends System {
+
+ constructor(config = {}) {
+
+ super();
+
+ /**
+ * The node collection of physics entities
+ *
+ * @property {external:Serpentity.NodeCollection} physicalEntities
+ * @instance
+ * @memberof PhysicsWorldControlSystem
+ */
+ this.physicalEntities = null;
+
+ /**
+ * The matter-js engine we will use to process physics
+ *
+ * @property {external:MatterJs.Engine} engine
+ * @instance
+ * @memberof PhysicsWorldControlSystem
+ */
+ this.engine = config.engine;
+
+ if (!this.engine) {
+ throw new Error(internals.kNoEngine);
+ }
+ }
+
+ /**
+ * Initializes system when added. Requests physics nodes and
+ * attaches to event listeners to add / remove them to pixi stage
+ *
+ * @function added
+ * @memberof PhysicsWorldControlSystem
+ * @instance
+ * @param {external:Serpentity.Engine} engine the serpentity engine to
+ * which we are getting added
+ */
+ added(engine) {
+
+ this.physicalEntities = engine.getNodes(PhysicalNode);
+ this.physicalEntities.on('nodeAdded', (event) => {
+
+ World.add(this.engine.world, [event.node.body.body]);
+ });
+ this.physicalEntities.on('nodeRemoved', (event) => {
+
+ World.remove(this.engine.world, [event.node.body.body]);
+ });
+ }
+
+ /**
+ * Clears system resources when removed.
+ *
+ * @function removed
+ * @instance
+ * @memberof PhysicsWorldControlSystem
+ */
+ removed() {
+
+ this.physicalEntities.removeAllListeners('nodeAdded');
+ this.physicalEntities.removeAllListeners('nodeRemoved');
+ this.physicalEntities = null;
+ }
+
+ /**
+ * Runs on every update of the loop. Updates the physics
+ *
+ * @function update
+ * @instance
+ * @param {Number} currentFrameDuration the duration of the current
+ * frame
+ * @memberof PhysicsWorldControlSystem
+ */
+ update(currentFrameDuration) {
+
+ Engine.run(this.engine);
+ }
+};
+
+
};
/**
- * Renders renderable objects to console
+ * Renders renderable objects using pixi
*
* @extends {external:Serpentity.System}
* @class RenderSystem
}
/**
- * Runs on every update of the loop. Prints the location of every
- * renderable
+ * Runs on every update of the loop. Does nothing.
*
* @function update
* @instance
* frame
* @memberof RenderSystem
*/
- update(currentFrameDuration) {
-
- for (const renderable of this.renderables) {
- renderable.container.container.position.x = renderable.position.x;
- renderable.container.container.position.y = renderable.position.y;
- }
- }
+ update(currentFrameDuration) {}
};
"integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==",
"dev": true
},
+ "matter-js": {
+ "version": "0.14.1",
+ "resolved": "https://registry.npmjs.org/matter-js/-/matter-js-0.14.1.tgz",
+ "integrity": "sha512-qbPBf5NpjPfNlxiRXpoJHAnMMF4WNP22mRhkas0hsUnVTztFBt3QpxRChEws4j1YuaH2bCXEd2i4qmRwADqyuA=="
+ },
"md5.js": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
"@serpentity/components.debug": "^2.0.0",
"@serpentity/components.position": "^2.0.0",
"@serpentity/serpentity": "^2.1.0",
+ "matter-js": "^0.14.1",
"pixi.js": "^4.7.3"
},
"browserslist": "last two versions",