95 lines
2.7 KiB
GDScript
95 lines
2.7 KiB
GDScript
extends TileMapLayer
|
|
|
|
# Detect and make tiles fall
|
|
func detect_and_make_tiles_fall():
|
|
var all_tiles = get_used_cells()
|
|
var grounded_tiles = get_grounded_tiles()
|
|
print("Grounded tiles:", grounded_tiles)
|
|
|
|
var floating_tiles = []
|
|
for tile in all_tiles:
|
|
if tile not in grounded_tiles:
|
|
floating_tiles.append(tile)
|
|
|
|
print("Floating tiles:", floating_tiles)
|
|
|
|
for tile_pos in floating_tiles:
|
|
make_tile_fall(tile_pos)
|
|
|
|
# Returns all the grounded tiles (tiles connected to the bottom-most tiles)
|
|
func get_grounded_tiles() -> Array:
|
|
var grounded_tiles = []
|
|
var bottom_y = get_bottom_y() # Identify the bottom-most y coordinate
|
|
print("Bottom y:", bottom_y)
|
|
|
|
# Get all tiles at the bottom-most y-coordinate
|
|
var bottom_tiles = []
|
|
for tile in get_used_cells():
|
|
if tile.y == bottom_y:
|
|
bottom_tiles.append(tile)
|
|
|
|
print("Bottom tiles:", bottom_tiles)
|
|
|
|
# Traverse all tiles connected to the bottom-most tiles (iteratively)
|
|
var visited = {} # Dictionary to track visited tiles
|
|
var queue = bottom_tiles.duplicate() # Initialize the queue with bottom-most tiles
|
|
|
|
while queue.size() > 0:
|
|
var current = queue.pop_front() # Get the next tile to process
|
|
|
|
# Skip if already visited
|
|
if visited.has(current):
|
|
continue
|
|
|
|
visited[current] = true # Mark as visited
|
|
grounded_tiles.append(current) # Add to grounded tiles
|
|
|
|
# Check neighboring tiles (up, down, left, right)
|
|
var neighbors = [
|
|
current + Vector2i(1, 0), # Right
|
|
current + Vector2i(-1, 0), # Left
|
|
current + Vector2i(0, 1), # Down (already checked for bottom-most)
|
|
current + Vector2i(0, -1) # Up
|
|
]
|
|
|
|
for neighbor in neighbors:
|
|
if has_tile(neighbor) and not visited.has(neighbor):
|
|
queue.append(neighbor) # Add unvisited neighboring tile to the queue
|
|
|
|
return grounded_tiles
|
|
|
|
|
|
# Function to get the lowest y-coordinate of tiles in the map
|
|
func get_bottom_y() -> int:
|
|
var bottom_y = -1
|
|
|
|
for tile in get_used_cells():
|
|
if tile.y > bottom_y:
|
|
bottom_y = tile.y # Keep track of the largest y value (lowest tile)
|
|
|
|
return bottom_y
|
|
|
|
|
|
# Check if a specific tile exists at the given coordinates
|
|
func has_tile(coords: Vector2i) -> bool:
|
|
return get_cell_source_id(coords) != -1
|
|
|
|
|
|
|
|
# Make a tile fall by erasing it and placing it below
|
|
func make_tile_fall(coords: Vector2i) -> void:
|
|
var source_id = get_cell_source_id(coords) # Get the source ID of the tile
|
|
var atlas_coords = get_cell_atlas_coords(coords) # Get the atlas coordinates
|
|
var below_coords = coords + Vector2i(0, 1) # Position where the tile will fall
|
|
|
|
# Erase the current tile
|
|
erase_cell(coords)
|
|
|
|
# Place the tile one step below
|
|
#set_cell(below_coords, source_id, atlas_coords)
|
|
|
|
|
|
func _ready():
|
|
# Automatically call the function to test it when the scene runs
|
|
detect_and_make_tiles_fall()
|