Keep your place in this quest

Log in or sign up for free to subscribe, follow lesson progress, and access more learning content.

Beispiel: Komplettes Spiel

Diese Lektion erstellt ein kleines Sammelspiel. Der Spieler bewegt sich in einer Szene, stößt gegen Wände, sammelt Münzen und zeigt eine Punktzahl an, wenn das Spiel endet.

Anstatt das gesamte Skript auf einmal einzufügen, wurde das Beispiel in die gleichen Teile unterteilt, die Du in den meisten Tiniest2D-Projekten verwenden wirst:

  • Asset- und Statusvariablen
  • start()
  • onUpdate(dt)
  • onCollision(objA, objB)
  • end()

1. Assets und Spielzustand

Der erste Abschnitt erstellt die Assets und Variablen, die der Rest des Skripts verwenden wird. Sprites sind Bilder, die Szene ist das Level, der Spieler ist ein Objekt, das in dieser Szene platziert wird, und die Punkte-/Geschwindigkeitsvariablen speichern den einfachen Spielzustand.

// Erstelle Assets
var playerImg = Sprite(16, 16)
var wallImg = Sprite(16, 16)
var coinImg = Sprite(8, 8)
var level = Scene()

// Erstelle das Spielerobjekt
var player = Object("Player")

// Spielzustand
var score = 0
var speed = 100

Zu diesem Zeitpunkt existieren die Variablen, aber das Spiel hat noch nichts in die Szene eingefügt. Diese Einrichtung erfolgt in start().

2. Die start() Funktion

start() wird einmal aufgerufen, wenn das Spiel beginnt. Verwende es, um Objekte zu konfigurieren, die erste Szene festzulegen, die Kamera zu positionieren und etwaige Anfangswerte vorzubereiten.

func start() {
    // Spieler einrichten
    setSprite(player, playerImg)
    setCollisionType(player, COLLISION_DYNAMIC())
    setX(player, 50)
    setY(player, 50)
    addObject(level, player)

    // Anfangsszene festlegen
    setScene(level)

    // Kamera auf Spieler zentrieren
    setCameraX(level, getX(player))
    setCameraY(level, getY(player))
    setCameraZoom(level, 3)

    print("Sammle die Münzen!")
}

Der Spieler verwendet COLLISION_DYNAMIC(), weil er mit Wänden zusammenstoßen und aus ihnen herausgeschoben werden sollte. Die Kamera beginnt zentriert auf dem Spieler, so dass die Levelansicht an der richtigen Stelle beginnt.

3. Die onUpdate(dt) Funktion

onUpdate(dt) wird in jedem Frame aufgerufen. Hier liest der Spieler Eingaben, bewegt sich, aktualisiert die Kamera und überprüft die Reset-Tasten.

dt bedeutet "Delta-Zeit": die Zeitspanne seit dem vorherigen Frame. Die Bewegung mit dt zu multiplizieren, sorgt dafür, dass die Bewegungsgeschwindigkeit über verschiedene Frame-Raten hinweg konsistenter ist.

func onUpdate(dt) {
    // Spielerbewegung
    var moveX = 0
    var moveY = 0

    if (isKeyHeld(KEY_LEFT()) || isKeyHeld(KEY_A())) {
        moveX = -1
    }
    if (isKeyHeld(KEY_RIGHT()) || isKeyHeld(KEY_D())) {
        moveX = 1
    }
    if (isKeyHeld(KEY_UP()) || isKeyHeld(KEY_W())) {
        moveY = -1
    }
    if (isKeyHeld(KEY_DOWN()) || isKeyHeld(KEY_S())) {
        moveY = 1
    }

    // Bewegung anwenden
    setX(player, getX(player) + moveX * speed * dt)
    setY(player, getY(player) + moveY * speed * dt)

    // Kamera folgt Spieler
    setCameraX(level, getX(player))
    setCameraY(level, getY(player))

    // Level mit R-Taste zurücksetzen
    if (isKeyPressed(KEY_R())) {
        resetScene(level)
        setX(player, 50)
        setY(player, 50)
        score = 0
        print("Level zurückgesetzt!")
    }
}

Der Bewegungscode erstellt eine Richtung aus der Tastatureingabe. Dann wird diese Richtung zur aktuellen Position des Spielers hinzugefügt. Die Kamera wird nach der Bewegung aktualisiert, sodass sie der neuen Position folgt.

4. Die onCollision(objA, objB) Funktion

onCollision(objA, objB) wird aufgerufen, wenn zwei Objekte kollidieren. In diesem Beispiel sollten Münzen COLLISION_TRIGGER() verwenden. Triggerobjekte melden Überlappungen, blockieren aber nicht die Bewegung.

func onCollision(objA, objB) {
    var nameB = getName(objB)
    var typeB = getCollisionType(objB)

    // Münzesammlung (Münzen sollten im Szeneneditor vom Typ TRIGGER sein)
    if (typeB == COLLISION_TRIGGER()) {
        removeObject(level, objB)
        score = score + 1
        print("Punkte: " + score)
    }
}

Wenn der Spieler einen Trigger berührt, entfernt das Skript dieses Objekt aus der Szene und erhöht die Punktzahl. Dies ist das grundlegende Muster für Einsammelobjekte, Schlüssel, Power-ups und Checkpoints.

5. Die end() Funktion

end() wird aufgerufen, wenn das Spiel stoppt. Dieses Beispiel gibt nur die endgültige Punktzahl aus, aber größere Spiele können diese Funktion zur Bereinigung oder für letzte Debug-Nachrichten nutzen.

func end() {
    print("Endgültige Punktzahl: " + score)
}

Beispiel einrichten

  1. Erstelle die Sprites:
  2. Ctrl+Click auf playerImg, zeichne einen Charakter (zum Beispiel eine einfache Strichfigur)
  3. Ctrl+Click auf wallImg, zeichne einen festen Block
  4. Ctrl+Click auf coinImg, zeichne einen kleinen Kreis oder ein Diamant

  5. Gestalte die Szene:

  6. Ctrl+Click auf level
  7. Wähle wallImg im linken Panel, setze die Kollision auf "Statisch"
  8. Male Wände um die Ränder und erstelle ein Labyrinth
  9. Wähle coinImg, setze die Kollision auf "Keine" für dekorative Münzfliesen
  10. Platziere Münzen im Level als visuelle Hinweise

  11. Erstelle Trigger-Münzobjekte:

In die Szene gestempelte Sprites sind nützlich für Fliesen und Dekoration, aber sammelbare Münzen sollten Objekte sein, damit Kollision-Rückrufmethoden sie entfernen können. Füge Münzobjekte wie folgt hinzu:

var coin1 = Object("Coin1")
var coin2 = Object("Coin2")

func start() {
    // ... Spieler einrichten ...

    // Münzen als Trigger einrichten
    setSprite(coin1, coinImg)
    setCollisionType(coin1, COLLISION_TRIGGER())
    setX(coin1, 100)
    setY(coin1, 80)
    addObject(level, coin1)

    setSprite(coin2, coinImg)
    setCollisionType(coin2, COLLISION_TRIGGER())
    setX(coin2, 150)
    setY(coin2, 120)
    addObject(level, coin2)

    // ... restliches Setup ...
}

Dieses Muster kann für weitere Münzen, Feinde, Türen oder jedes Objekt mit Skriptverhalten erweitert werden.