NL

Tutorial 1 — Hello world: een menu, een tekst, een geluid

De kleinste JumPHP-game: een titelscherm met een menu (spelen, geluid, afsluiten), daarna een tekst die met de pijltjestoetsen beweegt en een geluid op Spatie. Twee bestanden. Je kunt hem meteen aanpassen in de sandbox, of thuis aanmaken met bin/jumphp new hello-world.

De configuratie: config/game.yaml

game:
  id: hello-world
  title: "HELLO WORLD"
  width: 320                    # de resolutie van de game, vergroot naar de grootte van het scherm
  height: 180
  start_scene: App\Scene\TitleScene
  touch: { a: Space, b: Escape, start: Return }    # de knoppen van de pad op telefoon
  smoke:                        # wat `bin/jumphp test` zelf speelt, zonder scherm
    scene: App\Scene\HelloScene
    params: { demo: true }

De toetsen: de engine definieert al up down left right confirm back pause (pijltjes, Enter, Esc, de gamepad, het touchscreen). Een actie voeg je toe in config/input.yaml:

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

Het titelscherm: src/Scene/TitleScene.php

Een menu schrijf je door van MenuScene te erven: je geeft de titel en de regels, de engine doet de rest (tekenen, bewegen met toetsenbord / gamepad / vinger, menugeluiden).

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

    public function enter(array $params = []): void
    {
        parent::enter($params);
        // geluiden gemaakt in PHP: geen enkel audiobestand nodig
        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]]));
        }
    }

    /** De regels: [label, rechts getoonde waarde, actie bij Enter, actie bij 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()];   // geen “afsluiten” in de browser
        }
        return $items;
    }

    private function toggleSound(): void
    {
        $this->sound()->setMuted(!$this->sound()->isMuted());
        $this->refresh();    // het menu toont de nieuwe waarde opnieuw
    }
}

De geluiden menu_move en menu_confirm worden automatisch door het menu afgespeeld. De labels worden vertaald met config/lang.yaml (fr: { PLAY: JOUER }).

De game: src/Scene/HelloScene.php

Een scène heeft drie essentiële methodes:

  • enter($params): de scène begint. Zet hier alles op nul: dezelfde scène wordt meerdere keren gebruikt;
  • update($dt): 60 keer per seconde verander je de toestand van de game. $dt is de verstreken tijd in seconden;
  • render($r): je tekent, en verder niets.
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));   // een stijgende “bliep”
        }
    }

    public function update(float $dt): void
    {
        if ($this->actions()->isPressed('back')) {          // Esc: terug naar de titel
            $this->scenes()->switchTo(TitleScene::class);
            return;
        }
        // axis() is -1, 0 of 1: 90 pixels per seconde
        $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]);
        // het ingebouwde lettertype (5 × 7 pixels), 2 keer vergroot, gecentreerd, met een zwarte schaduw
        $this->font()->draw($r, 'HELLO WORLD!', $this->x, $this->y, 2, [255, 220, 80], 'center', [0, 0, 0]);
    }
}

Het echte bestand voegt sterren toe die bij elk geluid opspringen, een tekst die van kleur verandert, en een demomodus voor de tests: lees het in de broncode van de game.

Uitproberen

  • In de sandbox: verander de tekst, de kleur [255, 220, 80], de snelheid, het geluid (Synth::tone(220, 0.3, 'triangle')) en klik dan op ▶ Testen.
  • Thuis: bin/jumphp run hello-world, bin/jumphp test hello-world.

Volgende: een personage dat beweegt en animeert.