1 (function webpackUniversalModuleDefinition(root
, factory
) {
2 if(typeof exports
=== 'object' && typeof module
=== 'object')
3 module
.exports
= factory();
4 else if(typeof define
=== 'function' && define
.amd
)
6 else if(typeof exports
=== 'object')
7 exports
["Serpentity"] = factory();
9 root
["Serpentity"] = factory();
11 return /******/ (function(modules
) { // webpackBootstrap
12 /******/ // The module cache
13 /******/ var installedModules
= {};
15 /******/ // The require function
16 /******/ function __webpack_require__(moduleId
) {
18 /******/ // Check if module is in cache
19 /******/ if(installedModules
[moduleId
])
20 /******/ return installedModules
[moduleId
].exports
;
22 /******/ // Create a new module (and put it into the cache)
23 /******/ var module
= installedModules
[moduleId
] = {
29 /******/ // Execute the module function
30 /******/ modules
[moduleId
].call(module
.exports
, module
, module
.exports
, __webpack_require__
);
32 /******/ // Flag the module as loaded
33 /******/ module
.l
= true;
35 /******/ // Return the exports of the module
36 /******/ return module
.exports
;
40 /******/ // expose the modules object (__webpack_modules__)
41 /******/ __webpack_require__
.m
= modules
;
43 /******/ // expose the module cache
44 /******/ __webpack_require__
.c
= installedModules
;
46 /******/ // identity function for calling harmony imports with the correct context
47 /******/ __webpack_require__
.i = function(value
) { return value
; };
49 /******/ // define getter function for harmony exports
50 /******/ __webpack_require__
.d = function(exports
, name
, getter
) {
51 /******/ if(!__webpack_require__
.o(exports
, name
)) {
52 /******/ Object
.defineProperty(exports
, name
, {
53 /******/ configurable: false,
54 /******/ enumerable: true,
60 /******/ // getDefaultExport function for compatibility with non-harmony modules
61 /******/ __webpack_require__
.n = function(module
) {
62 /******/ var getter
= module
&& module
.__esModule
?
63 /******/ function getDefault() { return module
['default']; } :
64 /******/ function getModuleExports() { return module
; };
65 /******/ __webpack_require__
.d(getter
, 'a', getter
);
66 /******/ return getter
;
69 /******/ // Object.prototype.hasOwnProperty.call
70 /******/ __webpack_require__
.o = function(object
, property
) { return Object
.prototype.hasOwnProperty
.call(object
, property
); };
72 /******/ // __webpack_public_path__
73 /******/ __webpack_require__
.p
= "";
75 /******/ // Load entry module and return exports
76 /******/ return __webpack_require__(__webpack_require__
.s
= 5);
78 /************************************************************************/
81 /***/ (function(module
, exports
, __webpack_require__
) {
87 * Components store data. Nothing to say here really, just
88 * inherit and add a prototype, or don't even inherit, see?
89 * It's just an empty class, so what I'm trying to say is your
90 * components can be any class whatsoever.
93 function _classCallCheck(instance
, Constructor
) { if (!(instance
instanceof Constructor
)) { throw new TypeError("Cannot call a class as a function"); } }
95 var Component
= function Component(config
) {
96 _classCallCheck(this, Component
);
98 Object
.assign(this, config
);
101 module
.exports
= Component
;
105 /***/ (function(module
, exports
, __webpack_require__
) {
111 * The entity gives the entity framework its name. It exists only
112 * to hold components.
115 var _createClass = function () { function defineProperties(target
, props
) { for (var i
= 0; i
< props
.length
; i
++) { var descriptor
= props
[i
]; descriptor
.enumerable
= descriptor
.enumerable
|| false; descriptor
.configurable
= true; if ("value" in descriptor
) descriptor
.writable
= true; Object
.defineProperty(target
, descriptor
.key
, descriptor
); } } return function (Constructor
, protoProps
, staticProps
) { if (protoProps
) defineProperties(Constructor
.prototype, protoProps
); if (staticProps
) defineProperties(Constructor
, staticProps
); return Constructor
; }; }();
117 function _classCallCheck(instance
, Constructor
) { if (!(instance
instanceof Constructor
)) { throw new TypeError("Cannot call a class as a function"); } }
119 var Entity = function () {
120 function Entity(config
) {
121 _classCallCheck(this, Entity
);
123 this._componentKeys
= [];
124 this._components
= [];
126 Object
.assign(this, config
);
130 * Adds a component to the entity.
132 * returns true if added, false if already present
136 _createClass(Entity
, [{
138 value: function addComponent(component
) {
140 if (this._componentKeys
.indexOf(component
.constructor) >= 0) {
143 this._componentKeys
.push(component
.constructor);
144 this._components
.push(component
);
149 * returns true if component is included, false otherwise
154 value: function hasComponent(componentClass
) {
156 if (this._componentKeys
.indexOf(componentClass
) >= 0) {
163 * returns the component associated with that key
168 value: function getComponent(componentClass
) {
170 var position
= this._componentKeys
.indexOf(componentClass
);
172 return this._components
[position
];
180 module
.exports
= Entity
;
184 /***/ (function(module
, exports
, __webpack_require__
) {
190 * A node describes a set of components in order to describe entities
194 var _createClass = function () { function defineProperties(target
, props
) { for (var i
= 0; i
< props
.length
; i
++) { var descriptor
= props
[i
]; descriptor
.enumerable
= descriptor
.enumerable
|| false; descriptor
.configurable
= true; if ("value" in descriptor
) descriptor
.writable
= true; Object
.defineProperty(target
, descriptor
.key
, descriptor
); } } return function (Constructor
, protoProps
, staticProps
) { if (protoProps
) defineProperties(Constructor
.prototype, protoProps
); if (staticProps
) defineProperties(Constructor
, staticProps
); return Constructor
; }; }();
196 function _classCallCheck(instance
, Constructor
) { if (!(instance
instanceof Constructor
)) { throw new TypeError("Cannot call a class as a function"); } }
198 var Node = function () {
199 _createClass(Node
, null, [{
204 * Returns true if the given entity matches the defined protocol,
207 value: function matches(entity
) {
209 var typeNames
= Object
.keys(this.types
);
211 var _iteratorNormalCompletion
= true;
212 var _didIteratorError
= false;
213 var _iteratorError
= undefined;
216 for (var _iterator
= typeNames
[Symbol
.iterator
](), _step
; !(_iteratorNormalCompletion
= (_step
= _iterator
.next()).done
); _iteratorNormalCompletion
= true) {
217 var typeName
= _step
.value
;
220 var type
= this.types
[typeName
];
223 if (entity
.hasComponent(type
)) {
232 _didIteratorError
= true;
233 _iteratorError
= err
;
236 if (!_iteratorNormalCompletion
&& _iterator
.return) {
240 if (_didIteratorError
) {
241 throw _iteratorError
;
250 function Node(config
) {
251 _classCallCheck(this, Node
);
255 Object
.assign(this, config
);
261 module
.exports
= Node
;
265 /***/ (function(module
, exports
, __webpack_require__
) {
271 * Node Collections contain nodes, in order to keep the lists of nodes
272 * that belong to each type.
274 * It has a type which is the class name of the node, and an array of
275 * instances of that class.
278 var _createClass = function () { function defineProperties(target
, props
) { for (var i
= 0; i
< props
.length
; i
++) { var descriptor
= props
[i
]; descriptor
.enumerable
= descriptor
.enumerable
|| false; descriptor
.configurable
= true; if ("value" in descriptor
) descriptor
.writable
= true; Object
.defineProperty(target
, descriptor
.key
, descriptor
); } } return function (Constructor
, protoProps
, staticProps
) { if (protoProps
) defineProperties(Constructor
.prototype, protoProps
); if (staticProps
) defineProperties(Constructor
, staticProps
); return Constructor
; }; }();
280 function _classCallCheck(instance
, Constructor
) { if (!(instance
instanceof Constructor
)) { throw new TypeError("Cannot call a class as a function"); } }
282 var NodeCollection = function () {
283 function NodeCollection(config
) {
284 _classCallCheck(this, NodeCollection
);
289 Object
.assign(this, config
);
293 * Creates a node for an entity if it matches, and adds it to the
296 * Returns true if added, false otherwise.
300 _createClass(NodeCollection
, [{
302 value: function add(entity
) {
304 if (this.type
.matches(entity
) && !this._entityExists(entity
)) {
306 var node
= new this.type({});
307 var types
= this.type
.types
;
308 var typeNames
= Object
.keys(types
);
310 node
.entity
= entity
;
312 var _iteratorNormalCompletion
= true;
313 var _didIteratorError
= false;
314 var _iteratorError
= undefined;
317 for (var _iterator
= typeNames
[Symbol
.iterator
](), _step
; !(_iteratorNormalCompletion
= (_step
= _iterator
.next()).done
); _iteratorNormalCompletion
= true) {
318 var typeName
= _step
.value
;
320 node
[typeName
] = entity
.getComponent(types
[typeName
]);
323 _didIteratorError
= true;
324 _iteratorError
= err
;
327 if (!_iteratorNormalCompletion
&& _iterator
.return) {
331 if (_didIteratorError
) {
332 throw _iteratorError
;
337 this.nodes
.push(node
);
346 * Removes an entity by removing its related node from the list of nodes
348 * returns true if it was removed, false otherwise.
353 value: function remove(entity
) {
357 var found
= this.nodes
.some(function (node
, i
) {
359 if (node
.entity
=== entity
) {
366 this.nodes
.splice(foundIndex
, 1);
373 * Checks whether we already have nodes for this entity.
377 key: '_entityExists',
378 value: function _entityExists(entity
) {
382 var _iteratorNormalCompletion2
= true;
383 var _didIteratorError2
= false;
384 var _iteratorError2
= undefined;
387 for (var _iterator2
= this.nodes
[Symbol
.iterator
](), _step2
; !(_iteratorNormalCompletion2
= (_step2
= _iterator2
.next()).done
); _iteratorNormalCompletion2
= true) {
388 var node
= _step2
.value
;
390 if (node
.entity
=== entity
) {
395 _didIteratorError2
= true;
396 _iteratorError2
= err
;
399 if (!_iteratorNormalCompletion2
&& _iterator2
.return) {
403 if (_didIteratorError2
) {
404 throw _iteratorError2
;
413 return NodeCollection
;
416 module
.exports
= NodeCollection
;
420 /***/ (function(module
, exports
, __webpack_require__
) {
426 * Systems contain most of the logic, and work with nodes in order to
427 * act and change their values.
429 * You usually want to inherit from this class and override the
430 * three methods. They are shown here to document the interface.
433 var _createClass = function () { function defineProperties(target
, props
) { for (var i
= 0; i
< props
.length
; i
++) { var descriptor
= props
[i
]; descriptor
.enumerable
= descriptor
.enumerable
|| false; descriptor
.configurable
= true; if ("value" in descriptor
) descriptor
.writable
= true; Object
.defineProperty(target
, descriptor
.key
, descriptor
); } } return function (Constructor
, protoProps
, staticProps
) { if (protoProps
) defineProperties(Constructor
.prototype, protoProps
); if (staticProps
) defineProperties(Constructor
, staticProps
); return Constructor
; }; }();
435 function _classCallCheck(instance
, Constructor
) { if (!(instance
instanceof Constructor
)) { throw new TypeError("Cannot call a class as a function"); } }
437 var System = function () {
439 _classCallCheck(this, System
);
442 _createClass(System
, [{
447 * This will be run when the system is added to the engine
449 value: function added() {}
450 // Override with added(engine)
451 // Receives an instance of the serpentity engine
455 * This will be run when the system is removed from the engine
460 value: function removed() {}
461 // Override with removed(engine)
462 // Receives an instance of the serpentity engine
466 * This will run every time the engine's update method is called
471 value: function update() {
472 // Override with update(dt)
473 // Receives a delta of the time
480 module
.exports
= System
;
484 /***/ (function(module
, exports
, __webpack_require__
) {
490 Serpentity is a simple entity framework inspired by Ash.
494 const Serpentity = require('serpentity');
496 ## Instantiating an engine
498 const engine = new Serpentity();
500 Add entities or systems, systems are added with a priority (the smaller
501 the number, the earlier it will be called):
503 engine.addEntity(entityFactory());
504 engine.addSystem(new GameSystem(), priority);
510 Remove entities or systems:
512 engine.removeEntity(entityReference);
513 engine.removeSystem(systemReference);
517 Entities are the basic object of Serpentity, and they do nothing.
519 const entity = new Serpentity.Entity();
521 All the behavior is added through components
523 ## Creating Components
525 Components define data that we can add to an entity. This data will
526 eventually be consumed by "Systems"
528 const PositionComponent = class PositionComponent extends Serpentity.Component {
529 constructor(config) {
538 You can add components to entities by using the add method:
540 entity.addComponent(new PositionComponent());
543 Systems can refer to entities by requesting nodes.
545 ## Working with Nodes
547 Nodes are sets of components that you define, so your system can require
548 entities that always follow the API defined in the node.
550 const MovementNode = class MovementNode extends Serpentity.Node;
551 MovementNode.position = PositionComponent;
552 MovementNode.motion = MotionComponent;
554 You can then request an array of all the nodes representing entities
555 that comply with that API
557 engine.getNodes(MovementNode);
561 Systems are called on every update, and they use components through nodes.
563 const TestSystem = class TestSystem extends Serpentity.System {
566 this.nodeList = engine.getNodes(MovementNode);
571 this.nodeList = undefined;
576 for (const node of this.nodeList) {
577 console.log(`Current position is: ${node.position.x},${node.position.y}`);
584 Just run `engine.update(dt)` in your game loop :D
588 var _createClass = function () { function defineProperties(target
, props
) { for (var i
= 0; i
< props
.length
; i
++) { var descriptor
= props
[i
]; descriptor
.enumerable
= descriptor
.enumerable
|| false; descriptor
.configurable
= true; if ("value" in descriptor
) descriptor
.writable
= true; Object
.defineProperty(target
, descriptor
.key
, descriptor
); } } return function (Constructor
, protoProps
, staticProps
) { if (protoProps
) defineProperties(Constructor
.prototype, protoProps
); if (staticProps
) defineProperties(Constructor
, staticProps
); return Constructor
; }; }();
590 function _classCallCheck(instance
, Constructor
) { if (!(instance
instanceof Constructor
)) { throw new TypeError("Cannot call a class as a function"); } }
592 var Serpentity = function () {
593 function Serpentity(config
) {
594 _classCallCheck(this, Serpentity
);
598 this._nodeCollections
= [];
599 this._nodeCollectionKeys
= [];
601 Object
.assign(this, config
);
605 * Adds a system to the engine, so its update method will be called
606 * with the others. Triggers added hook.
608 * returns true if added succesfully, false if already added
612 _createClass(Serpentity
, [{
614 value: function addSystem(system
, priority
) {
616 if (this.systems
.indexOf(system
) >= 0) {
620 system
.priority
= priority
;
624 var found
= this.systems
.some(function (existingSystem
, i
) {
627 if (existingSystem
.priority
>= system
.priority
) {
636 this.systems
.splice(lastIndex
, 0, system
);
642 * Removes a system from the engine, so its update method will no
643 * longer will be called. Triggers the removed hook.
645 * returns true if removed succesfully, false if already added
650 value: function removeSystem(system
) {
652 var position
= this.systems
.indexOf(system
);
654 this.systems
[position
].removed(this);
655 this.systems
.splice(position
, 1);
663 * Adds an entity to the engine, adds to existing node collections
665 * returns true if added, false if already there
670 value: function addEntity(entity
) {
672 if (this.entities
.indexOf(entity
) >= 0) {
675 this.entities
.push(entity
);
677 var _iteratorNormalCompletion
= true;
678 var _didIteratorError
= false;
679 var _iteratorError
= undefined;
682 for (var _iterator
= this._nodeCollections
[Symbol
.iterator
](), _step
; !(_iteratorNormalCompletion
= (_step
= _iterator
.next()).done
); _iteratorNormalCompletion
= true) {
683 var collection
= _step
.value
;
685 collection
.add(entity
);
688 _didIteratorError
= true;
689 _iteratorError
= err
;
692 if (!_iteratorNormalCompletion
&& _iterator
.return) {
696 if (_didIteratorError
) {
697 throw _iteratorError
;
706 * Removes entity from system, removing from all node collections
708 * returns true if removed, false if not present
713 value: function removeEntity(entity
) {
715 var position
= this.entities
.indexOf(entity
);
717 var _iteratorNormalCompletion2
= true;
718 var _didIteratorError2
= false;
719 var _iteratorError2
= undefined;
722 for (var _iterator2
= this._nodeCollections
[Symbol
.iterator
](), _step2
; !(_iteratorNormalCompletion2
= (_step2
= _iterator2
.next()).done
); _iteratorNormalCompletion2
= true) {
723 var collection
= _step2
.value
;
725 collection
.remove(entity
);
728 _didIteratorError2
= true;
729 _iteratorError2
= err
;
732 if (!_iteratorNormalCompletion2
&& _iterator2
.return) {
736 if (_didIteratorError2
) {
737 throw _iteratorError2
;
742 this.entities
.splice(position
, 1);
750 * Given a Node Class, retrieves a list of all the nodes for each
756 value: function getNodes(nodeType
) {
758 var position
= this._nodeCollectionKeys
.indexOf(nodeType
);
761 return this._nodeCollections
[position
].nodes
;
764 var nodeCollection
= new Serpentity
.NodeCollection({
768 this._nodeCollectionKeys
.push(nodeType
);
769 this._nodeCollections
.push(nodeCollection
);
771 var _iteratorNormalCompletion3
= true;
772 var _didIteratorError3
= false;
773 var _iteratorError3
= undefined;
776 for (var _iterator3
= this.entities
[Symbol
.iterator
](), _step3
; !(_iteratorNormalCompletion3
= (_step3
= _iterator3
.next()).done
); _iteratorNormalCompletion3
= true) {
777 var entity
= _step3
.value
;
779 nodeCollection
.add(entity
);
782 _didIteratorError3
= true;
783 _iteratorError3
= err
;
786 if (!_iteratorNormalCompletion3
&& _iterator3
.return) {
790 if (_didIteratorError3
) {
791 throw _iteratorError3
;
796 return nodeCollection
.nodes
;
800 * Calls update for every loaded system.
805 value: function update(dt
) {
806 var _iteratorNormalCompletion4
= true;
807 var _didIteratorError4
= false;
808 var _iteratorError4
= undefined;
812 for (var _iterator4
= this.systems
[Symbol
.iterator
](), _step4
; !(_iteratorNormalCompletion4
= (_step4
= _iterator4
.next()).done
); _iteratorNormalCompletion4
= true) {
813 var system
= _step4
.value
;
818 _didIteratorError4
= true;
819 _iteratorError4
= err
;
822 if (!_iteratorNormalCompletion4
&& _iterator4
.return) {
826 if (_didIteratorError4
) {
827 throw _iteratorError4
;
837 // Add namespaced objects.
838 Serpentity
.Component
= __webpack_require__(0);
839 Serpentity
.Entity
= __webpack_require__(1);
840 Serpentity
.Node
= __webpack_require__(2);
841 Serpentity
.NodeCollection
= __webpack_require__(3);
842 Serpentity
.System
= __webpack_require__(4);
844 module
.exports
= Serpentity
;