Back to projects
Games

Collapse/Blast Puzzle Game

Level-based mobile blast game built in Unity. (Dream Games case study)

UnityC#

A software engineering case study for Dream Games: build a level-based mobile blast game where tapping a group of 2+ adjacent same-colored cubes clears them, spends one move, and can chain into bigger special-item explosions - all within a fixed move limit per level.

Blast game board mid-level

Finding groups with flood fill

Every tap needs to answer one question fast: what's connected to this cube? BoardManager answers it with a straightforward BFS flood fill over the grid, matching on block type:

private List<int> FloodFill(int startX, int startY, BlockType type, bool[] visited)
{
    List<int> result = new();
    Queue<Vector2Int> queue = new();
    queue.Enqueue(new Vector2Int(startX, startY));
 
    while (queue.Count > 0)
    {
        var c = queue.Dequeue();
        if (!IsValid(c.x, c.y)) continue;
 
        int index = GetIndex(c.x, c.y);
        if (visited[index] || board[index].type != type) continue;
 
        visited[index] = true;
        result.Add(index);
 
        queue.Enqueue(new Vector2Int(c.x + 1, c.y));
        queue.Enqueue(new Vector2Int(c.x - 1, c.y));
        queue.Enqueue(new Vector2Int(c.x, c.y + 1));
        queue.Enqueue(new Vector2Int(c.x, c.y - 1));
    }
 
    return result;
}

A second variant, FloodFillMatching, reuses the same BFS shape but matches against a predicate instead of one exact type - that's what gathers an entire connected cluster of different special items (say, a TNT touching two rockets) so a combo can be resolved as one unit instead of item-by-item.

Group size decides what a blast leaves behind: 4-5 cubes fly together into a rocket (random horizontal or vertical), 6 or more collapse into a TNT, anything smaller just clears.

private BlockType GetSpawnType(int groupSize)
{
    if (groupSize >= 6) return BlockType.TNT;
    if (groupSize >= 4)
        return UnityEngine.Random.Range(0, 2) == 0 ? BlockType.RocketH : BlockType.RocketV;
    return BlockType.Empty;
}

Rocket and TNT combo explosion

Obstacles with different rules, one interface

Vases, stones, and chalice boxes all implement the same ObstacleDefinition, but each overrides just enough to get different behavior for free - no special-casing scattered through the board logic. A vase takes 2 hit points and falls with gravity; a stone ignores adjacent blasts entirely and only takes damage from special-item explosions; a chalice box is a static 2x2 with an 11-point life bar - one hit to break its door, then ten more (one per chalice) to clear it:

public class ChaliceDefinition : ObstacleDefinition
{
    public override BlockType Type => BlockType.Chalice;
    public override int MaxLife => 11; // 1 door hit + 10 chalices
    public override bool FallsWithGravity => false;
    public override bool DamagedByAdjacentBlast => true;
    public override GoalType? Goal => GoalType.Chalice;
    public override int GoalContribution => 10;
}

Combo classification follows the same "definition, not conditionals" approach - a connected cluster of specials gets classified by composition (only rockets → a +-shaped double rocket; 2+ TNTs → a 7x7 blast; one TNT plus rockets → a 3x3 array of exploding rockets) via a single ComboResolver.Classify call.

Debug level selection window

Levels as data, not code

All 10 levels are JSON files under Assets/Resources/Levels/ - grid size, move count, and a flat array of starting cell contents ("rand" for random cubes, "s"/"b"/"g" for obstacle codes) - so tuning difficulty never touches game logic. An editor-only Debug → Set Current Level window (backed by LevelProgressWindow.cs) reads and overwrites the persisted progress directly, letting anyone jump to any level - or straight to the "Finished!" state - without playing through the rest.

Result

A polished 10-level game with BFS-driven combo clusters, chained special-item explosions, three obstacle types sharing one extensible definition/view interface, and an editor debug menu for jumping between levels during testing.