Ficha 01 · Godot fundamentos
Exercício 1 · Setup e primeira cena
Cria projecto Godot 4 "MeuPrimeiroJogo". Adiciona uma cena com Node2D + Label que diz "Olá mundo!". Corre (F5) e tira screenshot.
Resposta:
Passos:
1. Abrir Godot, criar novo projecto.
2. New Scene → 2D Scene (cria Node2D root).
3. Add Child Node → Label.
4. No inspector: Text = "Olá mundo!", Font Size = 64.
5. Posicionar no centro (Position 400, 300).
6. Save scene como main.tscn.
7. F5 → escolher main.tscn como cena principal.
Screenshot deve mostrar texto "Olá mundo!" centrado.
Exercício 2 · Sprite + movimento básico
Cria cena com Sprite2D (importa qualquer imagem PNG). Atribui script ao Sprite e mexe-o 100 pixels para a direita por segundo usando _process.
Resposta:
extends Sprite2D
func _process(delta):
position.x += 100 * delta
delta = segundos desde último frame. Multiplica por velocidade → movimento independente de framerate.
Exercício 3 · Player com input
Modifica o exercício anterior para o sprite mover-se com setas ou WASD. Usa Input.get_vector() e velocidade de 200 px/s.
Resposta:
extends Sprite2D
const SPEED = 200
func _process(delta):
var input_dir = Input.get_vector(
"ui_left", "ui_right", "ui_up", "ui_down")
position += input_dir * SPEED * delta
ui_left, ui_right, etc. já têm as setas mapeadas por defeito. Para adicionar WASD: Project → Project Settings → Input Map.
Exercício 4 · CharacterBody2D + colisão
Cria scene "Player.tscn" com CharacterBody2D + Sprite2D + CollisionShape2D (RectangleShape2D). Adiciona scene "World.tscn" com StaticBody2D + CollisionShape2D para chão. Player deve cair com gravidade e parar no chão.
Resposta:
player.gd:
extends CharacterBody2D
const SPEED = 300
const JUMP_VELOCITY = -400
const GRAVITY = 980
func _physics_process(delta):
if not is_on_floor():
velocity.y += GRAVITY * delta
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
velocity.y = JUMP_VELOCITY
var dir = Input.get_axis("ui_left", "ui_right")
if dir:
velocity.x = dir * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
move_and_slide()
Estrutura:
- World.tscn: Node2D root + StaticBody2D (chão) + Player instanciado.
Exercício 5 · Coin coletável (Area2D)
Cria scene "Coin.tscn" com Area2D + Sprite2D + CollisionShape2D. Quando o Player entra, a coin desaparece e imprime no console "Coin!".
Resposta:
coin.gd:
extends Area2D
func _ready():
body_entered.connect(_on_body_entered)
func _on_body_entered(body):
if body.name == "Player":
print("Coin!")
queue_free()
Ou via signal connection no editor (Inspector → Node → Signals → body_entered → conectar a self).
Exercício 6 · Score com Autoload
Cria singleton game.gd (autoload) com var score = 0. Quando uma Coin é apanhada, incrementa score em 10 e imprime o novo valor.
Resposta:
game.gd:
extends Node
var score = 0
Project → Project Settings → Autoload:
- Path: res://game.gd
- Name: Game
- Enabled: ✓
coin.gd:
extends Area2D
func _on_body_entered(body):
if body.name == "Player":
Game.score += 10
print("Score: ", Game.score)
queue_free()
Exercício 7 · UI com Label
Adiciona CanvasLayer + Label "ScoreLabel" à World scene. Atualiza o texto sempre que o score muda usando um signal.
Resposta:
game.gd (autoload):
extends Node
signal score_mudou(novo)
var score = 0:
set(value):
score = value
score_mudou.emit(value)
Estrutura world:
World
├── ... (player, coins, etc.)
└── UI (CanvasLayer)
└── ScoreLabel (Label)
UI.gd:
extends CanvasLayer
@onready var label = $ScoreLabel
func _ready():
label.text = "Score: 0"
Game.score_mudou.connect(_atualizar)
func _atualizar(novo):
label.text = "Score: " + str(novo)
Exercício 8 · AnimatedSprite2D
Substitui o Sprite2D do Player por AnimatedSprite2D. Cria 2 animações: "idle" (parado) e "run" (a andar). Toca a animação correcta consoante o movimento. Faz flip_h quando vira para a esquerda.
Resposta:
- Apagar Sprite2D, adicionar AnimatedSprite2D.
- No Inspector → Sprite Frames → New SpriteFrames.
- Clica no recurso → painel inferior abre.
- Adicionar animações "idle" e "run". Adicionar frames (drag images ou spritesheet).
player.gd:
extends CharacterBody2D
const SPEED = 300
const JUMP_VELOCITY = -400
const GRAVITY = 980
@onready var sprite = $AnimatedSprite2D
func _physics_process(delta):
if not is_on_floor():
velocity.y += GRAVITY * delta
if Input.is_action_just_pressed("ui_accept") and is_on_floor():
velocity.y = JUMP_VELOCITY
var dir = Input.get_axis("ui_left", "ui_right")
if dir:
velocity.x = dir * SPEED
sprite.flip_h = dir < 0
sprite.play("run")
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
sprite.play("idle")
move_and_slide()
Recurso gratuito para sprites: Kenney.nl ou OpenGameArt.