All lessons
Lesson 03

Walls and Collisions

Find your way through a maze. A StaticBody2D blocks the player; an Area2D notices a touch without blocking it.

Loading the game engine. This takes a moment the first time.

Build style
  • The maze walls are StaticBody2D nodes. They never move, and the player cannot pass through them. One exception: the gold platforms in the Platformer build, which stop you from one side only. See One Way Collision below.
  • Each wall holds two shapes drawn from the same corner points: a Polygon2D you can see, and a CollisionPolygon2D the player bumps into.
  • The goal is an Area2D, so the player CAN pass through it. An Area2D only notices a touch, it never blocks.
  • This player is in a GROUP called "Player", a label stuck on the node, set on the Node tab next to the Inspector.

ONE WAY COLLISION

  1. In the Scene dock, click the CollisionPolygon2D INSIDE the platform. Not the platform itself: the setting lives on the shape, not the body.
  2. Tick "One Way Collision" in the Inspector on the right.
  3. Press F6 and jump up through the platform.

The scenes

UI node · 2D node · % unique name · .tscn instanced scene

walls_and_collisions.tscn
  • WallsAndCollisions Node2D
  • MazePlayer CharacterBody2D player.tscn
  • Goal Area2D goal.tscn
  • Wall1 StaticBody2D
  • Polygon2D
  • CollisionPolygon2D
  • Wall2 StaticBody2D
  • Polygon2D
  • CollisionPolygon2D
  • Wall3 StaticBody2D
  • Polygon2D
  • CollisionPolygon2D
  • Wall4 StaticBody2D
  • Polygon2D
  • CollisionPolygon2D
goal.tscn
  • Goal Area2D goal.gd
  • Polygon2D
  • CollisionShape2D
player.tscn
  • MazePlayer CharacterBody2D player.gd
  • Sprite2D
  • CollisionShape2D
Build style
extends CharacterBody2D

## How fast the player moves. "@export" puts "speed" at the top of the
## Inspector panel, so you can change it there instead of in this file.
@export var speed: float = 250.0

# "_physics_process()" runs about 60 times a second. Godot calls it for you.
func _physics_process(_delta: float) -> void:
	# "Input.get_vector(...)" checks all four keys at once and turns them
	# into one arrow pointing where you want to go. The names in quotes are
	# Godot's built-in names for the arrow keys.
	var direction: Vector2 = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	# "direction" is only WHICH WAY (its length is always 1).
	# "direction * speed" stretches it, so "velocity" is also HOW FAST.
	velocity = direction * speed
	# Nothing moves until "move_and_slide()" runs.
	# "Slide" means we slide along walls instead of sticking to them.
	move_and_slide()

	# The warrior picture only faces right, so walking left mirrors it and
	# walking right puts it back. Neither "if" runs when you stand still,
	# which is what keeps the warrior facing the way you last walked.
	if direction.x < 0.0:
		$Sprite2D.flip_h = true
	if direction.x > 0.0:
		$Sprite2D.flip_h = false