]> git.r.bdr.sh - rbdr/sumo/blob - lib/systems/physics_world_control.js
Merge branch 'feature/rbdr-gitlab-pipeline' into 'develop'
[rbdr/sumo] / lib / systems / physics_world_control.js
1 import { System } from '@serpentity/serpentity';
2 import { Engine, World } from 'matter-js';
3
4 import PhysicalNode from '../nodes/physical';
5 import GrabAreaNode from '../nodes/grab_area';
6
7 const internals = {
8 kNoEngine: 'No matter js physics engine found. Make sure you set the `engine` key in the config object when initializing.'
9 };
10
11 /**
12 * Adds and removes objects to the physics world and calls update
13 *
14 * @extends {external:Serpentity.System}
15 * @class PhysicsWorldControlSystem
16 * @param {object} config a configuration object to extend.
17 */
18 export default class PhysicsWorldControlSystem extends System {
19
20 constructor(config = {}) {
21
22 super();
23
24 /**
25 * The node collection of physics entities
26 *
27 * @property {external:Serpentity.NodeCollection} physicalEntities
28 * @instance
29 * @memberof PhysicsWorldControlSystem
30 */
31 this.physicalEntities = null;
32
33 /**
34 * The matter-js engine we will use to process physics
35 *
36 * @property {external:MatterJs.Engine} engine
37 * @instance
38 * @memberof PhysicsWorldControlSystem
39 */
40 this.engine = config.engine;
41
42 if (!this.engine) {
43 throw new Error(internals.kNoEngine);
44 }
45 }
46
47 /**
48 * Initializes system when added. Requests physics nodes and
49 * attaches to event listeners to add / remove them to pixi stage
50 *
51 * @function added
52 * @memberof PhysicsWorldControlSystem
53 * @instance
54 * @param {external:Serpentity.Engine} engine the serpentity engine to
55 * which we are getting added
56 */
57 added(engine) {
58
59 this.physicalEntities = engine.getNodes(PhysicalNode);
60 this.grabAreaEntities = engine.getNodes(GrabAreaNode);
61
62 this.physicalEntities.on('nodeAdded', (event) => {
63
64 World.add(this.engine.world, [event.node.body.body]);
65 });
66 this.physicalEntities.on('nodeRemoved', (event) => {
67
68 World.remove(this.engine.world, [event.node.body.body]);
69 });
70
71 this.grabAreaEntities.on('nodeAdded', (event) => {
72
73 World.add(this.engine.world, [event.node.grabArea.area]);
74 });
75 this.grabAreaEntities.on('nodeRemoved', (event) => {
76
77 World.remove(this.engine.world, [event.node.grabArea.area]);
78 });
79 }
80
81 /**
82 * Clears system resources when removed.
83 *
84 * @function removed
85 * @instance
86 * @memberof PhysicsWorldControlSystem
87 */
88 removed() {
89
90 this.physicalEntities.removeAllListeners('nodeAdded');
91 this.physicalEntities.removeAllListeners('nodeRemoved');
92 this.physicalEntities = null;
93
94 this.grabAreaEntities.removeAllListeners('nodeAdded');
95 this.grabAreaEntities.removeAllListeners('nodeRemoved');
96 this.grabAreaEntities = null;
97 }
98
99 /**
100 * Runs on every update of the loop. Updates the physics
101 *
102 * @function update
103 * @instance
104 * @param {Number} currentFrameDuration the duration of the current
105 * frame
106 * @memberof PhysicsWorldControlSystem
107 */
108 update(currentFrameDuration) {
109
110 Engine.update(this.engine, currentFrameDuration);
111 }
112 };
113