]>
git.r.bdr.sh - rbdr/sumo/blob - lib/systems/control_mapper.js
1 import { System
} from '@serpentity/serpentity';
3 import ControllableNode
from '../nodes/controllable';
5 /* global navigator window */
15 * Updates control status based on the controller map
17 * @extends {external:Serpentity.System}
18 * @class ControlMapperSystem
19 * @param {object} config a configuration object to extend.
21 export default class ControlMapperSystem
extends System
{
23 constructor(config
= {}) {
28 * The node collection of controllable entities
30 * @property {external:Serpentity.NodeCollection} controllables
32 * @memberof RenderSystem
34 this.controllables
= null;
36 this._initializeKeyboard();
37 this._initializeGamepad();
41 * Initializes system when added. Requests controllable nodes.
44 * @memberof RenderSystem
46 * @param {external:Serpentity.Engine} engine the serpentity engine to
47 * which we are getting added
51 this.controllables
= engine
.getNodes(ControllableNode
);
55 * Clears system resources when removed.
59 * @memberof RenderSystem
63 this.controllables
= null;
67 * Runs on every update of the loop. Maps the actions given the current state of the inputs
71 * @param {Number} currentFrameDuration the duration of the current
73 * @memberof RenderSystem
75 update(currentFrameDuration
) {
77 this._updateGamepads();
79 for (const controllable
of this.controllables
) {
80 for (const map
of controllable
.controlMap
.map
) {
81 if (map
.source
.type
=== 'keyboard') {
82 this._setValue(controllable
.entity
, map
.target
, !!internals
.keyboardState
[map
.source
.index
]);
85 if (map
.source
.type
=== 'gamepad') {
86 const gamepad
= internals
.gamepadState
[map
.source
.gamepadNumber
];
88 const source
= gamepad
[map
.source
.gamepadInputSource
];
89 source
&& this._setValue(controllable
.entity
, map
.target
, source
[map
.source
.index
]);
96 // Listens to keyboard to update internal map
98 _initializeKeyboard() {
100 window
.addEventListener('keydown', (event
) => {
102 internals
.keyboardState
[event
.keyCode
] = true;
105 window
.addEventListener('keyup', (event
) => {
107 internals
.keyboardState
[event
.keyCode
] = false;
111 // Requests gamepad access and binds to the events
113 _initializeGamepad() {
115 window
.addEventListener('gamepadconnected', (event
) => {
117 internals
.gamepadState
[event
.gamepad
.index
] = event
.gamepad
;
118 window
.gamepad
= event
.gamepad
;
121 window
.addEventListener('gamepaddisconnected', (event
) => {
123 delete internals
.gamepadState
[event
.gamepad
.index
];
131 const gamepads
= navigator
.getGamepads();
132 for (const index
of Object
.keys(internals
.gamepadState
)) {
133 internals
.gamepadState
[index
] = gamepads
[index
];
137 // Sets the value to a target
139 _setValue(entity
, target
, value
) {
141 const component
= entity
.getComponent(target
.component
);
144 const keyFragments
= target
.property
.split('.');
145 let currentObject
= component
;
146 for (const keyFragment
of keyFragments
.slice(0, keyFragments
.length
- 1)) {
147 currentObject
= currentObject
[keyFragment
] = currentObject
[keyFragment
] || {};
151 const finalValue
= !!target
.value
? target
.value(value
) : value
;
152 const finalProperty
= keyFragments
.pop();
153 currentObject
[finalProperty
] += finalValue
;