Barrel Blast! 🦍Build Your Own Donkey Kong-Style Game
Dodge rolling barrels, climb ladders, and reach the top to win! You'll build a climbing arcade game just like the original Donkey Kong one of the greatest games ever made!
Dodge rolling barrels, climb ladders, and reach the top to win! You'll build a climbing arcade game just like the original Donkey Kong one of the greatest games ever made!
Understand what we're building and get Godot open and ready!
We're going to make a game like the VERY FIRST arcade games ever made! There's a big gorilla at the top throwing barrels, and your little hero has to dodge them and climb all the way up. It's going to be SO much fun and YOU are going to build it! 🦍🛢️
Episode 5 of My First Video Game. Core new concepts: ladder climbing via Area2D overlap (disabling gravity), barrel spawning using a Timer node, and rolling barrels as CharacterBody2D with constant horizontal velocity that flips on collision. The girder level is built with StaticBody2D rectangles whichever the child finds easier to paint.
Create a new Godot 4 project called "Barrel Blast" and get it open.
Every game starts the same way with a brand new empty project! It's like opening a fresh box of LEGOs. Let's set ours up so we can start building our arcade game!
Standard Godot 4 new project. Compatibility renderer, Desktop platform. This time we'll set the window size to 480×640 in Project Settings to give a tall arcade-style aspect ratio — optional but fun.
Create a Hero scene with running, jumping, and gravity just like Jump Jump!
Remember Jump Jump? We're going to build a character the same way a CharacterBody2D who can run and jump. If you did Jump Jump already, this will feel very familiar! If not, don't worry we'll go through it together.
Identical setup to Jump Jump: CharacterBody2D → Sprite2D + CollisionShape2D (RectangleShape2D). Add the hero to a "player" group. Gravity constant + jump on ui_accept + horizontal movement with get_axis. Save as hero.tscn. We'll add ladder logic in Step 5.
extends CharacterBody2D const SPEED = 200 const JUMP_FORCE = -440 var gravity = ProjectSettings.get_setting("physics/2d/default_gravity") var on_ladder = false # We'll use this in Step 5! func _physics_process(delta): # Gravity (skip when on a ladder) if not is_on_floor() and not on_ladder: velocity.y += gravity * delta # Jump if Input.is_action_just_pressed("ui_accept") and is_on_floor(): velocity.y = JUMP_FORCE # Left / right var dir = Input.get_axis("ui_left", "ui_right") velocity.x = dir * SPEED move_and_slide()
Create a Main scene with girder platforms the hero can stand and walk on.
In Donkey Kong, the hero walks on these wide metal floors called girders. We're going to build ours! We'll stack them up going from left to right, right to left — like a zig-zag staircase going upward.
Create main.tscn with a Node2D root. Simplest girders: add several StaticBody2D nodes, each with a CollisionShape2D (RectangleShape2D) and a Sprite2D/ColorRect as a visual. Stack 4–5 at different heights, alternating left/right. Instance hero.tscn at the bottom-left. Add a Camera2D as a child of the hero.
Build a Ladder scene when the hero touches it, they can climb up and down!
The most special thing in our game is the LADDERS! When you walk into a ladder and press UP or DOWN, you climb! We're going to turn off gravity while climbing so it's like the ladder is holding you up.
Ladder scene: Area2D → Sprite2D (tall thin rectangle) + CollisionShape2D. In the hero script we detect body_entered/body_exited from the ladder's Area2D. When on_ladder is true, gravity is skipped and vertical velocity comes from ui_up/ui_down. Set the Area2D's collision layer/mask so only the hero detects it.
extends Area2D func _on_body_entered(body): if body.is_in_group("player"): body.on_ladder = true func _on_body_exited(body): if body.is_in_group("player"): body.on_ladder = false body.velocity.y = 0 # Stop carrying momentum off the ladder # --- ADD this inside _physics_process in hero.tscn script --- # (after the gravity block) # if on_ladder: # var climb = Input.get_axis("ui_up", "ui_down") # velocity.y = climb * SPEED * 0.7
Build a Barrel scene that rolls along girders, falls off edges, and disappears at the bottom.
Now for the EXCITING bit the barrels! 🛢️ We're going to make a barrel that rolls across the floor. When it reaches the edge, it falls down to the next girder and keeps rolling. Just like the real Donkey Kong!
Barrel scene: CharacterBody2D → Sprite2D (brown circle) + CollisionShape2D. In the script: constant horizontal velocity, gravity applied, move_and_slide(). When it hits a wall (is_on_wall()) it flips direction this handles the zig-zag layout. Add to "barrel" group. Use queue_free() when it goes below the screen.
extends CharacterBody2D const ROLL_SPEED = 130 var gravity = ProjectSettings.get_setting("physics/2d/default_gravity") var direction = 1 # Start rolling right func _physics_process(delta): # Gravity — barrels fall too! if not is_on_floor(): velocity.y += gravity * delta # Roll sideways velocity.x = direction * ROLL_SPEED move_and_slide() # Flip direction if hitting a wall if is_on_wall(): direction *= -1 # Disappear if it rolls off the bottom of the screen if position.y > 900: queue_free()
Place a Boss character at the top who throws barrels on a timer!
Every great game has a big bad boss! Our gorilla sits at the TOP of all the girders and throws barrels down at us. We're going to use something called a TIMER it tells Godot to throw a new barrel every few seconds. Uh oh!
Boss scene: Node2D → Sprite2D + Timer node. On the Timer's timeout signal, instantiate barrel.tscn at the boss's position and add it to the main scene. Set Timer wait_time to 2.5s, autostart true. @export var barrel_scene: PackedScene lets you assign barrel.tscn in the Inspector.
extends Node2D @export var barrel_scene: PackedScene func _on_timer_timeout(): if barrel_scene: var barrel = barrel_scene.instantiate() # Spawn barrel at the boss's feet barrel.global_position = global_position + Vector2(0, 40) # Add to the main scene so it interacts with everything get_parent().add_child(barrel)
Make the hero die (or lose a life) when a barrel touches them.
What happens when a barrel rolls into our hero? Right now nothing! We need to fix that. When a barrel touches the hero, we'll show a "Game Over" message. Watch out for those barrels! 🛢️💨
Add an Area2D to the Hero (HitBox) to detect overlaps with the "barrel" group. On collision, show a CanvasLayer "Game Over" label and call reload_current_scene() after a short delay. Or track lives (start at 3) for a friendlier feel.
await get_tree().create_timer(1.5).timeout achieves this neatly.# ADD to hero.tscn script: @export var game_over_label: Label var dead = false func _on_hit_box_body_entered(body): if body.is_in_group("barrel") and not dead: dead = true game_over_label.show() # Wait a moment then restart! await get_tree().create_timer(1.5).timeout get_tree().reload_current_scene()
Place a goal at the top of the level touch it to win!
Our game needs a way to WIN! We're going to put a big shiny prize at the top of all the girders. If you can dodge all those barrels and climb all the way up YOU WIN! 🌟
Reuse the Flag/Goal pattern: Area2D → Sprite2D (star/trophy) + CollisionShape2D. On body_entered with "player" group, show a "You Win! 🎉" CanvasLayer label. Optional: a 2s timer then load the next scene or celebrate.
extends Area2D @export var win_label: Label func _on_body_entered(body): if body.is_in_group("player"): win_label.show()
Show a score on screen that counts up every second the hero is alive.
Real arcade games always have a score! Ours is going to count UP every second you're alive and dodging barrels. The longer you survive, the higher your score can you beat your own record? 🏅
Add a CanvasLayer → Label to main.tscn for the HUD. In the main script, accumulate delta in _process and increment score each second, updating the label text. A simple int score variable in main.gd keeps things clean.
extends Node2D var score = 0 var time_passed = 0.0 @onready var score_label = $CanvasLayer/ScoreLabel func _process(delta): time_passed += delta if time_passed >= 1.0: time_passed = 0.0 score += 10 score_label.text = "Score: " + str(score)
Make barrels roll faster and spawn more often as the score goes up.
Right now the barrels always go the same speed. But in real arcade games they get FASTER! We're going to make it so the longer you play, the more barrels there are and the quicker they go. Uh oh! 😬
Two changes: (1) In main.gd, as score increases, shorten the Boss's Timer wait_time. (2) Pass a speed multiplier to each barrel on instantiation. Every 50 points, reduce wait_time by 0.2s (min 0.8s) and increase ROLL_SPEED. Cap it so it stays playable!
# In boss.tscn script modify _on_timer_timeout: var speed_boost = 1.0 # We'll increase this over time func _on_timer_timeout(): if barrel_scene: var barrel = barrel_scene.instantiate() barrel.global_position = global_position + Vector2(0, 40) barrel.speed_boost = speed_boost # Pass boost to barrel! get_parent().add_child(barrel) # In barrel.tscn script — add this variable and use it: var speed_boost = 1.0 # Change the roll line to: # velocity.x = direction * ROLL_SPEED * speed_boost # In main.gd — call this when score goes up: func update_difficulty(): var boss = $Boss boss.speed_boost = 1.0 + (score / 100.0) boss.$Timer.wait_time = max(0.8, 2.5 - (score / 200.0))
Customise everything characters, colours, level layout, and your own creative twist!
THIS IS THE BEST STEP! 🎉 Your game already works. It's a REAL arcade game! Now make it completely YOURS. Give the hero a name. Make the gorilla purple. Design a wild level with tons of ladders. Add more floors! You made this you're an arcade game developer! 🕹️
Great stretch goals: animate the hero flipping with scale.x; add a high score saved with FileAccess; add sound effects with AudioStreamPlayer; add a faster second barrel type; add a lives system (3 hearts in a CanvasLayer); or add a second level using change_scene_to_file().
A climbing arcade game inspired by the original Donkey Kong! Your hero climbs girder platforms and ladders, dodges barrels rolling down from the top, and reaches the goal to win.
Have you ever seen old arcade games? Donkey Kong was one of the very FIRST! A big gorilla at the top throws barrels and your little hero has to dodge them and climb up. We're going to make our own version with our own characters!
This is Episode 3 of My First Video Game. It builds on Jump Jump's gravity and CharacterBody2D patterns, adding new concepts: ladder climbing (disabling gravity on overlap), AnimatableBody2D for rolling barrels, a Timer node for barrel spawning, and a simple thrower AI. No prior episodes required.
🛠️ Free In-House Dev Tools
Use these free browser tools alongside this workshop to create custom sprites, sounds, levels and colour schemes for your game. No installs. Free forever.