first iteration of KeyboardBindingUiHandler
parent
c963970adf
commit
c6d3f93b3f
|
@ -5,6 +5,7 @@ const cfg_keyboard_azerty = {
|
|||
padID: 'keyboard',
|
||||
padType: 'azerty',
|
||||
gamepadMapping: {
|
||||
NEED TO ADD KEYCODE FROM EVENT HERE
|
||||
KEY_A: 0,
|
||||
KEY_B: 0,
|
||||
KEY_C: 0,
|
||||
|
|
|
@ -10,6 +10,12 @@ export function getKeyFromInputIndex(config: GamepadConfig, index: number): Stri
|
|||
}
|
||||
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
|
||||
export function getKeyForSettingName(config: GamepadConfig, settingName: string): String | null {
|
||||
|
@ -41,6 +47,11 @@ export function getCurrenlyAssignedIconFromInputIndex(config: GamepadConfig, ind
|
|||
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
|
||||
export function getCurrentlyAssignedIconToSettingName(config: GamepadConfig, settingName: string): string {
|
||||
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 {
|
||||
getCurrenlyAssignedIconFromInputIndex, getCurrentlyAssignedIconToSettingName,
|
||||
getKeyFromInputIndex, getCurrentlyAssignedToSettingName
|
||||
getKeyFromInputIndex, getCurrentlyAssignedToSettingName, getCurrenlyAssignedIconFromKeyboardKey
|
||||
} from "./configs/gamepad-utils";
|
||||
import SettingsKeyboardUiHandler from "#app/ui/settings/settings-keyboard-ui-handler";
|
||||
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)];
|
||||
}
|
||||
|
||||
getPressedKeyLabel(key): string {
|
||||
return getCurrenlyAssignedIconFromKeyboardKey(this.configs[this.chosenKeyboard], key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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);
|
||||
}
|
||||
|
||||
getKeyboardCurrentlyAssignedIconToDisplay(target: SettingGamepad): string {
|
||||
return getCurrentlyAssignedIconToSettingName(this.configs[this.chosenKeyboard], target);
|
||||
}
|
||||
|
||||
/**
|
||||
* Swaps the binding of two controls on the chosen gamepad 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);
|
||||
}
|
||||
|
||||
swapKeyboardBinding(settingName, pressedButton): void {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 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.
|
||||
|
|
|
@ -2,88 +2,207 @@ import UiHandler from "../ui-handler";
|
|||
import BattleScene from "../../battle-scene";
|
||||
import {Mode} from "../ui";
|
||||
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 {
|
||||
// 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) {
|
||||
super(scene, mode);
|
||||
// Listen to gamepad button down events to initiate binding.
|
||||
scene.input.keyboard.on('keydown', this.onKeyDown, this);
|
||||
}
|
||||
|
||||
setup() {
|
||||
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 {
|
||||
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.
|
||||
// this.getUi().moveTo(this.settingsContainer, this.getUi().length - 1);
|
||||
// Bring the option and action containers to the front of the UI.
|
||||
this.getUi().bringToTop(this.optionSelectContainer);
|
||||
this.getUi().bringToTop(this.actionsContainer);
|
||||
|
||||
// Hide any tooltips that might be visible before showing the settings container.
|
||||
this.getUi().hideTooltip();
|
||||
|
||||
// Return true to indicate the UI was successfully shown.
|
||||
this.optionSelectContainer.setVisible(true);
|
||||
setTimeout(() => this.listening = true, 150);
|
||||
return true;
|
||||
}
|
||||
|
||||
getWindowWidth(): number {
|
||||
return 160;
|
||||
}
|
||||
|
||||
getWindowHeight(): number {
|
||||
return 64;
|
||||
}
|
||||
|
||||
processInput(button: Button): boolean {
|
||||
if (this.buttonPressed === null) return;
|
||||
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 {
|
||||
const ret = super.setCursor(cursor);
|
||||
return ret;
|
||||
}
|
||||
|
||||
setOptionCursor(settingIndex: integer, cursor: integer, save?: boolean): boolean {
|
||||
this.cursor = cursor;
|
||||
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));
|
||||
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;
|
||||
}
|
||||
|
||||
setScrollCursor(scrollCursor: integer): boolean {
|
||||
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 {
|
||||
clear() {
|
||||
super.clear();
|
||||
|
||||
// Hide the settings container to remove it from the view.
|
||||
// this.settingsContainer.setVisible(false);
|
||||
|
||||
// Remove the cursor from the UI.
|
||||
this.eraseCursor();
|
||||
}
|
||||
|
||||
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;
|
||||
this.target = null;
|
||||
this.cancelFn = null;
|
||||
this.optionSelectContainer.setVisible(false);
|
||||
this.actionsContainer.setVisible(false);
|
||||
this.newButtonIcon.setVisible(false);
|
||||
this.targetButtonIcon.setVisible(false);
|
||||
this.swapText.setVisible(false);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue