2D platformers are the perfect first project in Godot. They teach you movement, physics, animation, and level design — all core skills. Let's build one from scratch.
Project Setup
Create a new Godot project and select the Compatibility renderer for best 2D performance. Our scene structure will be: a World scene containing the Player, a TileMap for level geometry, and collectible items.
# Player.gd
extends CharacterBody2D
@export var speed = 200.0
@export var jump_force = -350.0
var gravity = 980.0
func _physics_process(delta):
# Gravity
if not is_on_floor():
velocity.y += gravity * delta
# Jump
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = jump_force
# Horizontal movement
var direction = Input.get_axis("move_left", "move_right")
velocity.x = direction * speed
move_and_slide()Adding Animations
Use an AnimatedSprite2D node to switch between idle, run, and jump animations based on player state. Connect it to velocity changes for responsive visual feedback.
# Animation logic
func update_animation():
if not is_on_floor():
$AnimatedSprite2D.play("jump")
elif velocity.x != 0:
$AnimatedSprite2D.play("run")
$AnimatedSprite2D.flip_h = velocity.x < 0
else:
$AnimatedSprite2D.play("idle")TileMap Level Design
Add a TileMap node and import a tileset. Paint your level directly in the editor. Enable physics layers on tiles that should be solid. Godot's TileMap system supports multiple layers, auto-tiling rules, and animated tiles.
Collectibles with Signals
# Coin.gd
extends Area2D
signal collected(value)
@export var value = 10
func _on_body_entered(body):
if body.is_in_group("player"):
collected.emit(value)
queue_free()This pattern — Area2D detecting body entry, emitting a signal, then removing itself — is the foundation for pickups, checkpoints, hazards, and triggers throughout your game.
