Exercise Overview
These exercises will help you practice the concepts learned in Part 1. Start with the easy exercises and work your way up to the more challenging ones.
Easy Exercises
Create Your First Scene
Objective
Create a simple scene with basic nodes to understand GoDot's scene system.
Tasks
- Create a new GoDot project
- Add a Node2D as the root node
- Add a Sprite2D as a child node
- Add a Label as another child node
- Save the scene as "MyFirstScene.tscn"
Expected Outcome
You should have a scene with a tree structure: Node2D → Sprite2D and Label as children.
Tips
- Use Scene → New Scene to create a new scene
- Right-click in the Scene tab to add child nodes
- Use Ctrl+S to save your scene
Basic Node Properties
Objective
Learn to modify node properties using the Inspector panel.
Tasks
- Select the Sprite2D node in your scene
- In the Inspector, change the position to (100, 100)
- Change the scale to (2.0, 2.0)
- Change the rotation to 45 degrees
- Select the Label node and change its text to "Hello GoDot!"
Expected Outcome
The sprite should be larger, positioned at (100,100), rotated 45 degrees, and the label should display "Hello GoDot!".
Tips
- Click on nodes in the Scene tab to select them
- Use the Inspector panel on the right to modify properties
- You can type values directly or use the sliders
Simple Script
Objective
Create your first GDScript and attach it to a node.
Tasks
- Select the Node2D root node
- Attach a new script to it
- Add a simple print statement in the _ready() function
- Run the scene and check the output
Code Example
extends Node2D
func _ready():
print("Hello from GoDot!")
print("My first script is working!")
Expected Outcome
When you run the scene (F5), you should see the print statements in the Output panel.
Tips
- Right-click the node and select "Attach Script"
- Choose GDScript as the language
- Use F5 to run the scene
- Check the Output panel at the bottom for print statements
Medium Exercises
Interactive Scene
Objective
Create a scene with multiple nodes and basic interaction.
Tasks
- Create a new scene with Node2D as root
- Add three Sprite2D nodes as children
- Position them at different locations
- Add a script to the root node
- Make the sprites change color when clicked
Code Example
extends Node2D
func _ready():
# Connect input events to all sprites
for sprite in get_children():
if sprite is Sprite2D:
sprite.input_event.connect(_on_sprite_clicked)
func _on_sprite_clicked(viewport, event, shape_idx):
if event is InputEventMouseButton and event.pressed:
# Change color to random color
var sprite = event.target
sprite.modulate = Color(randf(), randf(), randf())
Expected Outcome
Clicking on any sprite should change its color to a random color.
Tips
- Use the connect() function to handle input events
- randf() generates random float values between 0 and 1
- Make sure sprites have collision shapes for input detection
Moving Object
Objective
Create a script that moves an object using keyboard input.
Tasks
- Create a scene with a Sprite2D
- Attach a script to the Sprite2D
- Implement movement using arrow keys
- Add boundary checking to keep the sprite on screen
- Add a speed variable that can be adjusted
Code Example
extends Sprite2D
var speed = 200
var screen_size
func _ready():
screen_size = get_viewport_rect().size
func _process(delta):
var velocity = Vector2.ZERO
if Input.is_action_pressed("ui_right"):
velocity.x += 1
if Input.is_action_pressed("ui_left"):
velocity.x -= 1
if Input.is_action_pressed("ui_down"):
velocity.y += 1
if Input.is_action_pressed("ui_up"):
velocity.y -= 1
velocity = velocity.normalized()
position += velocity * speed * delta
# Keep sprite on screen
position = position.clamp(Vector2.ZERO, screen_size)
Expected Outcome
The sprite should move smoothly with arrow keys and stay within the screen boundaries.
Tips
- Use _process(delta) for continuous movement
- normalize() prevents faster diagonal movement
- clamp() keeps the position within bounds
- You can adjust the speed variable in the Inspector
Scene Hierarchy
Objective
Create a complex scene hierarchy and understand parent-child relationships.
Tasks
- Create a scene with this hierarchy:
- Node2D (Root)
- ├── Sprite2D (Player)
- │ ├── Label (PlayerName)
- │ └── Sprite2D (Weapon)
- └── Node2D (Environment)
- ├── Sprite2D (Tree1)
- ├── Sprite2D (Tree2)
- └── Sprite2D (Rock)
- Move the Player node and observe how children move with it
- Move the Environment node and observe how its children move
- Add a script that prints the hierarchy structure
Code Example
extends Node2D
func _ready():
print_hierarchy(self, 0)
func print_hierarchy(node, depth):
var indent = " " * depth
print(indent + "- " + node.name + " (" + node.get_class() + ")")
for child in node.get_children():
print_hierarchy(child, depth + 1)
Expected Outcome
You should see the complete hierarchy printed in the output, and moving parent nodes should move all their children.
Tips
- Use drag and drop in the Scene tab to create hierarchy
- Right-click to rename nodes for clarity
- Moving a parent moves all its children
- get_children() returns an array of child nodes
Hard Exercises
Scene Manager
Objective
Create a scene management system that can switch between different scenes.
Tasks
- Create three different scenes: Menu, Game, and Pause
- Create a main scene that manages these scenes
- Implement scene switching functionality
- Add a simple UI to navigate between scenes
- Handle scene transitions smoothly
Code Example
extends Node
var current_scene = null
var scenes = {
"menu": preload("res://scenes/Menu.tscn"),
"game": preload("res://scenes/Game.tscn"),
"pause": preload("res://scenes/Pause.tscn")
}
func _ready():
current_scene = get_child(0)
switch_scene("menu")
func switch_scene(scene_name):
if scene_name in scenes:
# Remove current scene
if current_scene:
current_scene.queue_free()
# Add new scene
current_scene = scenes[scene_name].instantiate()
add_child(current_scene)
print("Switched to: " + scene_name)
Expected Outcome
You should be able to switch between different scenes using UI buttons or keyboard shortcuts.
Tips
- Use preload() to load scenes at compile time
- instantiate() creates an instance of the scene
- queue_free() safely removes nodes
- Create a simple UI with buttons for scene switching
Node Factory
Objective
Create a system that dynamically creates and manages nodes programmatically.
Tasks
- Create a script that can spawn different types of nodes
- Implement a node pool for efficient memory usage
- Add random positioning for spawned nodes
- Create a cleanup system for unused nodes
- Add a UI to control spawning parameters
Code Example
extends Node2D
var node_pool = []
var max_nodes = 50
var spawn_timer = 0
var spawn_interval = 1.0
func _ready():
# Pre-populate pool
for i in range(max_nodes):
var sprite = Sprite2D.new()
sprite.visible = false
add_child(sprite)
node_pool.append(sprite)
func _process(delta):
spawn_timer += delta
if spawn_timer >= spawn_interval:
spawn_timer = 0
spawn_node()
func spawn_node():
if node_pool.size() > 0:
var sprite = node_pool.pop_back()
sprite.visible = true
sprite.position = Vector2(randf_range(0, 800), randf_range(0, 600))
sprite.modulate = Color(randf(), randf(), randf())
func cleanup_nodes():
for child in get_children():
if child is Sprite2D and child.visible:
child.visible = false
node_pool.append(child)
Expected Outcome
Nodes should spawn automatically, and you should be able to clean them up efficiently using the pool system.
Tips
- Use a pool to avoid creating/destroying nodes constantly
- randf_range() generates random values within a range
- visible property controls node visibility
- Add UI buttons to control spawning and cleanup