From 8466b5c6dcdd084ba001bec89654a8b9b4b3da6b Mon Sep 17 00:00:00 2001 From: karl Date: Sun, 21 Nov 2021 12:52:19 +0100 Subject: [PATCH] Improved collision and line removal --- GameBoard.gd | 60 +++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 12 deletions(-) diff --git a/GameBoard.gd b/GameBoard.gd index 96c59f9..1223daa 100644 --- a/GameBoard.gd +++ b/GameBoard.gd @@ -15,6 +15,9 @@ var active_shape: TetrisShape const RASTER_SIZE = 64 const BOTTOM = RASTER_SIZE * 10 +const SPAWN = -RASTER_SIZE * 7 +const LEFT = -RASTER_SIZE * 5 +const RIGHT = RASTER_SIZE * 5 func _ready(): @@ -26,6 +29,7 @@ func _ready(): func get_random_shape(): var new_shape = shapes[randi() % shapes.size()].instance() add_child(new_shape) + new_shape.position.y = SPAWN return new_shape @@ -44,14 +48,32 @@ func move_active_down(): func can_active_move_down(): - if active_shape.position.y >= BOTTOM: - return false - + return _can_active_move_towards(Vector2(0.0, RASTER_SIZE)) + + +func can_active_move_left(): + return _can_active_move_towards(Vector2(-RASTER_SIZE, 0.0)) + + +func can_active_move_right(): + return _can_active_move_towards(Vector2(RASTER_SIZE, 0.0)) + + +func _can_active_move_towards(diff: Vector2): for block in active_shape.get_blocks(): - var down_x = block.global_position.x - var down_y = block.global_position.y + RASTER_SIZE + var new_x = block.global_position.x + diff.x + var new_y = block.global_position.y + diff.y - if is_block_at_position(down_x, down_y): + var global_bottom = to_global(Vector2(0.0, BOTTOM)).y + var global_left = to_global(Vector2(LEFT, 0.0)).x + var global_right = to_global(Vector2(RIGHT, 0.0)).x + + if new_x <= global_left \ + or new_x >= global_right \ + or new_y >= global_bottom: + return false + + if is_block_at_position(new_x, new_y): return false return true @@ -70,11 +92,16 @@ func turn_active_into_static(): func check_for_full_line(): var line_counts = {} # Maps a y position to a count + # Count how many blocks we have in each line (with at least 1 block) for block in $StaticBlocks.get_children(): if not line_counts.has(block.position.y): line_counts[block.position.y] = 0 line_counts[block.position.y] += 1 + # Remember which blocks we need to move down later (we can't apply this immediately because that + # would mess with comparisons to the line_counts + var pending_position_diffs = {} + for line_count_y in line_counts.keys(): if line_counts[line_count_y] == 10: # Free this line @@ -82,18 +109,27 @@ func check_for_full_line(): if line_block.position.y == line_count_y: line_block.free() elif line_block.position.y < line_count_y: - # Move higher-up blocks down - line_block.position.y += RASTER_SIZE + # If this block is above the line currently being freed, remember to move down + # by one raster cell + if not pending_position_diffs.has(line_block): + pending_position_diffs[line_block] = 0 + pending_position_diffs[line_block] += RASTER_SIZE + + # Apply the pending downward movements, but only if the block hasn't been freed (because that + # line was above, but also full) + for block in pending_position_diffs.keys(): + if is_instance_valid(block): + block.position.y += pending_position_diffs[block] func move_left(): - # TODO: Check for collision - active_shape.position.x -= RASTER_SIZE + if can_active_move_left(): + active_shape.position.x -= RASTER_SIZE func move_right(): - # TODO: Check for collision - active_shape.position.x += RASTER_SIZE + if can_active_move_right(): + active_shape.position.x += RASTER_SIZE func rotate_shape():