]> git.r.bdr.sh - rbdr/sumo/blame - lib/systems/control_mapper.js
Add control via keyboard (#6)
[rbdr/sumo] / lib / systems / control_mapper.js
CommitLineData
7ade6f8d
RBR
1import { System } from '@serpentity/serpentity';
2
3import ControllableNode from '../nodes/controllable';
4
5/* global window */
6
7const internals = {
8 keyboardState: {
9 }
10};
11
12/**
13 * Updates control status based on the controller map
14 *
15 * @extends {external:Serpentity.System}
16 * @class ControlMapperSystem
17 * @param {object} config a configuration object to extend.
18 */
19export default class ControlMapperSystem extends System {
20
21 constructor(config = {}) {
22
23 super();
24
25 /**
26 * The node collection of controllable entities
27 *
28 * @property {external:Serpentity.NodeCollection} controllables
29 * @instance
30 * @memberof RenderSystem
31 */
32 this.controllables = null;
33
34 this._initializeKeyboard();
35 }
36
37 /**
38 * Initializes system when added. Requests controllable nodes.
39 *
40 * @function added
41 * @memberof RenderSystem
42 * @instance
43 * @param {external:Serpentity.Engine} engine the serpentity engine to
44 * which we are getting added
45 */
46 added(engine) {
47
48 this.controllables = engine.getNodes(ControllableNode);
49 }
50
51 /**
52 * Clears system resources when removed.
53 *
54 * @function removed
55 * @instance
56 * @memberof RenderSystem
57 */
58 removed() {
59
60 this.controllables = null;
61 }
62
63 /**
64 * Runs on every update of the loop. Maps the actions given the current state of the inputs
65 *
66 * @function update
67 * @instance
68 * @param {Number} currentFrameDuration the duration of the current
69 * frame
70 * @memberof RenderSystem
71 */
72 update(currentFrameDuration) {
73
74 for (const controllable of this.controllables) {
75 for (const map of controllable.controlMap.map) {
76 if (map.source.type === 'keyboard') {
77 this._setValue(controllable.entity, map.target, !!internals.keyboardState[map.source.index]);
78 }
79 }
80 }
81 }
82
83 // Listens to keyboard to update internal map
84
85 _initializeKeyboard() {
86
87 window.addEventListener('keydown', (event) => {
88
89 internals.keyboardState[event.keyCode] = true;
90 });
91
92 window.addEventListener('keyup', (event) => {
93
94 internals.keyboardState[event.keyCode] = false;
95 });
96 }
97
98 // Sets the value to a target
99
100 _setValue(entity, target, value) {
101
102 const component = entity.getComponent(target.component);
103
104 if (component) {
105 const keyFragments = target.property.split('.');
106 let currentObject = component;
107 for (const keyFragment of keyFragments.slice(0, keyFragments.length - 1)) {
108 currentObject = currentObject[keyFragment] = currentObject[keyFragment] || {};
109 }
110
111
112 const finalValue = !!target.value ? target.value(value) : value;
113 const finalProperty = keyFragments.pop();
114 currentObject[finalProperty] += finalValue;
115 }
116 }
117};
118