first iteration of KeyboardBindingUiHandler
parent
c963970adf
commit
c6d3f93b3f
|
@ -5,6 +5,7 @@ const cfg_keyboard_azerty = {
|
||||||
padID: 'keyboard',
|
padID: 'keyboard',
|
||||||
padType: 'azerty',
|
padType: 'azerty',
|
||||||
gamepadMapping: {
|
gamepadMapping: {
|
||||||
|
NEED TO ADD KEYCODE FROM EVENT HERE
|
||||||
KEY_A: 0,
|
KEY_A: 0,
|
||||||
KEY_B: 0,
|
KEY_B: 0,
|
||||||
KEY_C: 0,
|
KEY_C: 0,
|
||||||
|
|
|
@ -10,6 +10,12 @@ export function getKeyFromInputIndex(config: GamepadConfig, index: number): Stri
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
export function getKeyFromKeyboardKey(config: GamepadConfig, key): String | null {
|
||||||
|
for (const _key of Object.keys(config.gamepadMapping)) {
|
||||||
|
if (config.gamepadMapping[_key] === key) return _key;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
// Given a setting name, return the key assigned to it from the config file
|
// Given a setting name, return the key assigned to it from the config file
|
||||||
export function getKeyForSettingName(config: GamepadConfig, settingName: string): String | null {
|
export function getKeyForSettingName(config: GamepadConfig, settingName: string): String | null {
|
||||||
|
@ -41,6 +47,11 @@ export function getCurrenlyAssignedIconFromInputIndex(config: GamepadConfig, ind
|
||||||
return config.icons[key];
|
return config.icons[key];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getCurrenlyAssignedIconFromKeyboardKey(config: GamepadConfig, key): String {
|
||||||
|
const _key = getKeyFromKeyboardKey(config, key);
|
||||||
|
return config.icons[_key];
|
||||||
|
}
|
||||||
|
|
||||||
// Given a setting name, return the icon currently assigned to this setting name
|
// Given a setting name, return the icon currently assigned to this setting name
|
||||||
export function getCurrentlyAssignedIconToSettingName(config: GamepadConfig, settingName: string): string {
|
export function getCurrentlyAssignedIconToSettingName(config: GamepadConfig, settingName: string): string {
|
||||||
const key = getCurrentlyAssignedToSettingName(config, settingName);
|
const key = getCurrentlyAssignedToSettingName(config, settingName);
|
||||||
|
|
|
@ -10,7 +10,7 @@ import SettingsGamepadUiHandler from "./ui/settings/settings-gamepad-ui-handler"
|
||||||
import {SettingGamepad} from "./system/settings-gamepad";
|
import {SettingGamepad} from "./system/settings-gamepad";
|
||||||
import {
|
import {
|
||||||
getCurrenlyAssignedIconFromInputIndex, getCurrentlyAssignedIconToSettingName,
|
getCurrenlyAssignedIconFromInputIndex, getCurrentlyAssignedIconToSettingName,
|
||||||
getKeyFromInputIndex, getCurrentlyAssignedToSettingName
|
getKeyFromInputIndex, getCurrentlyAssignedToSettingName, getCurrenlyAssignedIconFromKeyboardKey
|
||||||
} from "./configs/gamepad-utils";
|
} from "./configs/gamepad-utils";
|
||||||
import SettingsKeyboardUiHandler from "#app/ui/settings/settings-keyboard-ui-handler";
|
import SettingsKeyboardUiHandler from "#app/ui/settings/settings-keyboard-ui-handler";
|
||||||
import cfg_keyboard_azerty from "#app/configs/cfg_keyboard_azerty";
|
import cfg_keyboard_azerty from "#app/configs/cfg_keyboard_azerty";
|
||||||
|
@ -724,6 +724,10 @@ export class InputsController {
|
||||||
return [this.configs[this.chosenGamepad].padType, getCurrenlyAssignedIconFromInputIndex(this.configs[this.chosenGamepad], button.index)];
|
return [this.configs[this.chosenGamepad].padType, getCurrenlyAssignedIconFromInputIndex(this.configs[this.chosenGamepad], button.index)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getPressedKeyLabel(key): string {
|
||||||
|
return getCurrenlyAssignedIconFromKeyboardKey(this.configs[this.chosenKeyboard], key);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the currently assigned icon for a specific setting on the chosen gamepad.
|
* Retrieves the currently assigned icon for a specific setting on the chosen gamepad.
|
||||||
*
|
*
|
||||||
|
@ -734,6 +738,10 @@ export class InputsController {
|
||||||
return getCurrentlyAssignedIconToSettingName(this.configs[this.chosenGamepad], target);
|
return getCurrentlyAssignedIconToSettingName(this.configs[this.chosenGamepad], target);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getKeyboardCurrentlyAssignedIconToDisplay(target: SettingGamepad): string {
|
||||||
|
return getCurrentlyAssignedIconToSettingName(this.configs[this.chosenKeyboard], target);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Swaps the binding of two controls on the chosen gamepad configuration.
|
* Swaps the binding of two controls on the chosen gamepad configuration.
|
||||||
* It temporarily pauses updates, swaps the key bindings, saves the new configuration,
|
* It temporarily pauses updates, swaps the key bindings, saves the new configuration,
|
||||||
|
@ -754,6 +762,10 @@ export class InputsController {
|
||||||
setTimeout(() => this.pauseUpdate = false, 500);
|
setTimeout(() => this.pauseUpdate = false, 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
swapKeyboardBinding(settingName, pressedButton): void {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Injects a custom mapping configuration into the gamepad configuration for a specific gamepad.
|
* Injects a custom mapping configuration into the gamepad configuration for a specific gamepad.
|
||||||
* If the gamepad does not have an existing configuration, it initializes one first.
|
* If the gamepad does not have an existing configuration, it initializes one first.
|
||||||
|
|
|
@ -2,88 +2,207 @@ import UiHandler from "../ui-handler";
|
||||||
import BattleScene from "../../battle-scene";
|
import BattleScene from "../../battle-scene";
|
||||||
import {Mode} from "../ui";
|
import {Mode} from "../ui";
|
||||||
import {Button} from "../../enums/buttons";
|
import {Button} from "../../enums/buttons";
|
||||||
|
import Phaser from "phaser";
|
||||||
|
import {addWindow} from "#app/ui/ui-theme";
|
||||||
|
import {addTextObject, TextStyle} from "#app/ui/text";
|
||||||
|
import {SettingKeyboard} from "#app/system/settings-keyboard";
|
||||||
|
|
||||||
|
|
||||||
export default class KeyboardBindingUiHandler extends UiHandler {
|
export default class KeyboardBindingUiHandler extends UiHandler {
|
||||||
|
// Containers for different segments of the UI.
|
||||||
|
protected optionSelectContainer: Phaser.GameObjects.Container;
|
||||||
|
protected actionsContainer: Phaser.GameObjects.Container;
|
||||||
|
|
||||||
|
// Background elements for titles and action areas.
|
||||||
|
protected titleBg: Phaser.GameObjects.NineSlice;
|
||||||
|
protected actionBg: Phaser.GameObjects.NineSlice;
|
||||||
|
protected optionSelectBg: Phaser.GameObjects.NineSlice;
|
||||||
|
|
||||||
|
// Text elements for displaying instructions and actions.
|
||||||
|
private unlockText: Phaser.GameObjects.Text;
|
||||||
|
private swapText: Phaser.GameObjects.Text;
|
||||||
|
private actionLabel: Phaser.GameObjects.Text;
|
||||||
|
private cancelLabel: Phaser.GameObjects.Text;
|
||||||
|
|
||||||
|
private listening: boolean = false;
|
||||||
|
private buttonPressed: number | null = null;
|
||||||
|
|
||||||
|
// Icons for displaying current and new button assignments.
|
||||||
|
private newButtonIcon: Phaser.GameObjects.Sprite;
|
||||||
|
private targetButtonIcon: Phaser.GameObjects.Sprite;
|
||||||
|
|
||||||
|
// Function to call on cancel or completion of binding.
|
||||||
|
private cancelFn: (boolean?) => boolean;
|
||||||
|
|
||||||
|
// The specific setting being modified.
|
||||||
|
private target: SettingKeyboard;
|
||||||
constructor(scene: BattleScene, mode?: Mode) {
|
constructor(scene: BattleScene, mode?: Mode) {
|
||||||
super(scene, mode);
|
super(scene, mode);
|
||||||
|
// Listen to gamepad button down events to initiate binding.
|
||||||
|
scene.input.keyboard.on('keydown', this.onKeyDown, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
setup() {
|
setup() {
|
||||||
const ui = this.getUi();
|
const ui = this.getUi();
|
||||||
|
this.optionSelectContainer = this.scene.add.container(0, 0);
|
||||||
|
this.actionsContainer = this.scene.add.container(0, 0);
|
||||||
|
// Initially, containers are not visible.
|
||||||
|
this.optionSelectContainer.setVisible(false);
|
||||||
|
this.actionsContainer.setVisible(false);
|
||||||
|
|
||||||
|
// Add containers to the UI.
|
||||||
|
ui.add(this.optionSelectContainer);
|
||||||
|
ui.add(this.actionsContainer);
|
||||||
|
|
||||||
|
// Setup backgrounds and text objects for UI.
|
||||||
|
this.titleBg = addWindow(this.scene, (this.scene.game.canvas.width / 6) - this.getWindowWidth(), -(this.scene.game.canvas.height / 6) + 28 + 21, this.getWindowWidth(), 24);
|
||||||
|
this.titleBg.setOrigin(0.5);
|
||||||
|
this.optionSelectContainer.add(this.titleBg);
|
||||||
|
|
||||||
|
this.actionBg = addWindow(this.scene, (this.scene.game.canvas.width / 6) - this.getWindowWidth(), -(this.scene.game.canvas.height / 6) + this.getWindowHeight() + 28 + 21 + 21, this.getWindowWidth(), 24);
|
||||||
|
this.actionBg.setOrigin(0.5);
|
||||||
|
this.actionsContainer.add(this.actionBg);
|
||||||
|
|
||||||
|
// Text prompts and instructions for the user.
|
||||||
|
this.unlockText = addTextObject(this.scene, 0, 0, 'Press a button...', TextStyle.WINDOW);
|
||||||
|
this.unlockText.setOrigin(0, 0);
|
||||||
|
this.unlockText.setPositionRelative(this.titleBg, 36, 4);
|
||||||
|
this.optionSelectContainer.add(this.unlockText);
|
||||||
|
|
||||||
|
this.optionSelectBg = addWindow(this.scene, (this.scene.game.canvas.width / 6) - this.getWindowWidth(), -(this.scene.game.canvas.height / 6) + this.getWindowHeight() + 28, this.getWindowWidth(), this.getWindowHeight());
|
||||||
|
this.optionSelectBg.setOrigin(0.5);
|
||||||
|
this.optionSelectContainer.add(this.optionSelectBg);
|
||||||
|
|
||||||
|
// New button icon setup.
|
||||||
|
this.newButtonIcon = this.scene.add.sprite(0, 0, 'keyboard');
|
||||||
|
this.newButtonIcon.setScale(0.15);
|
||||||
|
this.newButtonIcon.setPositionRelative(this.optionSelectBg, 78, 16);
|
||||||
|
this.newButtonIcon.setOrigin(0.5);
|
||||||
|
this.newButtonIcon.setVisible(false);
|
||||||
|
|
||||||
|
this.swapText = addTextObject(this.scene, 0, 0, 'will swap with', TextStyle.WINDOW);
|
||||||
|
this.swapText.setOrigin(0.5);
|
||||||
|
this.swapText.setPositionRelative(this.optionSelectBg, this.optionSelectBg.width / 2 - 2, this.optionSelectBg.height / 2 - 2);
|
||||||
|
this.swapText.setVisible(false);
|
||||||
|
|
||||||
|
this.targetButtonIcon = this.scene.add.sprite(0, 0, 'keyboard');
|
||||||
|
this.targetButtonIcon.setScale(0.15);
|
||||||
|
this.targetButtonIcon.setPositionRelative(this.optionSelectBg, 78, 48);
|
||||||
|
this.targetButtonIcon.setOrigin(0.5);
|
||||||
|
this.targetButtonIcon.setVisible(false);
|
||||||
|
|
||||||
|
this.cancelLabel = addTextObject(this.scene, 0, 0, 'Cancel', TextStyle.SETTINGS_LABEL);
|
||||||
|
this.cancelLabel.setOrigin(0, 0.5);
|
||||||
|
this.cancelLabel.setPositionRelative(this.actionBg, 10, this.actionBg.height / 2);
|
||||||
|
|
||||||
|
this.actionLabel = addTextObject(this.scene, 0, 0, 'Confirm Swap', TextStyle.SETTINGS_LABEL);
|
||||||
|
this.actionLabel.setOrigin(0, 0.5);
|
||||||
|
this.actionLabel.setPositionRelative(this.actionBg, this.actionBg.width - 75, this.actionBg.height / 2);
|
||||||
|
|
||||||
|
// Add swap and cancel labels to the containers.
|
||||||
|
this.optionSelectContainer.add(this.newButtonIcon);
|
||||||
|
this.optionSelectContainer.add(this.swapText);
|
||||||
|
this.optionSelectContainer.add(this.targetButtonIcon);
|
||||||
|
this.actionsContainer.add(this.actionLabel);
|
||||||
|
this.actionsContainer.add(this.cancelLabel);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateBindings(): void {
|
onKeyDown(event): void {
|
||||||
|
const key = event.keyCode;
|
||||||
|
// // Check conditions before processing the button press.
|
||||||
|
if (!this.listening || this.buttonPressed !== null) return;
|
||||||
|
this.buttonPressed = key;
|
||||||
|
const buttonIcon = this.scene.inputController.getPressedKeyLabel(key);
|
||||||
|
const assignedButtonIcon = this.scene.inputController.getKeyboardCurrentlyAssignedIconToDisplay(this.target);
|
||||||
|
this.newButtonIcon.setFrame(buttonIcon);
|
||||||
|
this.targetButtonIcon.setFrame(assignedButtonIcon);
|
||||||
|
this.newButtonIcon.setVisible(true);
|
||||||
|
this.targetButtonIcon.setVisible(true);
|
||||||
|
this.swapText.setVisible(true);
|
||||||
|
this.setCursor(0);
|
||||||
|
this.actionsContainer.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
show(args: any[]): boolean {
|
show(args: any[]): boolean {
|
||||||
super.show(args);
|
super.show(args);
|
||||||
|
this.buttonPressed = null;
|
||||||
|
this.cancelFn = args[0].cancelHandler;
|
||||||
|
this.target = args[0].target;
|
||||||
|
|
||||||
// Move the settings container to the end of the UI stack to ensure it is displayed on top.
|
// Bring the option and action containers to the front of the UI.
|
||||||
// this.getUi().moveTo(this.settingsContainer, this.getUi().length - 1);
|
this.getUi().bringToTop(this.optionSelectContainer);
|
||||||
|
this.getUi().bringToTop(this.actionsContainer);
|
||||||
|
|
||||||
// Hide any tooltips that might be visible before showing the settings container.
|
this.optionSelectContainer.setVisible(true);
|
||||||
this.getUi().hideTooltip();
|
setTimeout(() => this.listening = true, 150);
|
||||||
|
|
||||||
// Return true to indicate the UI was successfully shown.
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getWindowWidth(): number {
|
||||||
|
return 160;
|
||||||
|
}
|
||||||
|
|
||||||
|
getWindowHeight(): number {
|
||||||
|
return 64;
|
||||||
|
}
|
||||||
|
|
||||||
processInput(button: Button): boolean {
|
processInput(button: Button): boolean {
|
||||||
|
if (this.buttonPressed === null) return;
|
||||||
const ui = this.getUi();
|
const ui = this.getUi();
|
||||||
return false;
|
let success = false;
|
||||||
|
switch (button) {
|
||||||
|
case Button.LEFT:
|
||||||
|
case Button.RIGHT:
|
||||||
|
// Toggle between action and cancel options.
|
||||||
|
const cursor = this.cursor ? 0 : 1;
|
||||||
|
success = this.setCursor(cursor);
|
||||||
|
break
|
||||||
|
case Button.ACTION:
|
||||||
|
// Process actions based on current cursor position.
|
||||||
|
if (this.cursor === 0) {
|
||||||
|
this.cancelFn();
|
||||||
|
} else {
|
||||||
|
success = true;
|
||||||
|
this.scene.inputController.swapKeyboardBinding(this.target, this.buttonPressed);
|
||||||
|
this.cancelFn(success);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Plays a select sound effect if an action was successfully processed.
|
||||||
|
if (success)
|
||||||
|
ui.playSelect();
|
||||||
|
else
|
||||||
|
ui.playError();
|
||||||
|
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
setCursor(cursor: integer): boolean {
|
setCursor(cursor: integer): boolean {
|
||||||
const ret = super.setCursor(cursor);
|
this.cursor = cursor;
|
||||||
return ret;
|
if (cursor === 1) {
|
||||||
|
this.actionLabel.setColor(this.getTextColor(TextStyle.SETTINGS_SELECTED));
|
||||||
|
this.actionLabel.setShadowColor(this.getTextColor(TextStyle.SETTINGS_SELECTED, true));
|
||||||
|
this.cancelLabel.setColor(this.getTextColor(TextStyle.WINDOW));
|
||||||
|
this.cancelLabel.setShadowColor(this.getTextColor(TextStyle.WINDOW, true));
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
this.actionLabel.setColor(this.getTextColor(TextStyle.WINDOW));
|
||||||
setOptionCursor(settingIndex: integer, cursor: integer, save?: boolean): boolean {
|
this.actionLabel.setShadowColor(this.getTextColor(TextStyle.WINDOW, true));
|
||||||
|
this.cancelLabel.setColor(this.getTextColor(TextStyle.SETTINGS_SELECTED));
|
||||||
|
this.cancelLabel.setShadowColor(this.getTextColor(TextStyle.SETTINGS_SELECTED, true));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
setScrollCursor(scrollCursor: integer): boolean {
|
clear() {
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
// updateSettingsScroll(): void {
|
|
||||||
// // Return immediately if the options container is not initialized.
|
|
||||||
// if (!this.optionsContainer) return;
|
|
||||||
//
|
|
||||||
// // Set the vertical position of the options container based on the current scroll cursor, multiplying by the item height.
|
|
||||||
// this.optionsContainer.setY(-16 * this.scrollCursor);
|
|
||||||
//
|
|
||||||
// // Iterate over all setting labels to update their visibility.
|
|
||||||
// for (let s = 0; s < this.settingLabels.length; s++) {
|
|
||||||
// // Determine if the current setting should be visible based on the scroll position.
|
|
||||||
// const visible = s >= this.scrollCursor && s < this.scrollCursor + 9;
|
|
||||||
//
|
|
||||||
// // Set the visibility of the setting label and its corresponding options.
|
|
||||||
// this.settingLabels[s].setVisible(visible);
|
|
||||||
// for (let option of this.optionValueLabels[s])
|
|
||||||
// option.setVisible(visible);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
clear(): void {
|
|
||||||
super.clear();
|
super.clear();
|
||||||
|
this.target = null;
|
||||||
// Hide the settings container to remove it from the view.
|
this.cancelFn = null;
|
||||||
// this.settingsContainer.setVisible(false);
|
this.optionSelectContainer.setVisible(false);
|
||||||
|
this.actionsContainer.setVisible(false);
|
||||||
// Remove the cursor from the UI.
|
this.newButtonIcon.setVisible(false);
|
||||||
this.eraseCursor();
|
this.targetButtonIcon.setVisible(false);
|
||||||
}
|
this.swapText.setVisible(false);
|
||||||
|
|
||||||
eraseCursor(): void {
|
|
||||||
// Check if a cursor object exists.
|
|
||||||
// if (this.cursorObj)
|
|
||||||
// this.cursorObj.destroy(); // Destroy the cursor object to clean up resources.
|
|
||||||
//
|
|
||||||
// // Set the cursor object reference to null to fully dereference it.
|
|
||||||
// this.cursorObj = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue