Separate Bomb Logic

This commit is contained in:
2025-12-15 04:55:05 +08:00
parent f4a2cac16d
commit 5f0af52710
3 changed files with 24 additions and 48 deletions

View File

@@ -16,13 +16,8 @@ namespace Services
{
if (matchPositions == null || matchPositions.Count == 0)
return Array.Empty<Vector2Int>();
// Activation: any match cell that is a bomb OR cardinal-adjacent to a bomb.
// NOTE: The actual "is bomb?" check depends on the board, so we only return
// the positions to be checked/queued by caller if desired.
// To keep BombService isolated, well let DetonateChainAsync validate bombs via getGemAt.
// Here we return: all matched positions + their cardinal neighbors.
HashSet<Vector2Int> candidates = new HashSet<Vector2Int>(matchPositions);
HashSet<Vector2Int> candidates = new HashSet<Vector2Int>();
foreach (Vector2Int p in matchPositions)
{
@@ -65,13 +60,11 @@ namespace Services
processed.Add(bombPos);
// Delay before neighbor blast
int neighborDelayMs = Mathf.Max(0, Mathf.RoundToInt(bombDelaySeconds * 1000f));
if (neighborDelayMs > 0)
await UniTask.Delay(neighborDelayMs);
// Blast neighbors first (cross)
foreach (Vector2Int n in CrossNeighbors(bombPos, radius))
foreach (Vector2Int n in DiamondNeighbors(bombPos, radius))
{
if (!inBounds(n))
continue;
@@ -80,7 +73,6 @@ namespace Services
if (g == null)
continue;
// Chain: if another bomb is in blast area, queue it
if (g.Type == GemType.Bomb)
{
if (!processed.Contains(n))
@@ -91,26 +83,28 @@ namespace Services
await destroyAtAsync(n);
}
// Delay before destroying the bomb itself
int selfDelayMs = Mathf.Max(0, Mathf.RoundToInt(bombSelfDelaySeconds * 1000f));
if (selfDelayMs > 0)
await UniTask.Delay(selfDelayMs);
// Destroy bomb last
Gem stillBomb = getGemAt(bombPos);
if (stillBomb is { Type: GemType.Bomb })
await destroyAtAsync(bombPos);
}
}
private static IEnumerable<Vector2Int> CrossNeighbors(Vector2Int center, int radius)
private static IEnumerable<Vector2Int> DiamondNeighbors(Vector2Int center, int radius)
{
for (int i = 1; i <= radius; i++)
for (int x = -radius; x <= radius; x++)
{
yield return center + Vector2Int.left * i;
yield return center + Vector2Int.right * i;
yield return center + Vector2Int.up * i;
yield return center + Vector2Int.down * i;
int maxY = radius - Mathf.Abs(x);
for (int y = -maxY; y <= maxY; y++)
{
if (x == 0 && y == 0)
continue;
yield return new Vector2Int(center.x + x, center.y + y);
}
}
}
}