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 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); } }