DE

Tutorial 1 — Hello World: ein Menü, ein Text, ein Sound

Das kleinste JumPHP-Spiel: ein Titelbildschirm mit einem Menü (Spielen, Sound, Beenden), dann ein Text, der sich mit den Pfeiltasten bewegt, und ein Sound auf der Leertaste. Zwei Dateien. Du kannst es sofort in der Sandbox ändern oder bei dir mit bin/jumphp new hello-world anlegen.

Die Konfiguration: config/game.yaml

game:
  id: hello-world
  title: "HELLO WORLD"
  width: 320                    # die Auflösung des Spiels, auf die Bildschirmgröße hochskaliert
  height: 180
  start_scene: App\Scene\TitleScene
  touch: { a: Space, b: Escape, start: Return }    # die Pad-Tasten auf dem Smartphone
  smoke:                        # was `bin/jumphp test` ohne Bildschirm von allein spielt
    scene: App\Scene\HelloScene
    params: { demo: true }

Die Tasten: Die Engine definiert bereits up down left right confirm back pause (Pfeiltasten, Eingabe, Esc, Gamepad, Touchscreen). Eine weitere Aktion fügst du in config/input.yaml hinzu:

actions:
  jump: [Space, pad0:a, touch:tap]

Der Titelbildschirm: src/Scene/TitleScene.php

Ein Menü schreibst du, indem du von MenuScene erbst: Du gibst den Titel und die Zeilen an, den Rest übernimmt die Engine (Zeichnen, Navigation per Tastatur / Gamepad / Finger, Menü-Sounds).

final class TitleScene extends MenuScene
{
    protected string $title = 'HELLO WORLD';

    public function enter(array $params = []): void
    {
        parent::enter($params);
        // in PHP erzeugte Sounds: keine Audiodatei nötig
        if (!$this->sound()->hasSfx('menu_move')) {
            $this->sound()->synth('menu_move', Synth::tone(660, 0.04));
            $this->sound()->synth('menu_confirm', Synth::sequence([[660, 0.05], [990, 0.08]]));
        }
    }

    /** Die Zeilen: [Beschriftung, rechts angezeigter Wert, Aktion bei Eingabe, Aktion bei links / rechts] */
    protected function items(): array
    {
        $items = [
            ['PLAY', null, fn () => $this->scenes()->switchTo(HelloScene::class)],
            ['SOUND', fn () => $this->sound()->isMuted() ? 'OFF' : 'ON', fn () => $this->toggleSound(), fn () => $this->toggleSound()],
        ];
        if (Platform::isDesktop()) {
            $items[] = ['QUIT', null, fn () => $this->engine->quit()];   // im Browser gibt es kein „Beenden“
        }
        return $items;
    }

    private function toggleSound(): void
    {
        $this->sound()->setMuted(!$this->sound()->isMuted());
        $this->refresh();    // das Menü zeigt den neuen Wert an
    }
}

Die Sounds menu_move und menu_confirm spielt das Menü automatisch ab. Die Beschriftungen werden über config/lang.yaml übersetzt (fr: { PLAY: JOUER }).

Das Spiel: src/Scene/HelloScene.php

Eine Szene hat drei wesentliche Methoden:

  • enter($params): Die Szene beginnt. Setze hier alles zurück: Dieselbe Szene wird mehrfach verwendet;
  • update($dt): 60-mal pro Sekunde änderst du den Zustand des Spiels. $dt ist die vergangene Zeit in Sekunden;
  • render($r): Du zeichnest, und sonst nichts.
final class HelloScene extends AbstractScene
{
    private float $x = 0.0;
    private float $y = 0.0;

    public function enter(array $params = []): void
    {
        $this->x = $this->width() / 2;
        $this->y = $this->height() / 2;
        if (!$this->sound()->hasSfx('beep')) {
            $this->sound()->synth('beep', Synth::sweep(440, 880, 0.12));   // ein aufsteigender „Piep“
        }
    }

    public function update(float $dt): void
    {
        if ($this->actions()->isPressed('back')) {          // Esc: zurück zum Titel
            $this->scenes()->switchTo(TitleScene::class);
            return;
        }
        // axis() ist -1, 0 oder 1: 90 Pixel pro Sekunde
        $this->x += $this->actions()->axis('left', 'right') * 90 * $dt;
        $this->y += $this->actions()->axis('up', 'down') * 90 * $dt;

        if ($this->actions()->isPressed('jump') || $this->actions()->isPressed('confirm')) {
            $this->sound()->playSfx('beep');
        }
    }

    public function render(Renderer $r): void
    {
        $r->clear([16, 16, 40]);
        // die eingebaute Schrift (5 × 7 Pixel), 2-fach vergrößert, zentriert, mit schwarzem Schatten
        $this->font()->draw($r, 'HELLO WORLD!', $this->x, $this->y, 2, [255, 220, 80], 'center', [0, 0, 0]);
    }
}

Die echte Datei fügt Sterne hinzu, die bei jedem Sound hervorsprühen, einen Text, der die Farbe wechselt, und einen Demo-Modus für die Tests: Lies sie in den Quellen des Spiels.

Ausprobieren

  • In der Sandbox: Ändere den Text, die Farbe [255, 220, 80], die Geschwindigkeit, den Sound (Synth::tone(220, 0.3, 'triangle')) und klicke dann auf ▶ Testen.
  • Bei dir: bin/jumphp run hello-world, bin/jumphp test hello-world.

Weiter geht es mit einer Spielfigur, die sich bewegt und animiert wird.