
Click Here to Dowload Godot
Click here to Download our Assets









extends CharacterBody2D
# Global Variables
const GRAVITY: int = 1800
const MAX_VEL: int = 600
const START_POS = Vector2(100,400)
const FLAP_SPEED: int = -500
var flying: bool = false
var falling: bool = false
func _ready():
reset()
func reset():
falling = false
flying = false
position = START_POS
set_rotation(0)
# Function that runs while game is running (Game loop)
func _physics_process(delta):
if flying or falling:
velocity.y += GRAVITY * delta
if velocity.y > MAX_VEL:
velocity.y = MAX_VEL
if flying:
set_rotation (deg_to_rad(velocity.y * 0.05))
$AnimatedSprite2D.play()
elif falling:
set_rotation(PI/2)
$AnimatedSprite2D.stop()
move_and_collide(velocity * delta)
else:
$AnimatedSprite2D.stop()
func flap():
velocity.y = FLAP_SPEED



extends Area2D
signal hit
func _on_body_entered(body):
hit.emit()


extends Node
var game_running: bool
var game_over: bool
var scroll
var score
const SCROLL_SPEED: int = 4
var screen_size: Vector2i
var ground_height: int
var pipes: Array
const PIPE_DELAY: int = 100
const PIPE_RANGE: int = 200
# Called when the node enters the scene tree for the first time.
func _ready():
screen_size = get_window().size
ground_height = $Ground.get_node("Sprite2D").texture.get_height()
new_game()
func new_game():
game_running = false
game_over = false
score = 0
scroll = 0
$Bird.reset()
func _input(event):
if (game_over) == false:
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
if game_running == false:
start_game()
else:
if $Bird.flying:
$Bird.flap()
func start_game():
game_running = true
$Bird.flying = true
$Bird.flap()
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
if game_running:
scroll += SCROLL_SPEED
if scroll >= screen_size.x:
scroll = 0
$Ground.position.x = -scroll





extends Area2D
signal hit
signal scored
func _on_body_entered(body):
hit.emit()
func _on_score_body_entered(body):
scored.emit()


Changes at:
extends Node
@export var pipe_scene:PackedScene
var game_running: bool
var game_over: bool
var scroll
var score
const SCROLL_SPEED: int = 4
var screen_size: Vector2i
var ground_height: int
var pipes: Array
const PIPE_DELAY: int = 100
const PIPE_RANGE: int = 200
func scored():
pass
#score += 1
#$ScoreLabel.text = "SCORE: " + str(score)
# Called when the node enters the scene tree for the first time.
func _ready():
screen_size = get_window().size
ground_height = $Ground.get_node("Sprite2D").texture.get_height()
new_game()
func new_game():
game_running = false
game_over = false
score = 0
scroll = 0
$Bird.reset()
# NEW CODE HERE
generate_pipes()
func _input(event):
if (game_over) == false:
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
if game_running == false:
start_game()
else:
if $Bird.flying:
$Bird.flap()
func start_game():
game_running = true
$Bird.flying = true
$Bird.flap()
# NEW CODE HERE
$PipeTimer.start()
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
if game_running:
scroll += SCROLL_SPEED
if scroll >= screen_size.x:
scroll = 0
$Ground.position.x = -scroll
for pipe in pipes:
pipe.position.x -= SCROLL_SPEED
func stop_game():
$PipeTimer.stop()
$Bird.flying = false
$GameOver.show()
game_running = false
game_over = true
func bird_hit():
$Bird.falling = true
stop_game()
func _on_pipe_timer_timeout():
generate_pipes()
func generate_pipes():
var pipe = pipe_scene.instantiate()
pipe.position.x = screen_size.x + PIPE_DELAY
pipe.position.y = (screen_size.y - ground_height) / 2 + randi_range(-PIPE_RANGE, PIPE_RANGE)
pipe.hit.connect(bird_hit)
pipe.scored.connect(scored)
add_child(pipe) # Add new pipe object to scene main
pipes.append(pipe) # Add new pipe object to pipes array, to keep track of them



func check_top():
if $Bird.position.y < 0:
$Bird.falling = true
stop_game()
func _input(event):
if (game_over) == false:
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
if game_running == false:
start_game()
else:
if $Bird.flying:
$Bird.flap()
check_top()
func _on_ground_hit():
if $Bird.flying:
$Bird.flap()
$Bird.falling = true # Set to false if you dont want to let rocky drown
stop_game()




extends CanvasLayer
signal restart
func _on_restart_button_pressed():
restart.emit()

extends Node
@export var pipe_scene:PackedScene
var game_running: bool
var game_over: bool
var scroll
var score
const SCROLL_SPEED: int = 4
var screen_size: Vector2i
var ground_height: int
var pipes: Array
const PIPE_DELAY: int = 100
const PIPE_RANGE: int = 200
# Called when the node enters the scene tree for the first time.
func _ready():
screen_size = get_window().size
ground_height = $Ground.get_node("Sprite2D").texture.get_height()
new_game()
func new_game():
game_running = false
game_over = false
score = 0
scroll = 0
$ScoreLabel.text = "SCORE: " + str(score)
$Bird.reset()
$GameOver.hide()
get_tree().call_group("pipes", "queue_free")
pipes.clear()
generate_pipes()
func _input(event):
if (game_over) == false:
if event is InputEventMouseButton:
if event.button_index == MOUSE_BUTTON_LEFT and event.pressed:
if game_running == false:
start_game()
else:
if $Bird.flying:
$Bird.flap()
check_top()
func start_game():
print("start game")
game_running = true
$Bird.flying = true
$Bird.flap()
$PipeTimer.start()
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
if game_running:
scroll += SCROLL_SPEED
if scroll >= screen_size.x:
scroll = 0
$Ground.position.x = -scroll
for pipe in pipes:
pipe.position.x -= SCROLL_SPEED
func _on_pipe_timer_timeout():
generate_pipes()
func generate_pipes():
var pipe = pipe_scene.instantiate()
pipe.position.x = screen_size.x + PIPE_DELAY
pipe.position.y = (screen_size.y - ground_height) / 2 + randi_range(-PIPE_RANGE, PIPE_RANGE)
pipe.hit.connect(bird_hit)
pipe.scored.connect(scored)
add_child(pipe) # Add new pipe object to scene main
pipes.append(pipe) # Add new pipe object to pipes array, to keep track of them
func scored():
score += 1
$ScoreLabel.text = "SCORE: " + str(score)
func stop_game():
$PipeTimer.stop()
$Bird.flying = false
$GameOver.show()
game_running = false
game_over = true
func check_top():
if $Bird.position.y < 0:
$Bird.falling = true
stop_game()
func bird_hit():
$Bird.falling = true
stop_game()
func _on_ground_hit():
if $Bird.flying:
$Bird.flap()
$Bird.falling = true # Set to false if you dont want to let rocky drown
stop_game()
func _on_game_over_restart():
new_game()
extends CharacterBody2D
const GRAVITY: int = 1800
const MAX_VEL: int = 600
const START_POS = Vector2(100,400)
const FLAP_SPEED: int = -500
var flying: bool = false
var falling: bool = false
func _ready():
reset()
func reset():
falling = false
flying = false
position = START_POS
set_rotation(0)
func _physics_process(delta):
if flying or falling:
velocity.y += GRAVITY * delta
if velocity.y > MAX_VEL:
velocity.y = MAX_VEL
if flying:
set_rotation (deg_to_rad(velocity.y * 0.05))
$AnimatedSprite2D.play()
elif falling:
set_rotation(PI/2)
$AnimatedSprite2D.stop()
move_and_collide(velocity * delta)
else:
$AnimatedSprite2D.stop()
func flap():
velocity.y = FLAP_SPEED
✅ Intro to Godot
✅ Introduction to Game Engines
❓ Checked in?!?

Solly thanks you for checking in and wanted to thank you guys personally. But Solly made a mistake and was forced to fight a galatic death god in a form of an alligator. But as one would expect from fighting a death god, he stood no chance. Fortunately it was an alligator and Solly grew up in Australia and came to Florida so he was able to escape with his life. But in return, he arrived on last Friday missing the workshop.
After missing the workshop Solly went undercover and went to an esport event at USF and there he found something shocking. Other than how bad gamers smelled, there was food. The image below is the amount of food AFTER everyone ate, although they woould probably eat more after the event finished. But luckily there was a kind gamer girl who shared some food with Solly and he had his first meal in 3 days. So be remember to sign in so food can come to both Solly and us.



Disapointly Solly did not make it today, for that he was only able to take 5 days off from a Triple A gaming studio per year. Thus he had left us with an gif of him waving at us.