diff --git a/Assets/GameVariables.asset b/Assets/GameVariables.asset index 577c8d9..b92df87 100644 --- a/Assets/GameVariables.asset +++ b/Assets/GameVariables.asset @@ -63,6 +63,9 @@ MonoBehaviour: bombExplodeSfx: {fileID: 8300000, guid: 9dcc9b1297952c446a5571fdb2fb7a2f, type: 3} bombDelay: 2 bombRadius: 2 - dropHeight: 2 - gemSpeed: 4 + dropHeight: 3 + gemSpeed: 5 scoreSpeed: 3 + cascadeDelayMs: 150 + swapDelayMs: 600 + fillBoardDelayMs: 500 diff --git a/Assets/Scripts/ScriptableObjects/GameVariables.cs b/Assets/Scripts/ScriptableObjects/GameVariables.cs index 5a1986b..d5e16fe 100644 --- a/Assets/Scripts/ScriptableObjects/GameVariables.cs +++ b/Assets/Scripts/ScriptableObjects/GameVariables.cs @@ -28,5 +28,10 @@ namespace ScriptableObjects { [Header("Score")] public float scoreSpeed = 5; + + [Header("Delays")] + public int cascadeDelayMs = 150; + public int swapDelayMs = 600; + public int fillBoardDelayMs = 250; } } \ No newline at end of file diff --git a/Assets/Scripts/Services/GameBoardService.cs b/Assets/Scripts/Services/GameBoardService.cs index 0f2d5bd..9967f70 100644 --- a/Assets/Scripts/Services/GameBoardService.cs +++ b/Assets/Scripts/Services/GameBoardService.cs @@ -138,14 +138,14 @@ namespace Services { ApplySwap(from, to); - await UniTask.Delay(600); + await UniTask.Delay(this.gameVariables.swapDelayMs); this.bombService.SetLastSwap(from, to); this.matchService.FindAllMatches(); this.bombService.DetectBombSpawnFromLastSwap(this.matchService.CurrentMatches); if (this.matchService.CurrentMatches.Count == 0) { ApplySwap(to, from); - await UniTask.Delay(600); + await UniTask.Delay(this.gameVariables.swapDelayMs); this.currentState = GameState.Move; return false; } @@ -229,7 +229,7 @@ namespace Services { foreach (Vector2Int p in matchPositions.Distinct()) await DestroyAtAsync(p); - await UniTask.Delay(600); + await UniTask.Delay(this.gameVariables.fillBoardDelayMs); await MoveGemsDown(); return; @@ -249,7 +249,7 @@ namespace Services { this.scoreService.ScoreCheck(gem.ScoreValue); ReleaseMatchedGems(pos); } - await UniTask.Delay(250); + await UniTask.Delay(this.gameVariables.fillBoardDelayMs); await MoveGemsDown(); } @@ -283,27 +283,45 @@ namespace Services { } private async UniTask MoveGemsDown() { - int nullCounter = 0; - for (int x = 0; x < this.gameBoard.Width; x++) + while (true) { - for (int y = 0; y < this.gameBoard.Height; y++) + // Build moves from a snapshot of the current grid state (no mid-wave chaining) + List<(Vector2Int from, Vector2Int to, Gem gem)> moves = new List<(Vector2Int, Vector2Int, Gem)>(); + + for (int x = 0; x < this.gameBoard.Width; x++) { - Gem currentGem = this.gameBoard.GetGemAt(new Vector2Int(x, y)); - if (currentGem == null) + for (int y = 1; y < this.gameBoard.Height; y++) { - nullCounter++; - } - else if (nullCounter > 0) - { - currentGem.SetPosition(new Vector2Int(currentGem.Position.x, currentGem.Position.y - nullCounter)); - this.gameBoard.SetGemAt(currentGem.Position, currentGem); - this.gameBoard.SetGemAt(new Vector2Int(x,y), null); + Vector2Int from = new Vector2Int(x, y); + Vector2Int to = new Vector2Int(x, y - 1); + + Gem gem = this.gameBoard.GetGemAt(from); + if (gem == null) + continue; + + Gem below = this.gameBoard.GetGemAt(to); + if (below != null) + continue; + + moves.Add((from, to, gem)); } } - nullCounter = 0; + + if (moves.Count == 0) + break; + + // Apply all moves simultaneously for this wave + for (int i = 0; i < moves.Count; i++) + { + (Vector2Int from, Vector2Int to, Gem gem) move = moves[i]; + this.gameBoard.SetGemAt(move.to, move.gem); + this.gameBoard.SetGemAt(move.from, null); + move.gem.SetPosition(move.to); + } + + await UniTask.Delay(this.gameVariables.cascadeDelayMs); } - await UniTask.Delay(600); await FillBoard(); } @@ -312,7 +330,7 @@ namespace Services { this.matchService.FindAllMatches(); if (this.matchService.CurrentMatches.Count > 0) { - await UniTask.Delay(600); + await UniTask.Delay(this.gameVariables.fillBoardDelayMs); // In cascades, there is no "creating slot" bomb protection. await DestroyMatchesAsync(new List()); @@ -359,7 +377,7 @@ namespace Services { SpawnGemGameObject(gem); if (i < groups.Count - 1) - await UniTask.Delay(150); + await UniTask.Delay(this.gameVariables.cascadeDelayMs); } if(this.currentState == GameState.Setup)