--- /dev/null
+'use strict';
+
+/*
+Serpentity is a simple entity framework inspired by Ash.
+
+Usage:
+
+ let Serpentity = require('serpentity');
+
+## Instantiating an engine
+
+ let engine = Serpentity();
+
+Add entities or systems, systems are added with a priority (the smaller
+the number, the earlier it will be called):
+
+ engine.addEntity(entityFactory());
+ engine.addSystem(new GameSystem(), priority);
+
+Update all systems:
+
+ engine.update(dt);
+
+Remove entities or systems:
+
+ engine.removeEntity(entityReference);
+ engine.removeSystem(systemReference);
+
+## Creating Entities
+
+Entities are the basic object of Serpentity, and they do nothing.
+
+ let entity = new Serpentity.Entity();
+
+All the behavior is added through components
+
+## Creating Components
+
+Components define data that we can add to an entity. This data will
+eventually be consumed by "Systems"
+
+ let PositionComponent = class PositionComponent extends Serpentity.Component {
+ constructor (config) {
+ this.x = 0;
+ this.y = 0;
+
+ super(config);
+ }
+ };
+
+You can add components to entities by using the add method:
+
+ entity.addComponent(new PositionComponent());
+
+
+Systems can refer to entities by requesting nodes.
+
+## Working with Nodes
+
+Nodes are sets of components that you define, so your system can require
+entities that always follow the API defined in the node.
+
+ let MovementNode = class MovementNode extends Serpentity.Node;
+ MovementNode.position = PositionComponent;
+ MovementNode.motion = MotionComponent;
+
+You can then request an array of all the nodes representing entities
+that comply with that API
+
+ engine.getNodes(MovementNode);
+
+## Creating Systems
+
+Systems are called on every update, and they use components through nodes.
+
+ let TestSystem = class TestSystem extends Serpentity.System {
+ added (engine){
+ this.nodeList = engine.getNodes(MovementNode);
+ },
+ removed (engine){
+ this.nodeList = undefined;
+ }
+ update (dt){
+ let node;
+ for (node of this.nodeList) {
+ console.log(`Current position is: ${node.position.x},${node.position.y}`);
+ }
+ }
+ };
+
+## That's it
+
+Just run `engine.update(dt)` in your game loop :D
+
+*/
+let Serpentity = class Serpentity {
+
+ constructor (config) {
+ this.systems = [];
+ this.entities = [];
+ this._nodeCollections = [];
+ this._nodeCollectionKeys = [];
+
+ Object.assign(this, config || {});
+ }
+
+ /*
+ * Adds a system to the engine, so its update method will be called
+ * with the others. Triggers added hook.
+ *
+ * returns true if added succesfully, false if already added
+ */
+ addSystem (system, priority) {
+ let lastIndex, found;
+
+ if (this.systems.indexOf(system) >= 0) {
+ return false;
+ }
+
+ system.priority = priority;
+
+ found = false;
+ lastIndex = 0;
+
+ this.systems.some(function findPriority(existingSystem, i) {
+ lastIndex = i;
+ if (existingSystem.priority >= system.priority) {
+ found = true;
+ return true;
+ }
+ });
+
+ if (!found) {
+ lastIndex += 1;
+ }
+
+ this.systems.splice(lastIndex, 0, system);
+ system.added(this);
+ return true;
+ }
+
+ /*
+ * Removes a system from the engine, so its update method will no
+ * longer will be called. Triggers the removed hook.
+ *
+ * returns true if removed succesfully, false if already added
+ */
+ removeSystem (system) {
+ let position;
+
+ position = this.systems.indexOf(system);
+ if (position >= 0) {
+ this.systems[position].removed(this);
+ this.systems.splice(position, 1);
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Adds an entity to the engine, adds to existing node collections
+ *
+ * returns true if added, false if already there
+ */
+ addEntity (entity) {
+ if (this.entities.indexOf(entity) >= 0) {
+ return false;
+ }
+ this.entities.push(entity);
+
+ this._nodeCollections.forEach(function (collection) {
+ collection.add(entity);
+ });
+
+ return true;
+ }
+
+ /*
+ * Removes entity from system, removing from all node collections
+ *
+ * returns true if removed, false if not present
+ */
+ removeEntity (entity) {
+ let position;
+
+ position = this.entities.indexOf(entity);
+ if (position >= 0) {
+ this._nodeCollections.forEach(function (collection) {
+ collection.remove(entity);
+ });
+
+ this.entities.splice(position, 1);
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Given a Node Class, retrieves a list of all the nodes for each
+ * applicable entity.
+ */
+ getNodes (nodeType) {
+ let position, nodeCollection;
+
+ position = this._nodeCollectionKeys.indexOf(nodeType);
+
+ if (position >= 0) {
+ return this._nodeCollections[position].nodes;
+ }
+
+ nodeCollection = new Serpentity.NodeCollection({
+ type : nodeType
+ });
+
+ this._nodeCollectionKeys.push(nodeType);
+ this._nodeCollections.push(nodeCollection);
+
+ this.entities.forEach(function (entity) {
+ nodeCollection.add(entity);
+ });
+
+ return nodeCollection.nodes;
+ }
+
+ /*
+ * Calls update for every loaded system.
+ */
+ update (dt) {
+ this.systems.forEach(function (system) {
+ system.update(dt);
+ });
+ }
+};
+
+// Add namespaced objects.
+if (typeof module !== 'undefined' && this.module !== module) {
+ Serpentity.Component = require('./serpentity/component.js');
+ Serpentity.Entity = require('./serpentity/entity.js');
+ Serpentity.Node = require('./serpentity/node.js');
+ Serpentity.NodeCollection = require('./serpentity/node_collection.js');
+ Serpentity.System = require('./serpentity/system.js');
+
+ module.exports = Serpentity;
+} else {
+ window.Serpentity = Serpentity;
+}
+'use strict';
+
+/* global Serpentity */
+
/*
* Components store data. Nothing to say here really, just
* inherit and add a prototype, or don't even inherit, see?
* It's just an empty class, so what I'm trying to say is your
* components can be any class whatsoever.
*/
-Class(Serpentity, "Component")({
- prototype : {
- init : function init(config) {
- var property;
- config = config || {};
+let Component = class Component {
+ constructor (config) {
+ Object.assign(this, config || {});
+ }
+};
- for (property in config) {
- if (config.hasOwnProperty(property)) {
- this[property] = config[property];
- }
- }
- }
- }
-});
+if (typeof module !== 'undefined' && this.module !== module) {
+ module.exports = Component;
+} else {
+ Serpentity.Component = Component;
+}
+'use strict';
+
+/* global Serpentity */
+
/*
* The entity gives the entity framework its name. It exists only
* to hold components.
*/
-Class(Serpentity, "Entity")({
- prototype : {
- _components : null,
- _componentKeys : null,
-
- init : function init(config) {
- var property;
-
- this._componentKeys = [];
- this._components = [];
-
- for (property in config) {
- if (config.hasOwnProperty(property)) {
- this[property] = config[property];
- }
- }
- },
-
- /*
- * Adds a component to the entity.
- *
- * returns true if added, false if already present
- */
- addComponent : function addComponent(component) {
- if (this._componentKeys.indexOf(component.constructor) >= 0) {
- return false;
- }
- this._componentKeys.push(component.constructor);
- this._components.push(component);
- return true;
- },
-
- /*
- * returns true if component is included, false otherwise
- */
- hasComponent : function hasComponent(componentClass) {
- if (this._componentKeys.indexOf(componentClass) >= 0) {
- return true;
- }
- return false;
- },
-
- /*
- * returns the component associated with that key
- */
- getComponent : function getComponent(componentClass) {
- var position;
- position = this._componentKeys.indexOf(componentClass);
- if (position >= 0) {
- return this._components[position];
- }
- }
+
+let Entity = class Entity {
+ constructor (config) {
+ this._componentKeys = [];
+ this._components = [];
+
+ Object.assign(this, config || {});
+ }
+
+ /*
+ * Adds a component to the entity.
+ *
+ * returns true if added, false if already present
+ */
+ addComponent (component) {
+ if (this._componentKeys.indexOf(component.constructor) >= 0) {
+ return false;
}
-});
+ this._componentKeys.push(component.constructor);
+ this._components.push(component);
+ return true;
+ }
+
+ /*
+ * returns true if component is included, false otherwise
+ */
+ hasComponent (componentClass) {
+ if (this._componentKeys.indexOf(componentClass) >= 0) {
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * returns the component associated with that key
+ */
+ getComponent (componentClass) {
+ let position;
+ position = this._componentKeys.indexOf(componentClass);
+ if (position >= 0) {
+ return this._components[position];
+ }
+ }
+};
+
+if (typeof module !== 'undefined' && this.module !== module) {
+ module.exports = Entity;
+} else {
+ Serpentity.Entity = Entity;
+}
+'use strict';
+
+/* global Serpentity */
+
/*
* A node describes a set of components in order to describe entities
* that include them.
*/
-Class(Serpentity, "Node")({
-
- /*
- * Returns true if the given entity matches the defined protocol,
- * false otherwise
- */
- matches : function matches(entity) {
- var property, matched, types;
-
- types = this.types;
-
- for (property in this.types) {
-
- if (this.types.hasOwnProperty(property)) {
- matched = false;
+let Node = class Node {
- if (entity.hasComponent(types[property])) {
- matched = true;
- }
+ /*
+ * Returns true if the given entity matches the defined protocol,
+ * false otherwise
+ */
+ static matches (entity) {
+ let property, types;
- if (!matched) {
- return false;
- }
- }
- }
+ types = this.types;
- return true;
- },
+ for (property in types) {
+ if (types.hasOwnProperty(property)) {
+ let matched, type;
- prototype : {
+ matched = false;
+ type = types[property];
+ if (entity.hasComponent(type)) {
+ matched = true;
+ }
+ if (!matched) {
+ return false;
+ }
+ }
+ }
- types : null,
+ return true;
+ }
- init : function (config) {
- var property;
+ constructor (config) {
+ this.types = {};
- this.types = {};
+ Object.assign(this, config || {});
+ }
+};
- for (property in this.constructor) {
- if (this.constructor.hasOwnProperty(property)) {
- this.types[property] = this.constructor[property];
- }
- }
- }
- }
-});
+if (typeof module !== 'undefined' && this.module !== module) {
+ module.exports = Node;
+} else {
+ Serpentity.Node = Node;
+}
+'use strict';
+
+/* global Serpentity */
+
/*
* Node Collections contain nodes, in order to keep the lists of nodes
* that belong to each type.
* It has a type which is the class name of the node, and an array of
* instances of that class.
*/
-Class(Serpentity, "NodeCollection")({
- prototype : {
- type : null,
- nodes : null,
-
- init : function init(config) {
- var property;
-
- config = config || {};
-
- this.nodes = [];
-
- for (property in config) {
- if (config.hasOwnProperty(property)) {
- this[property] = config[property];
- }
- }
- },
-
- /*
- * Creates a node for an entity if it matches, and adds it to the
- * node list.
- *
- * Returns true if added, false otherwise.
- */
- add : function add(entity) {
- var node, types, property;
-
- if (this.type.matches(entity) && !this._entityExists(entity)) {
- node = new this.type({});
-
- node.entity = entity;
-
- types = this.type.types;
-
- for (property in types) {
- if (types.hasOwnProperty(property)) {
- node[property] = entity.getComponent(types[property]);
- }
- }
-
- this.nodes.push(node);
-
- return true;
- }
-
- return false;
- },
-
- /*
- * Removes an entity by removing its related node from the list of nodes
- *
- * returns true if it was removed, false otherwise.
- */
- remove : function (entity) {
- var found;
- found = -1;
- this.nodes.forEach(function (node, i) {
- if (node.entity === entity) {
- found = i;
- }
- });
-
- if (found >= 0) {
- this.nodes.splice(found, 1);
- return true;
- }
-
- return false;
- },
-
- /*
- * Checks whether we already have nodes for this entity.
- */
- _entityExists : function entityExists(entity) {
- var found;
- found = false;
- this.nodes.forEach(function (node) {
- if (node.entity === entity) {
- found = true;
- }
- });
-
- return found;
+
+let NodeCollection = class NodeCollection {
+
+ constructor (config) {
+ this.nodes = [];
+ this.type = null;
+
+ Object.assign(this, config || {});
+ }
+
+ /*
+ * Creates a node for an entity if it matches, and adds it to the
+ * node list.
+ *
+ * Returns true if added, false otherwise.
+ */
+ add (entity) {
+
+ if (this.type.matches(entity) && !this._entityExists(entity)) {
+ let node, types, property;
+
+ node = new this.type({});
+ node.entity = entity;
+ types = this.type.types;
+
+ for (property in types) {
+ if (types.hasOwnProperty(property)) {
+ node[property] = entity.getComponent(types[property]);
}
+ }
+
+ this.nodes.push(node);
+
+ return true;
+ }
+
+ return false;
+ }
+
+ /*
+ * Removes an entity by removing its related node from the list of nodes
+ *
+ * returns true if it was removed, false otherwise.
+ */
+ remove (entity) {
+ let found;
+
+ found = -1;
+ this.nodes.forEach(function (node, i) {
+ if (node.entity === entity) {
+ found = i;
+ }
+ });
+
+ if (found >= 0) {
+ this.nodes.splice(found, 1);
+ return true;
}
-});
+
+ return false;
+ }
+
+ /*
+ * Checks whether we already have nodes for this entity.
+ */
+ _entityExists (entity) {
+ let found, node;
+
+ found = false;
+ for (node of this.nodes) {
+ if (node.entity === entity) {
+ found = true;
+ }
+ }
+
+ return found;
+ }
+};
+
+if (typeof module !== 'undefined' && this.module !== module) {
+ module.exports = NodeCollection;
+} else {
+ Serpentity.NodeCollection = NodeCollection;
+}
+++ /dev/null
-if (typeof require !== "undefined") {
- require("neon");
-}
-
-/*
-Serpentity is a simple entity framework inspired by Ash.
-
-Usage:
-
- require('serpentity');
-
-## Instantiating an engine
-
- var engine = Serpentity();
-
-Add entities or systems, systems are added with a priority (the smaller
-the number, the earlier it will be called):
-
- engine.addEntity(entityFactory());
- engine.addSystem(new GameSystem(), priority);
-
-Update all systems:
-
- engine.update(dt);
-
-Remove entities or systems:
-
- engine.removeEntity(entityReference);
- engine.removeSystem(systemReference);
-
-## Creating Entities
-
-Entities are the basic object of Serpentity, and they do nothing.
-
- var entity = new Serpentity.Entity();
-
-All the behavior is added through components
-
-## Creating Components
-
-Components define data that we can add to an entity. This data will
-eventually be consumed by "Systems"
-
- Class("PositionComponent").inherits(Serpentity.Component)({
- prototype : {
- x : 0,
- y : 0
- }
- });
-
-You can add components to entities by using the add method:
-
- entity.addComponent(new PositionComponent());
-
-
-Systems can refer to entities by requesting nodes.
-
-## Working with Nodes
-
-Nodes are sets of components that you define, so your system can require
-entities that always follow the API defined in the node.
-
- Class("MovementNode").inherits(Serpentity.Node)({
- types : {
- position : PositionComponent,
- motion : MotionComponent
- }
- });
-
-You can then request an array of all the nodes representing entities
-that comply with that API
-
- engine.getNodes(MovementNode);
-
-## Creating Systems
-
-Systems are called on every update, and they use components through nodes.
-
- Class("TestSystem").inherits(Serpentity.System)({
- prototype : {
- added : function added(engine){
- this.nodeList = engine.getNodes(MovementNode);
- },
- removed : function removed(engine){
- this.nodeList = undefined;
- }
- update : function update(dt){
- this.nodeList.forEach(function (node) {
- console.log("Current position is: " + node.position.x + "," + node.position.y);
- });
- }
- }
- });
-
-## That's it
-
-Just run `engine.update(dt)` in your game loop :D
-
-*/
-Class("Serpentity")({
- prototype : {
- systems : null,
- entities : null,
- _nodeCollections : null,
- _nodeCollectionKeys : null,
-
- init : function init(config) {
- var property;
-
- config = config || {};
-
- this.systems = [];
- this.entities = [];
- this._nodeCollections = [];
- this._nodeCollectionKeys = [];
-
- for (property in config) {
- if (config.hasOwnProperty(property)) {
- this[property] = config[property];
- }
- }
- },
-
- /*
- * Adds a system to the engine, so its update method will be called
- * with the others. Triggers added hook.
- *
- * returns true if added succesfully, false if already added
- */
- addSystem : function addSystem(system, priority) {
- var lastIndex, found;
-
- if (this.systems.indexOf(system) >= 0) {
- return false;
- }
-
- system.priority = priority;
-
- found = false;
- lastIndex = 0;
-
- this.systems.some(function findPriority(existingSystem, i) {
- lastIndex = i;
- if (existingSystem.priority >= system.priority) {
- found = true;
- return true;
- }
- });
-
- if (!found) {
- lastIndex += 1
- }
-
- this.systems.splice(lastIndex, 0, system);
- system.added(this);
- return true;
- },
-
- /*
- * Removes a system from the engine, so its update method will no
- * longer will be called. Triggers the removed hook.
- *
- * returns true if removed succesfully, false if already added
- */
- removeSystem : function removeSystem(system) {
- var position;
-
- position = this.systems.indexOf(system);
- if (position >= 0) {
- this.systems[position].removed(this);
- this.systems.splice(position, 1);
- return true;
- }
-
- return false;
- },
-
- /*
- * Adds an entity to the engine, adds to existing node collections
- *
- * returns true if added, false if already there
- */
- addEntity : function addEntity(entity) {
- if (this.entities.indexOf(entity) >= 0) {
- return false;
- }
- this.entities.push(entity);
-
- this._nodeCollections.forEach(function (collection) {
- collection.add(entity);
- });
-
- return true;
- },
-
- /*
- * Removes entity from system, removing from all node collections
- *
- * returns true if removed, false if not present
- */
- removeEntity : function removeEntity(entity) {
- var position;
-
- position = this.entities.indexOf(entity);
- if (position >= 0) {
- this._nodeCollections.forEach(function (collection) {
- collection.remove(entity);
- });
-
- this.entities.splice(position, 1);
- return true;
- }
-
- return false;
- },
-
- /*
- * Given a Node Class, retrieves a list of all the nodes for each
- * applicable entity.
- */
- getNodes : function getNodes(nodeType) {
- var position, nodeCollection;
-
- position = this._nodeCollectionKeys.indexOf(nodeType);
-
- if (position >= 0) {
- return this._nodeCollections[position].nodes;
- }
-
- nodeCollection = new Serpentity.NodeCollection({
- type : nodeType,
- });
-
- this._nodeCollectionKeys.push(nodeType);
- this._nodeCollections.push(nodeCollection);
-
- this.entities.forEach(function (entity) {
- nodeCollection.add(entity);
- });
-
- return nodeCollection.nodes;
- },
-
- /*
- * Calls update for every loaded system.
- */
- update : function update(dt) {
- this.systems.forEach(function (system) {
- system.update(dt);
- });
- }
- }
-});
-
-if (typeof require !== "undefined") {
- require("./component.js");
- require("./entity.js");
- require("./node.js");
- require("./node_collection.js");
- require("./system.js");
-}
+'use strict';
+
+/* global Serpentity */
+
/*
* Systems contain most of the logic, and work with nodes in order to
* act and change their values.
*
* You usually want to inherit from this class and override the
- * three methods.
+ * three methods. They are shown here to document the interface.
*/
-Class(Serpentity, "System")({
- prototype : {
- /*
- * This will be run when the system is added to the engine
- */
- added : function added(engine) {
- // Override
- },
+let System = class System {
+
+ /*
+ * This will be run when the system is added to the engine
+ */
+ added () {
+ // Override with added(engine)
+ // Receives an instance of the serpentity engine
+ }
+
+ /*
+ * This will be run when the system is removed from the engine
+ */
+ removed () {
+ // Override with removed(engine)
+ // Receives an instance of the serpentity engine
+ }
- /*
- * This will be run when the system is removed from the engine
- */
- removed : function removed(engine) {
- // Override
- },
+ /*
+ * This will run every time the engine's update method is called
+ */
+ update () {
+ // Override with update(dt)
+ // Receives a delta of the time
+ }
+};
- /*
- * This will run every time the engine's update method is called
- */
- update : function update(dt) {
- // Override
- }
- }
-});
+if (typeof module !== 'undefined' && this.module !== module) {
+ module.exports = System;
+} else {
+ Serpentity.System = System;
+}