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