]>
git.r.bdr.sh - rbdr/sumo/blob - lib/systems/control_mapper.js
1 import { System
} from '@serpentity/serpentity';
3 import ControllableNode
from '../nodes/controllable';
13 * Updates control status based on the controller map
15 * @extends {external:Serpentity.System}
16 * @class ControlMapperSystem
17 * @param {object} config a configuration object to extend.
19 export default class ControlMapperSystem
extends System
{
21 constructor(config
= {}) {
26 * The node collection of controllable entities
28 * @property {external:Serpentity.NodeCollection} controllables
30 * @memberof RenderSystem
32 this.controllables
= null;
34 this._initializeKeyboard();
35 this._initializeGamepad();
39 * Initializes system when added. Requests controllable nodes.
42 * @memberof RenderSystem
44 * @param {external:Serpentity.Engine} engine the serpentity engine to
45 * which we are getting added
49 this.controllables
= engine
.getNodes(ControllableNode
);
53 * Clears system resources when removed.
57 * @memberof RenderSystem
61 this.controllables
= null;
65 * Runs on every update of the loop. Maps the actions given the current state of the inputs
69 * @param {Number} currentFrameDuration the duration of the current
71 * @memberof RenderSystem
73 update(currentFrameDuration
) {
75 this._updateGamepads();
77 for (const controllable
of this.controllables
) {
78 for (const map
of controllable
.controlMap
.map
) {
79 if (map
.source
.type
=== 'keyboard') {
80 this._setValue(controllable
.entity
, map
.target
, !!internals
.keyboardState
[map
.source
.index
]);
83 if (map
.source
.type
=== 'gamepad') {
84 const gamepad
= internals
.gamepadState
[map
.source
.gamepadNumber
];
86 const source
= gamepad
[map
.source
.gamepadInputSource
];
87 source
&& this._setValue(controllable
.entity
, map
.target
, source
[map
.source
.index
]);
94 // Listens to keyboard to update internal map
96 _initializeKeyboard() {
98 window
.addEventListener('keydown', (event
) => {
100 internals
.keyboardState
[event
.keyCode
] = true;
103 window
.addEventListener('keyup', (event
) => {
105 internals
.keyboardState
[event
.keyCode
] = false;
109 // Requests gamepad access and binds to the events
111 _initializeGamepad() {
113 window
.addEventListener('gamepadconnected', (event
) => {
115 internals
.gamepadState
[event
.gamepad
.index
] = event
.gamepad
;
116 window
.gamepad
= event
.gamepad
;
119 window
.addEventListener('gamepaddisconnected', (event
) => {
121 delete internals
.gamepadState
[event
.gamepad
.index
];
129 const gamepads
= navigator
.getGamepads();
130 for (const index
of Object
.keys(internals
.gamepadState
)) {
131 internals
.gamepadState
[index
] = gamepads
[index
];
135 // Sets the value to a target
137 _setValue(entity
, target
, value
) {
139 const component
= entity
.getComponent(target
.component
);
142 const keyFragments
= target
.property
.split('.');
143 let currentObject
= component
;
144 for (const keyFragment
of keyFragments
.slice(0, keyFragments
.length
- 1)) {
145 currentObject
= currentObject
[keyFragment
] = currentObject
[keyFragment
] || {};
149 const finalValue
= !!target
.value
? target
.value(value
) : value
;
150 const finalProperty
= keyFragments
.pop();
151 currentObject
[finalProperty
] += finalValue
;