Lesson 13
The finish line. We add a couple of sound effects, a pause toggle, and export a real build. By the end you have a complete, shippable GridFall.
.wav or .ogg files into the project (a soft 'thud' for lock, a brighter 'ding' for clear). You can grab free CC0 sounds or generate simple ones — any short clip works.main.tscn, under Main, add two AudioStreamPlayer nodes named LockSound and ClearSound.@onready var lock_sound: AudioStreamPlayer = $LockSound
@onready var clear_sound: AudioStreamPlayer = $ClearSound
# call lock_sound.play() at the end of _lock_piece(), before spawn_piece():
# ... board writes ...
# lock_sound.play()
# if cleared > 0:
# _award_score(cleared)
# clear_sound.play()Concretely, update _lock_piece():
func _lock_piece() -> void:
for cell in active_piece.get_cells():
board.set_cell(cell.x, cell.y, active_piece.color_id)
active_piece.queue_free()
active_piece = null
lock_sound.play()
var cleared: int = board.clear_full_rows()
if cleared > 0:
_award_score(cleared)
clear_sound.play()
_render_board()
spawn_piece()Guard against missing streams
If an AudioStreamPlayer has no stream assigned, play() does nothing harmful but logs a warning. Make sure each has a file in its Stream slot, or wrap calls in if lock_sound.stream:.
pause bound to Esc or P.Godot has a built-in pause system. Toggle the SceneTree's paused flag. Add to main.gd:
func _input(event: InputEvent) -> void:
if event.is_action_pressed("pause"):
get_tree().paused = not get_tree().paused
return
if active_piece == null or game_over:
return
if event.is_action_pressed("hard_drop"):
_hard_drop()
elif event.is_action_pressed("rotate_cw"):
_try_rotate()Pause needs a process mode
By default a paused tree freezes every node — including the one reading the pause key. Select Main in the Inspector, find Process → Mode, and set it to Always so Main keeps listening for the unpause key while everything else is frozen.
index.html plus support files can be hosted anywhere (including TeqStudy).Android target
GridFall's touch-friendliness aside, exporting to Android needs the Android SDK + a debug keystore configured in Editor Settings. That's a larger setup covered by Godot's export docs; desktop and web work out of the box.
You built a complete game
Spawning, gravity, input, rotation with kicks, line clears, scoring, escalation, game over, HUD, preview, juice, sound, pause, and an export. That's GridFall — a full, shippable 2D game built entirely by example.
Checkpoint — expected state