Something something games
This commit is contained in:
87
src/games/lib/control/Control.ts
Normal file
87
src/games/lib/control/Control.ts
Normal file
@@ -0,0 +1,87 @@
|
||||
type state = 'down' | 'up';
|
||||
|
||||
// - TODO - Pull this from the actual game creating the controls
|
||||
const GameControls = {
|
||||
down: 'down',
|
||||
up: 'up',
|
||||
left: 'left',
|
||||
right: 'right',
|
||||
shift: 'shift',
|
||||
' ': ' ',
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Abstraction for game controls, the game should say what controls it expects and then we can remap the actual controls separately.
|
||||
* i.e. Both "ArrowDown" and "Down" from the keyboard listener should be the games "down" event.
|
||||
* Also handles when the keys are pressed or not.
|
||||
*/
|
||||
class Control {
|
||||
readonly gameControls = GameControls;
|
||||
private _controlMap: { [key: string]: keyof typeof GameControls } = {
|
||||
ArrowDown: GameControls.down,
|
||||
Down: GameControls.down,
|
||||
ArrowUp: GameControls.up,
|
||||
Up: GameControls.up,
|
||||
ArrowLeft: GameControls.left,
|
||||
Left: GameControls.left,
|
||||
ArrowRight: GameControls.right,
|
||||
Right: GameControls.right,
|
||||
Shift: GameControls.shift,
|
||||
' ': GameControls[' '],
|
||||
};
|
||||
|
||||
private _controlState: Map<keyof typeof GameControls, {
|
||||
state: state,
|
||||
|
||||
consumed: boolean
|
||||
}> = new Map();
|
||||
|
||||
constructor() {
|
||||
this._setKeys();
|
||||
window.addEventListener('keydown', (event) => {
|
||||
if (this._controlState.get(this._controlMap[event.key])?.state !== 'down') {
|
||||
this._controlState.set(this._controlMap[event.key], { state: 'down', consumed: false });
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener('keyup', (event) => {
|
||||
if (this._controlState.get(this._controlMap[event.key])?.state !== 'up') {
|
||||
this._controlState.set(this._controlMap[event.key], { state: 'up', consumed: false });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* - TODO
|
||||
*/
|
||||
private _setKeys(): void {
|
||||
Object.keys(GameControls).forEach((key) => {
|
||||
this._controlState.set(key as keyof typeof GameControls, { state: 'up', consumed: false });
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* - TODO
|
||||
*
|
||||
* @param key - TODO
|
||||
*/
|
||||
isDown(key: keyof typeof GameControls): boolean {
|
||||
return this._controlState.get(key)?.state === 'down';
|
||||
}
|
||||
|
||||
/**
|
||||
* Consume a down key event once
|
||||
*
|
||||
* @param key - TODO
|
||||
*/
|
||||
onceDown(key: keyof typeof GameControls): boolean {
|
||||
const keyState = this._controlState.get(key);
|
||||
if (keyState && keyState.state === 'down' && !keyState.consumed) {
|
||||
keyState.consumed = true;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export default Control;
|
||||
Reference in New Issue
Block a user