From 2bd94c8df9de0c33519381a100af2245689fc431 Mon Sep 17 00:00:00 2001 From: Jesus Castro Date: Thu, 18 Dec 2025 00:21:44 +0800 Subject: [PATCH] Separate SetGem and SpawnGemGameObject --- Assets/GameVariables.asset | 2 +- Assets/Scripts/Services/GameBoardService.cs | 85 ++++++++++++++------- Assets/Scripts/Views/GemView.cs | 8 +- 3 files changed, 60 insertions(+), 35 deletions(-) diff --git a/Assets/GameVariables.asset b/Assets/GameVariables.asset index b50bfce..577c8d9 100644 --- a/Assets/GameVariables.asset +++ b/Assets/GameVariables.asset @@ -64,5 +64,5 @@ MonoBehaviour: bombDelay: 2 bombRadius: 2 dropHeight: 2 - gemSpeed: 0.00625 + gemSpeed: 4 scoreSpeed: 3 diff --git a/Assets/Scripts/Services/GameBoardService.cs b/Assets/Scripts/Services/GameBoardService.cs index bbac2a7..9f1679a 100644 --- a/Assets/Scripts/Services/GameBoardService.cs +++ b/Assets/Scripts/Services/GameBoardService.cs @@ -9,6 +9,7 @@ using ScriptableObjects; using Services.Interfaces; using Structs; using UnityEngine; +using UnityEngine.UIElements; using Utils; using VContainer.Unity; using Views; @@ -72,6 +73,7 @@ namespace Services { //Instantiates background tiles and calls SpawnGems //Uses MatchService.MatchesAt to avoid matching Gems public void Setup() { + List gemsToSpawn = new List(); for (int x = 0; x < this.gameBoard.Width; x++) for (int y = 0; y < this.gameBoard.Height; y++) { @@ -85,34 +87,43 @@ namespace Services { iterations++; } while (this.matchService.MatchesAt(position.ToVector2Int(), (GemType)gemToUse) && iterations < 100); - SpawnGem(position.ToVector2Int(), (GemType)gemToUse); + gemsToSpawn.Add(SetGemAt(position.ToVector2Int(), (GemType)gemToUse)); } + + SpawnCascade(gemsToSpawn); this.currentState = GameState.Move; } + private Gem SetGemAt(Vector2Int position, GemType gemType, bool isBomb = false) { + GemTypeValues gemValue = GemUtils.GetGemValues(gemType, this.gameVariables.gemsPrefabs); + Gem gem = new Gem(isBomb ? GemType.Bomb : gemType, position, gemValue, gemType); + this.gameBoard.SetGemAt(position, gem); + + return gem; + } + + private void SpawnGemGameObject(Gem gem, bool isBomb = false) { + GemView gemView = this.objectPool.Get(isBomb ? GemType.Bomb : gem.Type, gem.Position, isBomb ? 0 : this.gameVariables.dropHeight); + gemView.name = "Gem - " + gem.Position.x + ", " + gem.Position.y + ' ' + gem.Type; + + GemTypeValues gemValue = GemUtils.GetGemValues(gem.MatchColor, this.gameVariables.gemsPrefabs); + gemView.Bind(gem, gemValue, isBomb: isBomb); + this.gemPresenters.Add(new GemPresenter(gem, gemView)); + } + + private void SetAndSpawnGem(Vector2Int position, GemType gemType, bool isBomb) { + if(isBomb) + ReleaseMatchedGems(position); + + SpawnGemGameObject(SetGemAt(position, gemType, isBomb), isBomb); + } + private void SpawnBackgroundTile(Vector2 position) { GameObject backgroundTile = Object.Instantiate(this.gameVariables.bgTilePrefabs, position, Quaternion.identity); backgroundTile.transform.SetParent(this.backgroundHolder); backgroundTile.name = "BG Tile - " + position.x + ", " + position.y; } - - //Uses the ObjectPool to spawn a gem at the given position - private void SpawnGem(Vector2Int position, GemType gemType, bool isBomb = false) { - if (isBomb) { - ReleaseMatchedGems(position); - } - - GemView gemView = this.objectPool.Get(isBomb ? GemType.Bomb : gemType, position, isBomb ? 0 : this.gameVariables.dropHeight); - gemView.name = "Gem - " + position.x + ", " + position.y + ' ' + gemType; - - GemTypeValues gemValue = GemUtils.GetGemValues(gemType, this.gameVariables.gemsPrefabs); - Gem gem = new Gem(isBomb ? GemType.Bomb : gemType, position, gemValue, gemType); - gemView.Bind(gem, gemValue, isBomb: isBomb); - - this.gemPresenters.Add(new GemPresenter(gem, gemView)); - this.gameBoard.SetGemAt(position, gem); - } //Listens to InputService OnSwapRequest public async UniTask TrySwap(Vector2Int from, Vector2Int to) { @@ -141,7 +152,7 @@ namespace Services { return false; } - List protectedPositions = this.bombService.ApplyPendingBombSpawns(SpawnGem); + List protectedPositions = this.bombService.ApplyPendingBombSpawns(SetAndSpawnGem); await DestroyMatchesAsync(protectedPositions); this.currentState = GameState.Move; return true; @@ -191,7 +202,7 @@ namespace Services { this.scoreService.ScoreCheck(gem.ScoreValue); ReleaseMatchedGems(pos); } - + await UniTask.Delay(250); await MoveGemsDown(); } @@ -225,8 +236,6 @@ namespace Services { } private async UniTask MoveGemsDown() { - await UniTask.Delay(50); - int nullCounter = 0; for (int x = 0; x < this.gameBoard.Width; x++) { @@ -247,13 +256,12 @@ namespace Services { nullCounter = 0; } + await UniTask.Delay(600); await FillBoard(); } private async UniTask FillBoard() { - await UniTask.Delay(250); - RefillBoard(); - await UniTask.Delay(600); + await RefillBoard(); this.matchService.FindAllMatches(); if (this.matchService.CurrentMatches.Count > 0) { @@ -262,12 +270,12 @@ namespace Services { // In cascades, there is no "creating slot" bomb protection. await DestroyMatchesAsync(new List()); } else { - await UniTask.Delay(250); this.currentState = GameState.Move; } } - private void RefillBoard() { + private async UniTask RefillBoard() { + List gemsToSpawn = new List(); for (int x = 0; x < this.gameBoard.Width; x++) { for (int y = 0; y < this.gameBoard.Height; y++) @@ -282,11 +290,30 @@ namespace Services { gemToUse = RandomUtils.RandomGemTypeAsInt(); iterations++; } - - SpawnGem(new Vector2Int(x, y), (GemType)gemToUse); + + gemsToSpawn.Add(SetGemAt(new Vector2Int(x,y), (GemType)gemToUse)); } } } + + await SpawnCascade(gemsToSpawn); + } + + private async UniTask SpawnCascade(List gemsToSpawn) + { + List> groups = gemsToSpawn + .GroupBy(gem => gem.Position.y) + .OrderBy(group => group.Key) + .ToList(); + + for (int i = 0; i < groups.Count; i++) + { + foreach (Gem gem in groups[i]) + SpawnGemGameObject(gem); + + if (i < groups.Count - 1) + await UniTask.Delay(150); + } } private void RemovePresenterFor(GemView gemView) { diff --git a/Assets/Scripts/Views/GemView.cs b/Assets/Scripts/Views/GemView.cs index 34da557..329d4e4 100644 --- a/Assets/Scripts/Views/GemView.cs +++ b/Assets/Scripts/Views/GemView.cs @@ -85,15 +85,13 @@ namespace Views { this.transform.localScale = Vector3.one; } - private async UniTask FallDelay() { - float fallDelay = 1 * (this.gem.Position.y / 10f); - await UniTask.WaitForSeconds(fallDelay); + private void FallDelay() { this.isFalling = true; } - public async UniTaskVoid UpdatePosition(Vector2Int positionBasedOnIndex, float gemSpeed) { + public void UpdatePosition(Vector2Int positionBasedOnIndex, float gemSpeed) { if (!this.isFalling) { - await FallDelay(); + FallDelay(); } if (!this.isFalling)