]>
Commit | Line | Data |
---|---|---|
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 |