Exercise

Your First Scene: Draw a Card

Module 1 ยท Exercise 1 ยท ~45 min ยท feeds into the capstone

You're going to build a tiny working thing: a scene with a single Card, clicked to flip, with a signal emitted. When you finish, you'll have written your first CardData resource, your first custom scene, your first script, and you'll have wired up a signal. Everything after this is more of the same.

What "done" looks like Hit Play, see a card on screen. Click it. It reads "flipped!" in the output log. That's it โ€” but every concept in Module 1 is exercised.

Prerequisites

Step-by-step

1Create a CardData resource class.

In the FileSystem dock, right-click โ†’ New โ†’ Folder โ†’ scripts. Inside it, right-click โ†’ New โ†’ Script. Name it card_data.gd. Paste:

class_name CardData
extends Resource

@export var letter: String = "A"
@export var value: int = 1

func describe() -> String:
    return "%s (%d)" % [letter, value]

Save. Godot will re-parse and the CardData type will be globally available.

2Create a card resource instance.

Right-click the FileSystem root โ†’ New โ†’ Folder โ†’ cards. In that folder, right-click โ†’ New โ†’ Resource. Type CardData in the dialog. Save as a_tile.tres. It opens in the Inspector. Set letter: A, value: 1. Save.

3Create the Card scene.

Scene menu โ†’ New Scene. "Other Node" โ†’ Node2D. Rename the root to Card. Save as scenes/card.tscn (create the folder if needed).

Add children โ€” right-click the root โ†’ Add Child Node:

4Attach a script to Card.

Click the Card root, then the scroll-with-plus icon ("Attach Script"). Accept the defaults. Paste:

extends Node2D
class_name Card

signal card_flipped(card: Card)

@export var data: CardData
@onready var label: Label = $LetterLabel
@onready var touch: Area2D = $TouchArea

var is_flipped := false

func _ready() -> void:
    if data:
        label.text = data.letter
    touch.input_event.connect(_on_touch_input)

func _on_touch_input(_viewport: Node, event: InputEvent, _shape_idx: int) -> void:
    if event is InputEventMouseButton and event.pressed:
        flip()

func flip() -> void:
    is_flipped = !is_flipped
    label.text = "โœฆ" if is_flipped else data.letter
    card_flipped.emit(self)
    print("card %s flipped -> %s" % [data.letter, is_flipped])

5Assign the data resource.

With the Card node selected in the scene, look at the Inspector. There's a Data slot (because @export var data: CardData). Drag cards/a_tile.tres from the FileSystem dock into that slot.

6Create a main scene that hosts the Card.

Scene โ†’ New Scene โ†’ Node2D. Rename to Main. Save as scenes/main.tscn. Drag scenes/card.tscn from the FileSystem dock into the Scene dock, dropping it onto Main. Position the card somewhere visible (e.g. (200, 200)).

Project โ†’ Project Settings โ†’ Application โ†’ Run โ†’ set Main Scene to main.tscn.

7Run it.

Press F5. A window opens. You see an "A" on a gray rectangle. Click it. The letter changes to โœฆ. The output log prints card A flipped -> true. Click again. Flips back.

That's the complete loop: scene composition, script behavior, signal emission, data-driven resource.

What you actually just did

Stretch goals

If you finish with time to spare:

If it doesn't work

When it runs, return to the dashboard and check off this exercise.