← Back to the blog

Godot

Make your first game with no experience — Flappy Bird

A first Flappy Bird-style game in Godot: the character, physics, collisions, and game over.

Make your first game with no experience — Flappy Bird

Free assets for this game

Download

What are we making?

The goal is a game in the spirit of “Flappy Bird”. The character sits on the left of the screen and tries to dodge obstacles while travelling right. You steer with single hops. Touch a column, or hit the ground, and the run is over.


The character — a UFO

The character is three nodes:

  • CharacterBody2D, the class that gives the character basic physics. Gravity pulls the little alien down, and the same body can hop.
  • Sprite2D, which decides how the character looks. Any image can sit here.
  • CollisionShape2D, the collision shape. This is how we know whether the character passed the pillars or hit them.

Sprite2D and CollisionShape2D are children of CharacterBody2D. They move as part of it.

On Sprite2D you assign a texture. On CollisionShape2D you add a shape. A capsule, CapsuleShape2D, fits this sprite. Resize it to the artwork with the two red handles.

Then the character needs a script so it can move up and down. Attach it to the CharacterBody2D node.

extends CharacterBody2D

const SPEED = 300.0 # tworzy stałą określającą prędkość
const JUMP_VELOCITY = -400.0 # "siła" skoku

var gravity = ProjectSettings.get_setting("physics/2d/default_gravity") # wczytujemy grawitację z ProjectSettings

func _physics_process(delta): # zawartość tej funkcji wykona się przy każdym tick'u procesu fizyki gry czyli wiele razy na sekundę
	
	velocity.y += gravity * delta # zmieniamy prędkość postaci w osi Y
	
	if Input.is_action_just_pressed("ui_accept"): # warunkowo po wciśnięciu np. Spacji zmieniamy prędkość w osi Y
		velocity.y = JUMP_VELOCITY
	
	move_and_slide() # wywołanie tego sprawia, że postać będzie płynnie się przemieszczać

The edges of the play field

The play field should match what the camera shows. The character should lose when it falls to the ground, and it should not be able to fly off the top of the screen.

I moved the scene so the whole CharacterBody2D sits halfway up the left edge. TopBorder, a StaticBody2D, sits just above the screen. Ground, an Area2D, sits just below it.

A StaticBody2D reacts to the character’s collider and blocks it. It is a wall. An Area2D does not, by itself, stop anything. You connect the moment the character enters Ground, and you do that with a signal.

Select a node and open the Node tab beside the Inspector. Signals and groups live there. Groups categorize objects. Signals are events. We want body_entered: some body stepped into Ground. Connect that event to CharacterBody2D.

func _on_ground_body_entered(body):
	get_tree().paused = true

The CharacterBody2D script then gains a function that runs every time a body enters the Ground collider.

← Back to the blog