A simple low-poly character in a grey room, on a monitor at a desk
|

Godot 4.x Beginner Tutorial – Full Game in One Hour

Build a tiny 2D platformer in Godot 4 with a CharacterBody2D player, custom input actions, solid platforms, collectibles, and a goal.

A quick word on the “one hour” promise. It assumes Godot 4 is already downloaded, that you use colored rectangles and the default Godot icon for art, and that you build one small level. Drawing real art or adding more levels will take longer. The goal today is a complete loop, not a polished game.

By the end, you will have a player that runs and jumps, platforms it can stand on, coins that disappear when touched, and a goal that restarts the level when you reach it.

Step 1: Create the project

Get Godot 4 from the official Godot website. On Windows and Linux it runs straight from the extracted download, with no installer.

In the Project Manager, create a new project. Pick an empty folder and give it a name. For the renderer, the default choice is fine for a small 2D game.

When the editor opens, you will see the main viewport in the middle, the Scene dock on the left, the FileSystem dock below it, and the Inspector on the right. The Scene dock shows the tree of nodes in the scene you are editing. The Inspector shows the properties of whatever node you select.

Step 2: Set up the input map

Godot lets you name actions such as “jump” and then attach keys to them. Your code checks the action name, so you can change keys later without touching the script.

  1. Open Project > Project Settings and go to the Input Map tab.
  2. Type move_left in the field at the top and click Add.
  3. Do the same for move_right and jump.
  4. Click the plus icon next to each action and press the key you want: the left arrow or A for move_left, the right arrow or D for move_right, and Space for jump.

Close the settings window.

Step 3: Build the player scene

Making the player its own scene keeps it reusable.

  1. Click Scene > New Scene. Choose Other Node and pick CharacterBody2D. Rename it Player.
  2. With Player selected, add a child node: Sprite2D. In the Inspector, drag icon.svg from the FileSystem dock into its Texture slot. The Godot logo becomes your placeholder character.
  3. Add another child to Player: CollisionShape2D. In the Inspector, set its Shape to a new RectangleShape2D. Drag the orange handles so the box roughly covers the sprite.
  4. Add a Camera2D as a child of Player. Because the camera is a child, it follows the player automatically.

Save the scene as player.tscn.

The node types matter. CharacterBody2D is designed for bodies you move with code, like a player. It handles sliding along floors and walls for you and can tell you when it is standing on the ground.

Step 4: Write the player script

Select the Player node and click the script icon at the top of the Scene dock to attach a new script. Godot may offer a template; choose the empty one so you can type this yourself:

extends CharacterBody2D

const SPEED = 250.0
const JUMP_VELOCITY = -450.0

var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")

func _physics_process(delta):
    # Fall when not standing on something
    if not is_on_floor():
        velocity.y += gravity * delta

    # Jump only from the ground
    if Input.is_action_just_pressed("jump") and is_on_floor():
        velocity.y = JUMP_VELOCITY

    # -1 for left, 1 for right, 0 for neither
    var direction = Input.get_axis("move_left", "move_right")
    velocity.x = direction * SPEED

    move_and_slide()

Here is what is going on.

_physics_process runs at a steady rate, which is where movement belongs. delta is the time since the last physics step, so multiplying gravity by it keeps falling speed consistent.

velocity is a built-in property of CharacterBody2D. You set how fast you want to move, and move_and_slide() does the moving and handles collisions. After it runs, is_on_floor() knows whether the body landed on something.

In Godot’s 2D coordinates, the y-axis points down. That is why the jump velocity is negative.

Input.get_axis reads two actions at once and returns a single number. It saves you from writing two separate checks.

The speed and jump values are starting points. Change them until the movement feels right to you.

Step 5: Build the level

  1. Create a new scene with a Node2D root. Rename it Level and save it as level.tscn.
  2. Drag player.tscn from the FileSystem dock into the viewport to add an instance of your player.

Now add a floor. Each platform uses the same three-node pattern:

  1. Add a StaticBody2D as a child of Level. Rename it Floor.
  2. Give it a CollisionShape2D child with a new RectangleShape2D. Make the shape wide and short.
  3. Give it a ColorRect child so you can see it. Set the ColorRect’s size and position so it covers the collision shape, and pick a color.

StaticBody2D is a body that does not move but blocks other bodies. The player will land on it.

Select Floor, duplicate it a few times, and drag the copies around to make platforms at different heights. Place the player above the floor.

Godot also has a tile-based system for painting levels. It is worth learning next, but rectangles keep this first build fast and easy to debug.

Step 6: Add a collectible

  1. Create a new scene with an Area2D root. Rename it Coin.
  2. Add a CollisionShape2D child with a small CircleShape2D.
  3. Add a Sprite2D child using icon.svg, scaled down, and set its Modulate color to yellow in the Inspector so it reads as a coin.
  4. Save it as coin.tscn.

An Area2D does not block anything. It detects when bodies enter it.

Attach a script to Coin:

extends Area2D

func _on_body_entered(body):
    if body is CharacterBody2D:
        queue_free()

Now connect the signal. Select Coin, open the Node dock next to the Inspector, and double-click body_entered. Make sure it connects to the Coin node and uses the method name _on_body_entered. Click Connect.

A signal is Godot’s way of announcing that something happened. When the player walks into the coin, body_entered fires, your function runs, and queue_free() removes the coin from the scene.

Back in level.tscn, drag several coins onto your platforms.

Step 7: Add a goal

Duplicate your coin approach. Create a scene with an Area2D root named Goal, a CollisionShape2D, and a green ColorRect. Attach this script and connect body_entered the same way:

extends Area2D

func _on_body_entered(body):
    if body is CharacterBody2D:
        print("Level complete")
        get_tree().reload_current_scene()

Place the goal at the far end of the level.

Step 8: Run the scene

With level.tscn open, press the Run Current Scene button in the top right of the editor (F6 on Windows and Linux). To make it the scene that launches when you run the project, open Project Settings and set it as the main scene, or accept the prompt Godot shows the first time you run the project.

Test each piece:

  • Arrow keys or A and D move the player.
  • Space jumps only from a platform.
  • The camera follows the player.
  • Coins vanish on touch.
  • The goal prints a message in the Output panel and restarts the level.

If the player falls through the floor, make sure every platform has a CollisionShape2D with a shape assigned. If a coin does nothing, check that the signal is connected; a small icon appears next to the node in the Scene dock when it is. If input does nothing, compare the action names in the Input Map with the names in your script, letter for letter.

Next steps

Once the loop works, try adding a coin counter on screen with a Label node, painting a level with tiles, and replacing the icon with your own sprite.

When you want to share the game, look at Project > Export. You will need to download export templates for your Godot version first, and the editor walks you through it.

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *