chip-game/Assets/Scripts/Inputs/KeyboardInput.cs

180 lines
9.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using UnityEngine;
/// <summary>
/// Реализация системы ввода с клавиатуры для тестирования и разработки.
/// Эмулирует работу периферийной платы через стандартные клавиши клавиатуры.
/// </summary>
/// <remarks>
/// Соответствие клавиш и пинов:
/// - Игрок 1: WASD + Space
/// - Игрок 2: Стрелки + RightControl
/// - Служебные: 1, 2, 3, F5
/// - Датчики хопера: O, P
/// </remarks>
public class KeyboardInput : InputSource
{
private int currentPlayer => gm.currentPlayer == CellState.Player1 ? 1 : 2;//ПЕРЕОПРЕДЕЛИТЕ ОПРЕДЕЛЕНИЕ ТЕКУЩЕГО ИГРОКА ПОД СВОЮ СИСТЕМУ.
private GameManager gm;//я получаю кто сейчас ходит через этого менеджера. Если у вас другое, допишите.
/// <summary>Проверяет состояние кнопки по её физическому пину через клавиатуру</summary>
public override bool GetButton(ButtonPinMapping button) => Input.GetKey(getKeyCode(button));
/// <summary>Проверяет нажатие кнопки по пину в текущем кадре через клавиатуру</summary>
public override bool GetButtonDown(ButtonPinMapping button) => Input.GetKeyDown(getKeyCode(button));
/// <summary>Проверяет отпускание кнопки по пину в текущем кадре через клавиатуру</summary>
public override bool GetButtonUp(ButtonPinMapping button) => Input.GetKeyUp(getKeyCode(button));
//----------------------------------------------------------------------------------
/// <summary>Проверяет состояние кнопки по числовому индексу пина через клавиатуру</summary>
public override bool GetButton(int pinIndex) => Input.GetKey(getKeyCode(pinIndex));
/// <summary>Проверяет нажатие кнопки по индексу пина в текущем кадре через клавиатуру</summary>
public override bool GetButtonDown(int pinIndex) => Input.GetKeyDown(getKeyCode(pinIndex));
/// <summary>Проверяет отпускание кнопки по индексу пина в текущем кадре через клавиатуру</summary>
public override bool GetButtonUp(int pinIndex) => Input.GetKeyUp(getKeyCode(pinIndex));
//----------------------------------------------------------------------------------
/// <summary>Проверяет состояние действия для текущего игрока (всегда игрок 1 для клавиатуры)</summary>
public override bool GetButtonCurrentPlayer(PlayerAction button) => GetButton(GetButtonForCurrentPlayer(button));
/// <summary>Проверяет начало действия текущим игроком в текущем кадре</summary>
public override bool GetButtonDownCurrentPlayer(PlayerAction button) => GetButtonDown(GetButtonForCurrentPlayer(button));
/// <summary>Проверяет завершение действия текущим игроком в текущем кадре</summary>
public override bool GetButtonUpCurrentPlayer(PlayerAction button) => GetButtonUp(GetButtonForCurrentPlayer(button));
//----------------------------------------------------------------------------------
/// <summary>Проверяет состояние действия для любого из игроков (игрок 1 ИЛИ игрок 2)</summary>
public override bool GetButtonAnyPlayer(PlayerAction button) => CheckBothPlayers(button, GetButton);
/// <summary>Проверяет начало действия любым игроком в текущем кадре</summary>
public override bool GetButtonDownAnyPlayer(PlayerAction button) => CheckBothPlayers(button, GetButtonDown);
/// <summary>Проверяет завершение действия любым игроком в текущем кадре</summary>
public override bool GetButtonUpAnyPlayer(PlayerAction button) => CheckBothPlayers(button, GetButtonUp);
//----------------------------------------------------------------------------------
/// <summary>
/// Инициализирует клавиатурный ввод. Всегда возвращает true так как клавиатура всегда доступна.
/// </summary>
/// <returns>Всегда true</returns>
public override bool Initialize() => gm = GameManager.instance;
// ================================================================================
// ВСПОМОГАТЕЛЬНЫЕ МЕТОДЫ
// ================================================================================
/// <summary>
/// Определяет кнопку текущего игрока для указанного действия.
/// Для клавиатуры всегда возвращает кнопку первого игрока.
/// </summary>
private ButtonPinMapping GetButtonForCurrentPlayer(PlayerAction button)
{
var buttons = _buttonByAction(button);
return currentPlayer == 1 ? buttons.player1button : buttons.player2button;
}
/// <summary>
/// Проверяет действие для обоих игроков используя указанную функцию проверки.
/// </summary>
private bool CheckBothPlayers(PlayerAction action, System.Func<ButtonPinMapping, bool> buttonFunc)
{
var buttons = _buttonByAction(action);
return buttonFunc(buttons.player1button) || buttonFunc(buttons.player2button);
}
/// <summary>
/// Возвращает соответствие между игровыми действиями и физическими кнопками игроков.
/// </summary>
private (ButtonPinMapping player1button, ButtonPinMapping player2button) _buttonByAction(PlayerAction playerAction) =>
playerAction switch
{
PlayerAction.up => (ButtonPinMapping.up1, ButtonPinMapping.up2),
PlayerAction.down => (ButtonPinMapping.down1, ButtonPinMapping.down2),
PlayerAction.left => (ButtonPinMapping.left1, ButtonPinMapping.left2),
PlayerAction.right => (ButtonPinMapping.right1, ButtonPinMapping.right2),
PlayerAction.action => (ButtonPinMapping.action1, ButtonPinMapping.action2),
PlayerAction.extra => (ButtonPinMapping.extra, ButtonPinMapping.extra),
_ => throw new System.ArgumentException($"Unknown player action: {playerAction}")
};
/// <summary>
/// Преобразует физический пин в соответствующую клавишу клавиатуры.
/// </summary>
private KeyCode getKeyCode(ButtonPinMapping button)
{
return button switch
{
ButtonPinMapping.up1 => KeyCode.W,
ButtonPinMapping.right1 => KeyCode.D,
ButtonPinMapping.down1 => KeyCode.S,
ButtonPinMapping.left1 => KeyCode.A,
ButtonPinMapping.action1 => KeyCode.Space,
ButtonPinMapping.up2 => KeyCode.UpArrow,
ButtonPinMapping.right2 => KeyCode.RightArrow,
ButtonPinMapping.down2 => KeyCode.DownArrow,
ButtonPinMapping.left2 => KeyCode.LeftArrow,
ButtonPinMapping.action2 => KeyCode.RightControl,
ButtonPinMapping.startOnePlayer => KeyCode.Alpha1,
ButtonPinMapping.startTwoPlayers => KeyCode.Alpha2,
ButtonPinMapping.secret => KeyCode.F5,
ButtonPinMapping.extra => KeyCode.Alpha3,
ButtonPinMapping.hasPrize => KeyCode.O,
ButtonPinMapping.prizeGiven => KeyCode.P,
_ => KeyCode.None,
};
}
/// <summary>
/// Преобразует числовой индекс пина в соответствующую клавишу клавиатуры.
/// Используется для методов с прямым доступом по индексу.
/// </summary>
private KeyCode getKeyCode(int pinIndex)
{
return pinIndex switch
{
0 => KeyCode.W, // up1
1 => KeyCode.D, // right1
2 => KeyCode.S, // down1
3 => KeyCode.A, // left1
4 => KeyCode.Space, // action1
5 => KeyCode.UpArrow, // up2
6 => KeyCode.RightArrow, // right2
7 => KeyCode.DownArrow, // down2
8 => KeyCode.LeftArrow, // left2
9 => KeyCode.RightControl, // action2
10 => KeyCode.Alpha1, // startOnePlayer
11 => KeyCode.Alpha2, // startTwoPlayers
12 => KeyCode.F5, // secret
13 => KeyCode.Alpha3, // extra
14 => KeyCode.O, // hasPrize
15 => KeyCode.P, // prizeGiven
_ => KeyCode.None, // невалидный индекс
};
}
public override bool AnyButton()
{
return Input.anyKey;
}
}