chip-gameV3/Assets/Scripts/Common/GameFSM/PositioningState.cs

180 lines
5.7 KiB
C#

using System.Collections.Generic;
using UnityEngine;
public class PositioningState : IState
{
GameManager gm;
GameObject chip;
int index;
int position;
bool chipOnPosition;
const int DEFAULT_SPEED = 50;
List<int> validPositions;
public void enter()
{
gm = GameManager.instance;
chip = gm.currentChip;
chipOnPosition = true;
validPositions = GameManager.fieldModel.CollectNonFullCols();
int centralIndex = validPositions.Count / 2;
index = centralIndex;
position = validPositions[centralIndex];
gm.currentColumnIndex = validPositions[centralIndex];
float offsety = gm.startY;
if (gm.gameMode == GameMode.pvp) offsety = gm.startY + 5;//повыше
float x = gm.slotLeftTop.position.x + validPositions[index] * gm.stepX;
float y = gm.startY + offsety;
chip.transform.position = new Vector3(x, y, 0);
chip.SetActive(true);
gm.chipPointer.Show();
gm.chipPointer.SetColorByPlayer(gm.currentPlayer);
}
public void exit()
{
gm.pvpPointer.SetVisibility(false);
gm.chipPointer.Hide();
}
public void update()
{
// вычисление ввода в зависимости от игрового режима
var input = GetInputs();
if (gm.gameMode == GameMode.pve) gm.vsBotThinkTime += Time.deltaTime;
HandleChipMovement(input.direction);
Vector2 stickedPosition = GetStickedPosition();
Vector2 targetPosition = GetTargetPosition();
gm.chipPointer.SetPosition(targetPosition);
if (gm.gameMode == GameMode.pvp)
{
gm.pvpPointer.SetColor(gm.currentPlayer);
gm.pvpPointer.SetVisibility(true);
gm.pvpPointer.MoveTo(stickedPosition);
stickedPosition += Vector2.up * 5;//повыше
}
chip.transform.position = Vector2.MoveTowards(chip.transform.position, stickedPosition, DEFAULT_SPEED * Time.deltaTime);
if ((Vector2)chip.transform.position == stickedPosition)
chipOnPosition = true;
else
chipOnPosition = false;
if (HandleDrop(input.action)) return;
if (HandleExitToMenu()) return;
}
private void HandleChipMovement(int direction)
{
if (!chipOnPosition) return;
index = Mathf.Clamp(index + direction, 0, validPositions.Count - 1);
int prevPos = position;
position = validPositions[index];
int dist = Mathf.Abs(position - prevPos);
gm.chipXSpeed = dist * DEFAULT_SPEED;//скорость зануляется
gm.currentColumnIndex = position;
SoundManager.instance.playSwitch();
}
private bool HandleExitToMenu()
{
bool exitPressed = In.GetButtonDown(ButtonPinMapping.startOnePlayer) || In.GetButtonDown(ButtonPinMapping.startTwoPlayers);
if (exitPressed && !gm.moveMade)
{
FieldCleaner.Clear();
PaymentSystem.ReturnCredits(gm.gameMode);
GameManager.instance.timerManager.StopAllTimers();
GameManager.instance.stateMachine.ChangeState(new MenuState());
return true;
}
return false;
}
private bool HandleDrop(bool action)
{
if (!action) return false;
//todo: посмотреть нахуя currentColumnIndex зарыто в gm. разрыть.
bool canDropInCurrentColumn = GameManager.fieldModel.GetColumnHeight(gm.currentColumnIndex) != -1;
if (!(chipOnPosition && canDropInCurrentColumn))
{
SoundManager.instance.playWrong();
return false;
}
float delayBeforeStartFalling = 0;
if (gm.gameMode == GameMode.pve) gm.vsBotMoves += 1;
if (gm.gameMode == GameMode.pvp)
{
AvatarEventBus.Instance.OnTurnEnd?.Invoke(gm.currentPlayer);
delayBeforeStartFalling = DualAvatarController.Instance.CurrentAvatar.ChipSpawnTime;
}
gm.moveMade = true;
Vector2 targetPosition = GetTargetPosition();
gm.stateMachine.ChangeState(new ChipFallingState(startDelay: delayBeforeStartFalling, gm.currentColumnIndex));
return true;
}
private Vector2 GetStickedPosition()
{
float targetX = gm.slotLeftTop.position.x +
gm.currentColumnIndex *
gm.stepX;
float targetY = gm.startY;
return new Vector2(targetX, targetY);
}
private Vector2 GetTargetPosition()
{
float targetX = gm.slotLeftTop.position.x +
gm.currentColumnIndex *
gm.stepX;
float targetY = GameManager.instance.slotLeftTop.transform.position.y - GameManager.instance.stepY * GameManager.fieldModel.GetColumnHeight(gm.currentColumnIndex);
return new Vector2(targetX, targetY);
}
private (int direction, bool action) GetInputs()
{
bool left = false,
right = false,
action = false;
if (gm.gameMode == GameMode.pvp)
{
left = In.GetButtonDownCurrentPlayer(PlayerAction.left);
right = In.GetButtonDownCurrentPlayer(PlayerAction.right);
action = In.GetButtonDownCurrentPlayer(PlayerAction.down);
}
else if (gm.gameMode == GameMode.pve)
{
left = In.GetButtonDownAnyPlayer(PlayerAction.left);
right = In.GetButtonDownAnyPlayer(PlayerAction.right);
action = In.GetButtonDownAnyPlayer(PlayerAction.down);
}
int direction = 0;
if (left) direction -= 1;
if (right) direction += 1;
return (direction, action);
}
}