extends Node2D const GRID_SIZE := Vector2i(8, 8) const TILE_TYPES := 5 const TILE_SCENE := preload("res://scenes/match3/tile.tscn") var grid := [] func _ready(): _initialize_grid() func _initialize_grid(): for y in range(GRID_SIZE.y): grid.append([]) for x in range(GRID_SIZE.x): var tile = TILE_SCENE.instantiate() tile.position = Vector2(x, y) * 64 # Adjust to your tile size tile.grid_position = Vector2i(x, y) tile.tile_type = randi() % TILE_TYPES add_child(tile) grid[y].append(tile) func _has_match_at(pos: Vector2i) -> bool: var matches_horizontal = _get_match_line(pos, Vector2i(1, 0)) if matches_horizontal.size() >= 3: return true var matches_vertical = _get_match_line(pos, Vector2i(0, 1)) return matches_vertical.size() >= 3 func _get_match_line(start: Vector2i, dir: Vector2i) -> Array: var line = [grid[start.y][start.x]] var type = grid[start.y][start.x].tile_type for offset in [1, -1]: var current = start + dir * offset while current.x >= 0 and current.y >= 0 and current.x < GRID_SIZE.x and current.y < GRID_SIZE.y: var neighbor = grid[current.y][current.x] if neighbor.tile_type != type: break line.append(neighbor) current += dir * offset return line func _clear_matches(): var to_clear := [] for y in range(GRID_SIZE.y): for x in range(GRID_SIZE.x): var pos = Vector2i(x, y) var horiz = _get_match_line(pos, Vector2i(1, 0)) if horiz.size() >= 3: to_clear.append_array(horiz) var vert = _get_match_line(pos, Vector2i(0, 1)) if vert.size() >= 3: to_clear.append_array(vert) # Remove duplicates using dictionary keys trick var unique_dict := {} for tile in to_clear: unique_dict[tile] = true to_clear = unique_dict.keys() for tile in to_clear: grid[tile.grid_position.y][tile.grid_position.x] = null tile.queue_free() _drop_tiles() await get_tree().create_timer(0.2).timeout _fill_empty_cells() func _drop_tiles(): var moved = true while moved: moved = false for x in range(GRID_SIZE.x): for y in range(GRID_SIZE.y - 2, -1, -1): var tile = grid[y][x] if tile and not grid[y + 1][x]: grid[y + 1][x] = tile grid[y][x] = null tile.grid_position = Vector2i(x, y + 1) # You can animate position here using Tween for smooth drop: # tween.interpolate_property(tile, "position", tile.position, Vector2(x, y + 1) * 64, 0.2) tile.position = Vector2(x, y + 1) * 64 moved = true func _fill_empty_cells(): for y in range(GRID_SIZE.y): for x in range(GRID_SIZE.x): if not grid[y][x]: var tile = TILE_SCENE.instantiate() tile.grid_position = Vector2i(x, y) tile.tile_type = randi() % TILE_TYPES tile.position = Vector2(x, y) * 64 grid[y][x] = tile add_child(tile) # Recheck matches await get_tree().create_timer(0.1).timeout _clear_matches()