using System.Collections; using UnityEngine; public class ChipFallingState : IState { const float ROTATION_SPEED_FACTOR = -0.5f; const float BOUNCE_SPEEDY_LOSS_FACTOR = 0.5f; const float BOUNCE_SPEEDY_TRESHOLD = 5; const float MAX_ANGULAR_SPEED = 500; bool USE_BOUNCE = false; int rowIndex; int colIndex; float angularSpeed; Vector2 targetPosition; Transform chipTransform; bool firstTouchCompleted = false; float startDelay = 0; bool delayCompleted = false; public ChipFallingState(float startDelay) { this.startDelay = startDelay; } #region ENTER_METHODS public void enter() => GameManager.instance.StartCoroutine(DelayedEnter(startDelay)); private void CacheFields() { chipTransform = GameManager.instance.currentChip.transform; colIndex = GameManager.instance.currentColumnIndex; rowIndex = GameManager.fieldModel.getHeight(colIndex); targetPosition = CalculateTargetPosition(); angularSpeed = Random.Range(-MAX_ANGULAR_SPEED, MAX_ANGULAR_SPEED); } private void PrepareForFalling() { chipTransform.GetComponent().enabled = true; GameManager.instance.chipYSpeed = 0; } private void InitialSound() => SoundManager.instance.playDropDown(); private Vector2 CalculateTargetPosition() { float targetX = chipTransform.position.x; float targetY = GameManager.instance.slotLeftTop.transform.position.y - GameManager.instance.stepY * rowIndex; return new Vector2(targetX, targetY); } #endregion #region UPDATE_METHODS public void update() { if (!delayCompleted) return; ChipFallProcess(); if (chipTransform.position.y == targetPosition.y) { //обработка первого касания if (!firstTouchCompleted) { firstTouchCompleted = true; chipTransform.GetComponent().emitting = false; //Можно попробовать некоторый звук подходящий в это место //SoundManager.instance.playExplosion(); } if (USE_BOUNCE) BounceBehaviour(); else NoBounceBehaviour(); } } private void ChipFallProcess() { GameManager.instance.chipYSpeed += GameManager.instance.chipAcceleration * Time.deltaTime; float speed = GameManager.instance.chipYSpeed; float offsetY = speed * Time.deltaTime; if (chipTransform.position.y - offsetY < targetPosition.y) offsetY = -targetPosition.y + chipTransform.position.y; chipTransform.transform.Translate(Vector2.down * offsetY, Space.World); chipTransform.transform.Rotate(0, 0, angularSpeed * Time.deltaTime); } private void BounceBehaviour() { if (GameManager.instance.chipYSpeed > BOUNCE_SPEEDY_TRESHOLD) { Bounce(); } else { CompleteChipLanding(); } } private void NoBounceBehaviour() { SoundManager.instance.playChipBounce(); CompleteChipLanding(); } private void Bounce() { angularSpeed *= ROTATION_SPEED_FACTOR; SoundManager.instance.playChipBounce(); GameManager.instance.chipYSpeed = -GameManager.instance.chipYSpeed * BOUNCE_SPEEDY_LOSS_FACTOR; } private void CompleteChipLanding() { chipTransform.position = targetPosition; GameManager.fieldModel.FieldArray[rowIndex, colIndex] = GameManager.instance.currentPlayer; GameManager.instance.setChipTransformToArray(rowIndex, colIndex, chipTransform); //GameManager.instance.stateMachine.ChangeState(new CheckState()); //EndOfTurnHandler.EvaluateTurnEnding(); StateRouter.RouteAfterTurn(); } #endregion #region EXIT_METHODS public void exit() => AnnouncePlayerTurn(); private void AnnouncePlayerTurn() { if (GameManager.instance.currentPlayer == CellState.Player1) { CharacterEventBus.Instance.OnPlayerTurn?.Invoke(); } } #endregion IEnumerator DelayedEnter(float startDelay) { yield return new WaitForSeconds(startDelay); CacheFields(); PrepareForFalling(); InitialSound(); delayCompleted = true; } }