157 lines
4.4 KiB
C#
157 lines
4.4 KiB
C#
//Refactored 24.11.2025
|
|
using System.Collections;
|
|
using UnityEngine;
|
|
using UnityEngine.UIElements;
|
|
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;
|
|
const 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<TrailRenderer>().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<TrailRenderer>().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.fieldArr[rowIndex, colIndex] = GameManager.instance.currentPlayer;
|
|
GameManager.instance.setChipTransformToArray(rowIndex, colIndex, chipTransform);
|
|
GameManager.instance.stateMachine.ChangeState(new CheckState(rowIndex, colIndex));
|
|
}
|
|
#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;
|
|
}
|
|
}
|