workadventure/front/src/Phaser/UserInput/UserInputManager.ts

239 lines
8.5 KiB
TypeScript
Raw Normal View History

import type { GameScene } from "../Game/GameScene";
import { touchScreenManager } from "../../Touch/TouchScreenManager";
import { MobileJoystick } from "../Components/MobileJoystick";
import { enableUserInputsStore } from "../../Stores/UserInputStore";
2021-12-16 10:04:55 +01:00
import type { Direction } from "phaser3-rex-plugins/plugins/virtualjoystick.js";
interface UserInputManagerDatum {
keyInstance: Phaser.Input.Keyboard.Key;
event: UserInputEvent;
}
export enum UserInputEvent {
MoveLeft = 1,
MoveUp,
MoveRight,
MoveDown,
SpeedUp,
2020-04-11 18:17:36 +02:00
Interact,
Follow,
2020-04-12 19:35:51 +02:00
Shout,
JoystickMove,
}
//we cannot use a map structure so we have to create a replacement
export class ActiveEventList {
private eventMap: Map<UserInputEvent, boolean> = new Map<UserInputEvent, boolean>();
2020-06-10 12:15:25 +02:00
get(event: UserInputEvent): boolean {
return this.eventMap.get(event) || false;
}
2020-06-10 12:15:25 +02:00
set(event: UserInputEvent, value: boolean): void {
this.eventMap.set(event, value);
}
2021-02-03 23:28:46 +01:00
forEach(callback: (value: boolean, key: UserInputEvent) => void): void {
this.eventMap.forEach(callback);
}
any(): boolean {
return Array.from(this.eventMap.values()).reduce((accu, curr) => accu || curr, false);
2021-02-03 23:28:46 +01:00
}
}
//this class is responsible for catching user inputs and listing all active user actions at every game tick events.
export class UserInputManager {
2020-09-21 00:34:25 +02:00
private KeysCode!: UserInputManagerDatum[];
private Scene: GameScene;
private isInputDisabled: boolean;
2021-04-20 11:40:39 +02:00
private joystick!: MobileJoystick;
2021-02-03 23:28:46 +01:00
private joystickEvents = new ActiveEventList();
private joystickForceThreshold = 60;
private joystickForceAccuX = 0;
private joystickForceAccuY = 0;
2021-02-03 23:28:46 +01:00
constructor(Scene: GameScene) {
2020-09-21 00:34:25 +02:00
this.Scene = Scene;
2021-03-28 16:36:02 +02:00
this.isInputDisabled = false;
2021-02-03 23:28:46 +01:00
this.initKeyBoardEvent();
this.initMouseWheel();
if (touchScreenManager.supportTouchScreen) {
this.initVirtualJoystick();
}
enableUserInputsStore.subscribe((enable) => {
enable ? this.restoreControls() : this.disableControls();
});
}
initVirtualJoystick() {
2021-04-20 11:40:39 +02:00
this.joystick = new MobileJoystick(this.Scene);
this.joystick.on("update", () => {
this.joystickForceAccuX = this.joystick.forceX ? this.joystickForceAccuX : 0;
this.joystickForceAccuY = this.joystick.forceY ? this.joystickForceAccuY : 0;
const cursorKeys = this.joystick.createCursorKeys();
2021-02-03 23:28:46 +01:00
for (const name in cursorKeys) {
const key = cursorKeys[name as Direction];
switch (name) {
case "up":
this.joystickEvents.set(UserInputEvent.MoveUp, key.isDown);
break;
case "left":
this.joystickEvents.set(UserInputEvent.MoveLeft, key.isDown);
break;
case "down":
this.joystickEvents.set(UserInputEvent.MoveDown, key.isDown);
break;
case "right":
this.joystickEvents.set(UserInputEvent.MoveRight, key.isDown);
break;
2021-02-03 23:28:46 +01:00
}
}
});
2020-09-21 00:34:25 +02:00
}
initKeyBoardEvent() {
2020-06-04 18:11:07 +02:00
this.KeysCode = [
{
event: UserInputEvent.MoveUp,
keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Z, false),
},
{
event: UserInputEvent.MoveUp,
keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.W, false),
},
{
event: UserInputEvent.MoveLeft,
keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Q, false),
},
{
event: UserInputEvent.MoveLeft,
keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A, false),
},
{
event: UserInputEvent.MoveDown,
keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.S, false),
},
{
event: UserInputEvent.MoveRight,
keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.D, false),
},
{
event: UserInputEvent.MoveUp,
keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.UP, false),
},
{
event: UserInputEvent.MoveLeft,
keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.LEFT, false),
},
{
event: UserInputEvent.MoveDown,
keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.DOWN, false),
},
{
event: UserInputEvent.MoveRight,
keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.RIGHT, false),
},
{
event: UserInputEvent.SpeedUp,
keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SHIFT, false),
},
{
event: UserInputEvent.Interact,
keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.E, false),
},
{
event: UserInputEvent.Interact,
keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SPACE, false),
},
{
event: UserInputEvent.Follow,
keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.F, false),
},
{
event: UserInputEvent.Shout,
keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.F, false),
},
2020-06-04 18:11:07 +02:00
];
}
clearAllListeners() {
2021-01-28 19:15:34 +01:00
this.Scene.input.keyboard.removeAllListeners();
2020-09-21 00:34:25 +02:00
}
//todo: should we also disable the joystick?
disableControls() {
2021-02-11 21:48:24 +01:00
this.Scene.input.keyboard.removeAllKeys();
2021-03-28 16:36:02 +02:00
this.isInputDisabled = true;
2021-02-11 21:48:24 +01:00
}
restoreControls() {
this.initKeyBoardEvent();
2021-03-28 16:36:02 +02:00
this.isInputDisabled = false;
}
getEventListForGameTick(): ActiveEventList {
2020-06-09 23:13:26 +02:00
const eventsMap = new ActiveEventList();
2021-03-28 16:36:02 +02:00
if (this.isInputDisabled) {
return eventsMap;
}
2021-02-03 23:28:46 +01:00
this.joystickEvents.forEach((value, key) => {
if (value) {
switch (key) {
case UserInputEvent.MoveUp:
case UserInputEvent.MoveDown:
this.joystickForceAccuY += this.joystick.forceY;
if (Math.abs(this.joystickForceAccuY) > this.joystickForceThreshold) {
eventsMap.set(key, value);
this.joystickForceAccuY = 0;
}
break;
case UserInputEvent.MoveLeft:
case UserInputEvent.MoveRight:
this.joystickForceAccuX += this.joystick.forceX;
if (Math.abs(this.joystickForceAccuX) > this.joystickForceThreshold) {
eventsMap.set(key, value);
this.joystickForceAccuX = 0;
}
break;
}
2021-02-03 23:28:46 +01:00
}
});
eventsMap.set(UserInputEvent.JoystickMove, this.joystickEvents.any());
this.KeysCode.forEach((d) => {
if (d.keyInstance.isDown) {
eventsMap.set(d.event, true);
}
});
return eventsMap;
}
spaceEvent(callback: Function) {
this.Scene.input.keyboard.on("keyup-SPACE", (event: Event) => {
callback();
return event;
});
}
2020-10-31 14:04:55 +01:00
addSpaceEventListner(callback: Function) {
this.Scene.input.keyboard.addListener("keyup-SPACE", callback);
2020-10-31 14:04:55 +01:00
}
removeSpaceEventListner(callback: Function) {
this.Scene.input.keyboard.removeListener("keyup-SPACE", callback);
2020-10-31 14:04:55 +01:00
}
destroy(): void {
this.joystick?.destroy();
}
private initMouseWheel() {
this.Scene.input.on(
"wheel",
(pointer: unknown, gameObjects: unknown, deltaX: number, deltaY: number, deltaZ: number) => {
this.Scene.zoomByFactor(1 - (deltaY / 53) * 0.1);
}
);
}
}