]>
Commit | Line | Data |
---|---|---|
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.addEventListener('nodeAdded', (event) => { | |
63 | ||
64 | World.add(this.engine.world, [event.node.body.body]); | |
65 | }); | |
66 | this.physicalEntities.addEventListener('nodeRemoved', (event) => { | |
67 | ||
68 | World.remove(this.engine.world, [event.node.body.body]); | |
69 | }); | |
70 | ||
71 | this.grabAreaEntities.addEventListener('nodeAdded', (event) => { | |
72 | ||
73 | World.add(this.engine.world, [event.node.grabArea.area]); | |
74 | }); | |
75 | this.grabAreaEntities.addEventListener('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 |