Scenes and nodes

The pieces every Godot game is built out of. Learn these first, because every lesson assumes them.

node

L01

One piece of your game: a player, a wall, a coin, a label. Every node is one kind of thing, and that kind decides what it can do. Nodes are the smallest thing Godot works with.

player.tscn
  • Player CharacterBody2D player.gd
  • Sprite2D
  • CollisionShape2D

scene

L01

A group of nodes saved together in one .tscn file. A scene can be a whole level, or one small thing like a coin that you use over and over.

player.tscn
  • Player CharacterBody2D player.gd
  • Sprite2D
  • CollisionShape2D

scene tree

L01

The list of nodes in the Scene dock, drawn as a family tree. Nodes indented under another node are its children, and children move with their parent.

game.tscn
  • Game Node2D
  • Player CharacterBody2D player.tscn
  • Borders Node2D
  • Top StaticBody2D hidden block.tscn
  • Bottom StaticBody2D hidden block.tscn
  • Left StaticBody2D hidden block.tscn
  • Right StaticBody2D hidden block.tscn

root node

L01

The node at the very top of a scene. Its type is what the whole scene counts as, so a scene whose root is a CharacterBody2D can be dropped into a level and it moves.

player.tscn
  • Player CharacterBody2D player.gd
  • Sprite2D
  • CollisionShape2D

Node2D

L01

The plain 2D node. It has a position and a rotation and draws nothing on its own, so it is what you reach for when you just need something to hold other nodes.

game.tscn
  • Game Node2D
  • Player CharacterBody2D player.tscn
  • Borders Node2D
  • Top StaticBody2D hidden block.tscn
  • Bottom StaticBody2D hidden block.tscn
extends Node2D

# draws nothing, but it has a position
position = Vector2(100, 50)

CharacterBody2D

L01

A body you drive yourself with code. It is the node for anything that walks, runs, or jumps: the player, and usually the enemies. You set velocity, call move_and_slide(), and Godot stops it at walls.

player.tscn
  • Player CharacterBody2D player.gd
  • Sprite2D
  • CollisionShape2D
extends CharacterBody2D

func _physics_process(delta):
    velocity = Vector2(200, 0)
    move_and_slide()

StaticBody2D

L02

A solid thing that never moves: walls, floors, platforms. It blocks bodies that run into it and needs no code at all.

block.tscn
  • Block StaticBody2D
  • Polygon2D
  • CollisionPolygon2D

Area2D

L08

A shape that notices a touch but does not block it. Coins, spikes, checkpoints, bullets. It tells you something arrived by sending the body_entered signal.

coin.tscn
  • Coin Area2D coin.gd
  • Polygon2D
  • CollisionShape2D
extends Area2D

func _on_body_entered(body):
    queue_free()    # noticed the touch, did not block it

CollisionShape2D

L01

The invisible shape that says which part of a node counts as solid. A body or an area with no CollisionShape2D child touches nothing, which is the most common reason a coin does nothing when you walk over it.

coin.tscn
  • Coin Area2D coin.gd
  • Polygon2D
  • CollisionShape2D

Sprite2D

L21

The node that draws a picture. Drag an image into its Texture slot and it shows up. The picture is only how the thing looks, never how it collides.

player.tscn
  • Player CharacterBody2D player.gd
  • Sprite2D
  • CollisionShape2D
$Sprite2D.texture = load("res://art/coin.png")
$Sprite2D.flip_h = true

Timer

L10

A node that counts down and sends timeout when it reaches zero. Use it for a shot cooldown, a countdown clock, or a spawner that fires every two seconds.

game.tscn
  • Game Node2D enemy_spawner.gd
  • Player CharacterBody2D % player.tscn
  • SpawnTimer Timer %
$Timer.wait_time = 2.0
$Timer.start()      # sends timeout in 2 seconds

Camera2D

L19

Decides which part of the world is on screen. Make it a child of the player and the view follows the player for free.

player.tscn
  • CameraPlayer CharacterBody2D player.gd
  • Sprite2D
  • CollisionShape2D
  • Camera Camera2D %

CanvasLayer

L08

A layer that stays put on screen even when the camera moves. Your score, your hearts, and your menus go in here so they do not slide away with the world.

hud.tscn
  • HUD CanvasLayer hud.gd
  • MarginContainer
  • ScoreLabel Label %

Label

L08

Draws text on screen. Set its text from code to show a score, a countdown, or the words GAME OVER.

hud.tscn
  • HUD CanvasLayer hud.gd
  • MarginContainer
  • ScoreLabel Label %
%ScoreLabel.text = "Score: " + str(score)

Button

L15

A thing the player can click. It sends the pressed signal, which is how a Play button starts the game.

game.tscn
  • Game Control main_menu.gd
  • MenuPanel VBoxContainer %
  • TitleLabel Label
  • PlayButton Button %
  • OptionsButton Button %
  • QuitButton Button %
%PlayButton.pressed.connect(_on_play_pressed)

func _on_play_pressed():
    get_tree().change_scene_to_file("res://level1.tscn")

AudioStreamPlayer

L16

The node that plays a sound. Put the sound file in its Stream slot, then call .play() when the coin is picked up.

game.tscn
  • Game Node2D sound_effects.gd
  • Player CharacterBody2D player.tscn
  • PickupSound AudioStreamPlayer %
  • JumpSound AudioStreamPlayer %
  • HUD CanvasLayer % hud.tscn
$PickupSound.play()

AnimationPlayer

L22

Changes a value over time and can loop it: a coin that spins, a door that slides open, a sprite that flashes red when it is hit. One of them holds several named animations and plays one at a time.

player.tscn
  • AnimPlayer CharacterBody2D player.gd
  • Sprite Sprite2D %
  • CollisionShape2D
  • AnimationPlayer %
$AnimationPlayer.play("spin")
$AnimationPlayer.play("hit_flash")

Marker2D

L04

An invisible node used only to mark a spot. Ours sits at the tip of the gun, so bullets start there instead of in the middle of the player.

player.tscn
  • ShooterPlayer CharacterBody2D player.gd
  • Body Sprite2D
  • Gun Polygon2D
  • Muzzle Marker2D %
  • ShootTimer Timer %
  • CollisionShape2D
var bullet = BULLET_SCENE.instantiate()
bullet.global_position = $Muzzle.global_position

PackedScene

L07

A saved scene file sitting ready to be copied, like a cookie cutter. It is not in the game yet.

spawn_enemy.tscn
  • SpawnEnemy CharacterBody2D spawn_enemy.gd
  • Polygon2D
  • CollisionShape2D
@export var enemy_scene: PackedScene

# the cookie cutter, not a cookie yet

instance

L07

One real copy of a scene, alive in the game. instantiate() makes the copy and add_child() puts it in, which is how one bullet scene becomes fifty bullets.

game.tscn
  • Game Node2D game.gd
  • Player CharacterBody2D player.tscn
  • Coin1 Area2D coin.tscn
  • Coin2 Area2D coin.tscn
  • Coin3 Area2D coin.tscn
  • HUD CanvasLayer hud.tscn
var enemy = enemy_scene.instantiate()   # one real copy
add_child(enemy)                       # now it is in the game