106 lines
3.3 KiB
C#
106 lines
3.3 KiB
C#
using System.Threading;
|
|
using Cysharp.Threading.Tasks;
|
|
using Enums;
|
|
using Services;
|
|
using UnityEngine;
|
|
using Utils;
|
|
|
|
namespace Views {
|
|
public class GemView : MonoBehaviour {
|
|
private Gem gem;
|
|
public Gem Gem => this.gem;
|
|
|
|
private SpriteRenderer spriteRenderer;
|
|
|
|
private bool isFalling;
|
|
private const float SPAWN_SCALE_FROM = 0f;
|
|
private const float SPAWN_SCALE_DURATION = 0.12f;
|
|
|
|
private CancellationTokenSource spawnScaleCts;
|
|
|
|
public void Bind(Gem gem, bool isBomb = false) {
|
|
this.gem = gem;
|
|
this.gameObject.SetActive(true);
|
|
|
|
SetupGem(isBomb);
|
|
PlaySpawnScale();
|
|
}
|
|
|
|
private void SetupGem(bool isBomb) {
|
|
this.spriteRenderer ??= GetComponent<SpriteRenderer>();
|
|
|
|
if (isBomb) {
|
|
this.spriteRenderer.color = this.gem.MatchColor switch {
|
|
GemType.Blue => Color.blue,
|
|
GemType.Green => Color.green,
|
|
GemType.Red => Color.red,
|
|
GemType.Yellow => Color.yellow,
|
|
GemType.Purple => Color.magenta,
|
|
_ => this.spriteRenderer.color
|
|
};
|
|
} else {
|
|
this.spriteRenderer.color = Color.white;
|
|
}
|
|
}
|
|
|
|
public void Unbind() {
|
|
this.spawnScaleCts?.Cancel();
|
|
this.spawnScaleCts?.Dispose();
|
|
this.spawnScaleCts = null;
|
|
|
|
this.gem = null;
|
|
this.gameObject.SetActive(false);
|
|
this.isFalling = false;
|
|
}
|
|
|
|
private void PlaySpawnScale() {
|
|
this.spawnScaleCts?.Cancel();
|
|
this.spawnScaleCts?.Dispose();
|
|
this.spawnScaleCts = new CancellationTokenSource();
|
|
|
|
this.transform.localScale = Vector3.one * SPAWN_SCALE_FROM;
|
|
AnimateSpawnScaleAsync(this.spawnScaleCts.Token).Forget();
|
|
}
|
|
|
|
private async UniTask AnimateSpawnScaleAsync(CancellationToken ct) {
|
|
float timer = 0f;
|
|
while (timer < SPAWN_SCALE_DURATION) {
|
|
ct.ThrowIfCancellationRequested();
|
|
|
|
timer += Time.deltaTime;
|
|
float scale = Mathf.Clamp01(timer / SPAWN_SCALE_DURATION);
|
|
|
|
scale = Mathf.SmoothStep(0f, 1f, scale);
|
|
|
|
this.transform.localScale = Vector3.LerpUnclamped(
|
|
Vector3.one * SPAWN_SCALE_FROM,
|
|
Vector3.one,
|
|
scale
|
|
);
|
|
|
|
await UniTask.Yield(PlayerLoopTiming.Update, ct);
|
|
}
|
|
|
|
this.transform.localScale = Vector3.one;
|
|
}
|
|
|
|
private async UniTask FallDelay() {
|
|
float fallDelay = 1 * (this.gem.Position.y / 10f);
|
|
await UniTask.WaitForSeconds(fallDelay);
|
|
this.isFalling = true;
|
|
}
|
|
|
|
public async UniTaskVoid UpdatePosition(Vector2Int positionBasedOnIndex, float gemSpeed) {
|
|
if (!this.isFalling) {
|
|
await FallDelay();
|
|
}
|
|
|
|
if (!this.isFalling)
|
|
return;
|
|
|
|
if (Vector2.Distance(this.transform.position, positionBasedOnIndex.ToVector2()) > 0.01f) {
|
|
this.transform.position = Vector2.Lerp(this.transform.position, positionBasedOnIndex.ToVector2(), gemSpeed);
|
|
}
|
|
}
|
|
}
|
|
} |