Switch to a side view. Gravity pulls down constantly, and jumping only fights it for a moment.
Loading the game engine. This takes a moment the first time.
This is the first side-view lesson. Gravity is always pulling the player down. Jumping fights it for a moment, and then gravity wins again.
■ UI node · ■ 2D node · % unique name · .tscn instanced scene
extends Node2D
func _ready() -> void:
# "_ready()" runs once, when the scene starts. Setup goes here.
# GoalArea is the green zone at the top of the level. We put the name
# "_on_goal_reached" inside ".connect()". That is the function Godot
# runs when something touches it.
%GoalArea.body_entered.connect(_on_goal_reached)
# "body" is whatever touched the goal zone.
func _on_goal_reached(body: Node2D) -> void:
# "PlatformPlayer" is the class_name at the top of player.gd.
if body is PlatformPlayer:
# hud.gd connects to "goal_reached" and puts the win message on screen.
GameEvents.goal_reached.emit()extends CanvasLayer
# "%MessageLabel" means "the node named MessageLabel in this scene."
@onready var message_label: Label = %MessageLabel
func _ready() -> void:
# platformer_movement.gd emits "goal_reached" when the player touches the
# green zone. We put "_on_goal_reached" inside ".connect()". That is the
# function Godot runs when the signal arrives.
GameEvents.goal_reached.connect(_on_goal_reached)
%HomeButton.pressed.connect(_on_home_pressed)
# Loads the lesson list screen, which replaces this whole scene.
func _on_home_pressed() -> void:
get_tree().change_scene_to_file("res://shared/ui/lesson_select.tscn")
func _on_goal_reached() -> void:
message_label.text = "You reached the top!"class_name PlatformPlayer
extends CharacterBody2D
## How fast the player runs left and right.
@export var speed: float = 200.0
## How hard the player jumps. This number is NEGATIVE on purpose. In Godot
## the top of the screen is 0 and the numbers grow going down, so up is
## the negative direction.
@export var jump_velocity: float = -650.0
## How hard gravity pulls down. A bigger number means you fall faster.
@export var gravity: float = 1800.0
# This one function does four jobs. Here they are, one at a time.
func _physics_process(delta: float) -> void:
# STEP 1: FALL. If our feet are not on the ground, gravity pulls us
# down. Notice it is "+=" and not "=": we add a little more speed every
# frame, so the longer you fall the faster you drop.
if not is_on_floor():
velocity.y += gravity * delta
# STEP 2: JUMP. "is_action_just_pressed" is true only on the one frame
# the key goes down. (If we used "is_action_pressed" it would be true
# the whole time you hold the key, and you would jump over and over.)
# The "is_on_floor()" check is what stops you jumping in mid-air.
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = jump_velocity
# STEP 3: RUN. "get_axis()" hands back a single number:
# -1 for left, 1 for right, and 0 for neither.
var direction: float = Input.get_axis("move_left", "move_right")
velocity.x = direction * speed
# STEP 4: MOVE. Steps 1 to 3 only DECIDED where to go.
# "move_and_slide()" is the line that actually moves us.
move_and_slide()
# The warrior picture only faces right. Walking left mirrors it.
if direction != 0.0:
$Sprite2D.flip_h = direction < 0.0