2021-05-12 09:13:25 +02:00
|
|
|
import type { Direction } from "../../types";
|
|
|
|
import type {GameScene} from "../Game/GameScene";
|
2021-04-16 18:49:04 +02:00
|
|
|
import {touchScreenManager} from "../../Touch/TouchScreenManager";
|
2021-04-20 11:40:39 +02:00
|
|
|
import {MobileJoystick} from "../Components/MobileJoystick";
|
2020-04-11 16:46:28 +02:00
|
|
|
|
|
|
|
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,
|
2020-04-12 19:35:51 +02:00
|
|
|
Shout,
|
2021-01-23 02:21:16 +01:00
|
|
|
JoystickMove,
|
2020-04-11 16:46:28 +02:00
|
|
|
}
|
|
|
|
|
2021-04-20 10:52:06 +02:00
|
|
|
|
2021-01-23 02:21:16 +01:00
|
|
|
//we cannot use a map structure so we have to create a replacment
|
2020-04-11 16:46:28 +02:00
|
|
|
export class ActiveEventList {
|
2021-01-23 02:21:16 +01:00
|
|
|
private eventMap : Map<UserInputEvent, boolean> = new Map<UserInputEvent, boolean>();
|
2020-06-10 12:15:25 +02:00
|
|
|
|
2020-04-11 16:46:28 +02:00
|
|
|
get(event: UserInputEvent): boolean {
|
2021-01-23 02:21:16 +01:00
|
|
|
return this.eventMap.get(event) || false;
|
2020-04-11 16:46:28 +02:00
|
|
|
}
|
2020-06-10 12:15:25 +02:00
|
|
|
set(event: UserInputEvent, value: boolean): void {
|
2021-01-23 02:21:16 +01:00
|
|
|
this.eventMap.set(event, value);
|
2020-04-11 16:46:28 +02:00
|
|
|
}
|
2021-02-03 23:28:46 +01:00
|
|
|
forEach(callback: (value: boolean, key: UserInputEvent) => void): void {
|
2021-01-23 02:21:16 +01:00
|
|
|
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
|
|
|
}
|
2020-05-19 19:11:12 +02:00
|
|
|
}
|
2020-04-11 16:46:28 +02: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;
|
2021-03-28 16:36:02 +02:00
|
|
|
private isInputDisabled : boolean;
|
2021-01-23 02:21:16 +01:00
|
|
|
|
2021-04-20 11:40:39 +02:00
|
|
|
private joystick!: MobileJoystick;
|
2021-02-03 23:28:46 +01:00
|
|
|
private joystickEvents = new ActiveEventList();
|
2021-01-23 02:21:16 +01:00
|
|
|
private joystickForceThreshold = 60;
|
|
|
|
private joystickForceAccuX = 0;
|
|
|
|
private joystickForceAccuY = 0;
|
2021-02-03 23:28:46 +01:00
|
|
|
|
2021-04-16 18:49:04 +02: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();
|
2021-05-05 09:35:24 +02:00
|
|
|
this.initMouseWheel();
|
2021-04-16 18:49:04 +02:00
|
|
|
if (touchScreenManager.supportTouchScreen) {
|
|
|
|
this.initVirtualJoystick();
|
|
|
|
}
|
|
|
|
}
|
2021-05-04 11:29:37 +02:00
|
|
|
|
2021-04-16 18:49:04 +02:00
|
|
|
initVirtualJoystick() {
|
2021-04-20 11:40:39 +02:00
|
|
|
this.joystick = new MobileJoystick(this.Scene);
|
2021-01-23 02:21:16 +01:00
|
|
|
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) {
|
2021-04-16 18:49:04 +02:00
|
|
|
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
|
|
|
}
|
2020-05-19 19:11:12 +02:00
|
|
|
|
2020-09-21 00:34:25 +02:00
|
|
|
initKeyBoardEvent(){
|
2020-06-04 18:11:07 +02:00
|
|
|
this.KeysCode = [
|
2020-09-23 17:22:00 +02:00
|
|
|
{event: UserInputEvent.MoveUp, keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Z, false) },
|
2020-11-09 12:24:45 +01:00
|
|
|
{event: UserInputEvent.MoveUp, keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.W, false) },
|
2020-09-23 17:22:00 +02:00
|
|
|
{event: UserInputEvent.MoveLeft, keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Q, false) },
|
2020-11-09 12:24:45 +01:00
|
|
|
{event: UserInputEvent.MoveLeft, keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.A, false) },
|
2020-09-23 17:22:00 +02:00
|
|
|
{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) },
|
2020-05-19 19:11:12 +02:00
|
|
|
|
2020-09-23 17:22:00 +02:00
|
|
|
{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) },
|
2020-05-19 19:11:12 +02:00
|
|
|
|
2020-09-23 17:22:00 +02:00
|
|
|
{event: UserInputEvent.SpeedUp, keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.SHIFT, false) },
|
2020-06-04 18:11:07 +02:00
|
|
|
|
2020-09-23 17:22:00 +02:00
|
|
|
{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.Shout, keyInstance: this.Scene.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.F, false) },
|
2020-06-04 18:11:07 +02:00
|
|
|
];
|
2020-04-11 16:46:28 +02:00
|
|
|
}
|
|
|
|
|
2021-02-11 21:48:24 +01:00
|
|
|
clearAllListeners(){
|
2021-01-28 19:15:34 +01:00
|
|
|
this.Scene.input.keyboard.removeAllListeners();
|
2020-09-21 00:34:25 +02:00
|
|
|
}
|
|
|
|
|
2021-04-20 10:52:06 +02:00
|
|
|
//todo: should we also disable the joystick?
|
2021-03-22 16:10:21 +01:00
|
|
|
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
|
|
|
}
|
|
|
|
|
2021-03-22 16:10:21 +01:00
|
|
|
restoreControls(){
|
2021-03-12 16:39:29 +01:00
|
|
|
this.initKeyBoardEvent();
|
2021-03-28 16:36:02 +02:00
|
|
|
this.isInputDisabled = false;
|
2021-03-12 16:39:29 +01:00
|
|
|
}
|
2020-04-11 16:46:28 +02:00
|
|
|
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) {
|
2021-01-23 02:21:16 +01:00
|
|
|
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
|
|
|
}
|
|
|
|
});
|
2021-01-23 02:21:16 +01:00
|
|
|
eventsMap.set(UserInputEvent.JoystickMove, this.joystickEvents.any());
|
2020-04-13 13:42:21 +02:00
|
|
|
this.KeysCode.forEach(d => {
|
2021-01-23 02:21:16 +01:00
|
|
|
if (d.keyInstance.isDown) {
|
2020-04-11 16:46:28 +02:00
|
|
|
eventsMap.set(d.event, true);
|
|
|
|
}
|
|
|
|
});
|
|
|
|
return eventsMap;
|
|
|
|
}
|
2020-09-23 17:22:00 +02:00
|
|
|
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
removeSpaceEventListner(callback : Function){
|
|
|
|
this.Scene.input.keyboard.removeListener('keyup-SPACE', callback);
|
|
|
|
}
|
2021-05-04 11:29:37 +02:00
|
|
|
|
|
|
|
destroy(): void {
|
2021-05-17 13:50:31 +02:00
|
|
|
this.joystick?.destroy();
|
2021-05-04 11:29:37 +02:00
|
|
|
}
|
2021-05-05 09:35:24 +02:00
|
|
|
|
|
|
|
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);
|
|
|
|
});
|
|
|
|
}
|
2020-05-19 19:11:12 +02:00
|
|
|
}
|