Separate SetGem and SpawnGemGameObject

This commit is contained in:
2025-12-18 00:21:44 +08:00
parent 9b6d2369c6
commit 2bd94c8df9
3 changed files with 60 additions and 35 deletions

View File

@@ -64,5 +64,5 @@ MonoBehaviour:
bombDelay: 2 bombDelay: 2
bombRadius: 2 bombRadius: 2
dropHeight: 2 dropHeight: 2
gemSpeed: 0.00625 gemSpeed: 4
scoreSpeed: 3 scoreSpeed: 3

View File

@@ -9,6 +9,7 @@ using ScriptableObjects;
using Services.Interfaces; using Services.Interfaces;
using Structs; using Structs;
using UnityEngine; using UnityEngine;
using UnityEngine.UIElements;
using Utils; using Utils;
using VContainer.Unity; using VContainer.Unity;
using Views; using Views;
@@ -72,6 +73,7 @@ namespace Services {
//Instantiates background tiles and calls SpawnGems //Instantiates background tiles and calls SpawnGems
//Uses MatchService.MatchesAt to avoid matching Gems //Uses MatchService.MatchesAt to avoid matching Gems
public void Setup() { public void Setup() {
List<Gem> gemsToSpawn = new List<Gem>();
for (int x = 0; x < this.gameBoard.Width; x++) for (int x = 0; x < this.gameBoard.Width; x++)
for (int y = 0; y < this.gameBoard.Height; y++) for (int y = 0; y < this.gameBoard.Height; y++)
{ {
@@ -85,35 +87,44 @@ namespace Services {
iterations++; iterations++;
} while (this.matchService.MatchesAt(position.ToVector2Int(), (GemType)gemToUse) && iterations < 100); } 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; 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) { private void SpawnBackgroundTile(Vector2 position) {
GameObject backgroundTile = Object.Instantiate(this.gameVariables.bgTilePrefabs, position, Quaternion.identity); GameObject backgroundTile = Object.Instantiate(this.gameVariables.bgTilePrefabs, position, Quaternion.identity);
backgroundTile.transform.SetParent(this.backgroundHolder); backgroundTile.transform.SetParent(this.backgroundHolder);
backgroundTile.name = "BG Tile - " + position.x + ", " + position.y; 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 //Listens to InputService OnSwapRequest
public async UniTask<bool> TrySwap(Vector2Int from, Vector2Int to) { public async UniTask<bool> TrySwap(Vector2Int from, Vector2Int to) {
if (this.currentState != GameState.Move) if (this.currentState != GameState.Move)
@@ -141,7 +152,7 @@ namespace Services {
return false; return false;
} }
List<Vector2Int> protectedPositions = this.bombService.ApplyPendingBombSpawns(SpawnGem); List<Vector2Int> protectedPositions = this.bombService.ApplyPendingBombSpawns(SetAndSpawnGem);
await DestroyMatchesAsync(protectedPositions); await DestroyMatchesAsync(protectedPositions);
this.currentState = GameState.Move; this.currentState = GameState.Move;
return true; return true;
@@ -191,7 +202,7 @@ namespace Services {
this.scoreService.ScoreCheck(gem.ScoreValue); this.scoreService.ScoreCheck(gem.ScoreValue);
ReleaseMatchedGems(pos); ReleaseMatchedGems(pos);
} }
await UniTask.Delay(250);
await MoveGemsDown(); await MoveGemsDown();
} }
@@ -225,8 +236,6 @@ namespace Services {
} }
private async UniTask MoveGemsDown() { private async UniTask MoveGemsDown() {
await UniTask.Delay(50);
int nullCounter = 0; int nullCounter = 0;
for (int x = 0; x < this.gameBoard.Width; x++) for (int x = 0; x < this.gameBoard.Width; x++)
{ {
@@ -247,13 +256,12 @@ namespace Services {
nullCounter = 0; nullCounter = 0;
} }
await UniTask.Delay(600);
await FillBoard(); await FillBoard();
} }
private async UniTask FillBoard() { private async UniTask FillBoard() {
await UniTask.Delay(250); await RefillBoard();
RefillBoard();
await UniTask.Delay(600);
this.matchService.FindAllMatches(); this.matchService.FindAllMatches();
if (this.matchService.CurrentMatches.Count > 0) { if (this.matchService.CurrentMatches.Count > 0) {
@@ -262,12 +270,12 @@ namespace Services {
// In cascades, there is no "creating slot" bomb protection. // In cascades, there is no "creating slot" bomb protection.
await DestroyMatchesAsync(new List<Vector2Int>()); await DestroyMatchesAsync(new List<Vector2Int>());
} else { } else {
await UniTask.Delay(250);
this.currentState = GameState.Move; this.currentState = GameState.Move;
} }
} }
private void RefillBoard() { private async UniTask RefillBoard() {
List<Gem> gemsToSpawn = new List<Gem>();
for (int x = 0; x < this.gameBoard.Width; x++) for (int x = 0; x < this.gameBoard.Width; x++)
{ {
for (int y = 0; y < this.gameBoard.Height; y++) for (int y = 0; y < this.gameBoard.Height; y++)
@@ -283,10 +291,29 @@ namespace Services {
iterations++; 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<Gem> gemsToSpawn)
{
List<IGrouping<int, Gem>> 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) { private void RemovePresenterFor(GemView gemView) {

View File

@@ -85,15 +85,13 @@ namespace Views {
this.transform.localScale = Vector3.one; this.transform.localScale = Vector3.one;
} }
private async UniTask FallDelay() { private void FallDelay() {
float fallDelay = 1 * (this.gem.Position.y / 10f);
await UniTask.WaitForSeconds(fallDelay);
this.isFalling = true; this.isFalling = true;
} }
public async UniTaskVoid UpdatePosition(Vector2Int positionBasedOnIndex, float gemSpeed) { public void UpdatePosition(Vector2Int positionBasedOnIndex, float gemSpeed) {
if (!this.isFalling) { if (!this.isFalling) {
await FallDelay(); FallDelay();
} }
if (!this.isFalling) if (!this.isFalling)