]> git.r.bdr.sh - rbdr/sumo/blob - lib/systems/apply_force.js
Deploy to Pages
[rbdr/sumo] / lib / systems / apply_force.js
1 import { System } from '@serpentity/serpentity';
2 import { Body, Vector } from 'matter-js';
3
4 const internals = {
5 kForce: 0.0001
6 };
7
8 import PhysicalWithExternalForceNode from '../nodes/physical_with_external_force';
9
10 /**
11 * Applies physica from external forces (eg. controls) to the physics body
12 *
13 * @extends {external:Serpentity.System}
14 * @class ApplyForceSystem
15 * @param {object} config a configuration object to extend.
16 */
17 export default class ApplyForceSystem extends System {
18
19 constructor(config = {}) {
20
21 super();
22
23 /**
24 * The node collection of entities that have external force
25 *
26 * @property {external:Serpentity.NodeCollection} physicalEntities
27 * @instance
28 * @memberof ApplyForceSystem
29 */
30 this.physicalEntities = null;
31 }
32
33 /**
34 * Initializes system when added. Requests physics nodes
35 *
36 * @function added
37 * @memberof ApplyForceSystem
38 * @instance
39 * @param {external:Serpentity.Engine} engine the serpentity engine to
40 * which we are getting added
41 */
42 added(engine) {
43
44 this.physicalEntities = engine.getNodes(PhysicalWithExternalForceNode);
45 }
46
47 /**
48 * Clears system resources when removed.
49 *
50 * @function removed
51 * @instance
52 * @memberof ApplyForceSystem
53 */
54 removed() {
55
56 this.physicalEntities = null;
57 }
58
59 /**
60 * Runs on every update of the loop. Updates the body based on the force
61 * component
62 *
63 * @function update
64 * @instance
65 * @param {Number} currentFrameDuration the duration of the current
66 * frame
67 * @memberof ApplyForceSystem
68 */
69 update(currentFrameDuration) {
70
71 for (const physicalEntity of this.physicalEntities) {
72 const body = physicalEntity.body.body;
73 const force = physicalEntity.force;
74 const forceVector = Vector.create(force.x * internals.kForce, force.y * internals.kForce);
75
76
77 // Store the last angle and apply force on non-zero forces
78
79 if (force.x || force.y) {
80 force.lastAngle = Math.atan2(force.y, force.x);
81 Body.applyForce(body,
82 {
83 x: body.position.x,
84 y: body.position.y
85 },
86 forceVector
87 );
88 }
89
90 // Reset the force
91
92 force.x = 0;
93 force.y = 0;
94 }
95 }
96 };
97