143 lines
3.9 KiB
C#

using System.Collections.Generic;
using UnityEngine;
public class Player : MonoBehaviour, IControlable
{
[SerializeField] private Board board;
[SerializeField] private float chipYOffset = 5f;
[SerializeField] private float prepareSpeed;
[SerializeField] private float moveSpeed;
[Header("Управление")]
[SerializeField] List<InSignal> _leftButtons;
[SerializeField] List<InSignal> _rightButtons;
[SerializeField] List<InSignal> _actionButtons;
private int[] availableColumns;
private int availableColumnsIndex;
private Chip myChip;
private Vector2 targetStickedPosition;
private Vector2 targetPosition;
private PlayerState _state;
private bool controlsEnabled;
private int SelectedColumn => availableColumns[availableColumnsIndex];
public bool ControlsEnabled {
get => _state == PlayerState.Idle || _state == PlayerState.Moving;
set => controlsEnabled = value;}
public void PrepareChip(Chip chip)
{
_state = PlayerState.Preparing;
CacheColumns();
myChip = chip;
targetStickedPosition = board.GetMiddleStickedPosition();
chip.transform.position = targetStickedPosition + Vector2.up * chipYOffset;
}
public void Sleep()
{
_state = PlayerState.Sleep;
availableColumns = null;
myChip = null;
}
public void UpdateControls()
{
if (!ControlsEnabled) return;
HandleHorizontalMove();
switch (_state)
{
case PlayerState.Preparing:
if (myChip.MoveToLinear(targetStickedPosition, prepareSpeed))
_state = PlayerState.Idle;
break;
case PlayerState.Moving:
if (myChip.MoveToLinear(targetStickedPosition, moveSpeed))
_state = PlayerState.Idle;
break;
case PlayerState.Dropped:
if (myChip.MoveToAccelerated(targetPosition))
{
_state = PlayerState.Sleep;
Debug.Log("Падение фишки закончено");
}
break;
case PlayerState.Idle:
if (HandleDrop()) return;
break;
case PlayerState.Sleep:
break;
}
}
private void CacheColumns()
{
availableColumns = board.GetNonFullColumns();
availableColumnsIndex = availableColumns.Length / 2;
}
private bool HandleHorizontalMove()
{
int direction = 0;
if (IsButtonPressed(_leftButtons)) direction -= 1;
if (IsButtonPressed(_rightButtons)) direction += 1;
if (direction != 0)
{
int newIndex = Mathf.Clamp(availableColumnsIndex+direction, 0, availableColumns.Length - 1);
bool indexChanged = newIndex != availableColumnsIndex;
if (indexChanged)
{
availableColumnsIndex = newIndex;
targetStickedPosition = board.GetStickedPosition(SelectedColumn);
_state = PlayerState.Moving;
return true;
}
}
return false;
}
private bool HandleDrop()
{
if (_state != PlayerState.Idle)
return false;
bool hasAction = IsButtonPressed(_actionButtons);
if (hasAction)
{
PerformDrop();
return true;
}
return false;
}
private void PerformDrop()
{
targetPosition = board.GetTargetPosition(SelectedColumn);
board.DropChip(myChip, SelectedColumn);
_state = PlayerState.Dropped;
}
private bool IsButtonPressed(List<InSignal> buttons)
{
foreach (var signal in buttons)
if (In.GetButtonDown(signal))
return true;
return false;
}
private enum PlayerState { Preparing, Idle, Moving, Dropped, Sleep }
}