PL

Samouczek 1 — Hello world: menu, tekst, dźwięk

Najmniejsza gra JumPHP: ekran tytułowy z menu (graj, dźwięk, wyjdź), a potem tekst poruszany strzałkami i dźwięk na Spacji. Dwa pliki. Możesz ją zmienić od razu w piaskownicy albo utworzyć u siebie poleceniem bin/jumphp new hello-world.

Konfiguracja: config/game.yaml

game:
  id: hello-world
  title: "HELLO WORLD"
  width: 320                    # rozdzielczość gry, powiększana do rozmiaru ekranu
  height: 180
  start_scene: App\Scene\TitleScene
  touch: { a: Space, b: Escape, start: Return }    # przyciski pada na telefonie
  smoke:                        # to, co `bin/jumphp test` odgrywa samo, bez ekranu
    scene: App\Scene\HelloScene
    params: { demo: true }

Klawisze: silnik już definiuje up down left right confirm back pause (strzałki, Enter, Esc, pad, ekran dotykowy). Dodajemy akcję w config/input.yaml:

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

Ekran tytułowy: src/Scene/TitleScene.php

Menu piszemy, dziedzicząc po MenuScene: podajemy tytuł i wiersze, a silnik zajmuje się resztą (rysowaniem, poruszaniem się klawiaturą / padem / palcem, dźwiękami menu).

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

    public function enter(array $params = []): void
    {
        parent::enter($params);
        // dźwięki wytworzone w PHP: żaden plik audio nie jest potrzebny
        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]]));
        }
    }

    /** Wiersze: [etykieta, wartość wyświetlana po prawej, akcja na Enter, akcja na lewo / prawo] */
    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()];   // w przeglądarce nie ma „wyjścia”
        }
        return $items;
    }

    private function toggleSound(): void
    {
        $this->sound()->setMuted(!$this->sound()->isMuted());
        $this->refresh();    // menu wyświetla nową wartość
    }
}

Dźwięki menu_move i menu_confirm menu odtwarza automatycznie. Etykiety są tłumaczone przez config/lang.yaml (fr: { PLAY: JOUER }).

Gra: src/Scene/HelloScene.php

Scena ma trzy podstawowe metody:

  • enter($params): scena się zaczyna. Wyzeruj tutaj wszystko: ta sama scena służy wielokrotnie;
  • update($dt): 60 razy na sekundę zmieniamy stan gry. $dt to czas, który upłynął, w sekundach;
  • render($r): rysujemy i nic więcej.
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));   // „bip” idący w górę
        }
    }

    public function update(float $dt): void
    {
        if ($this->actions()->isPressed('back')) {          // Esc: powrót do tytułu
            $this->scenes()->switchTo(TitleScene::class);
            return;
        }
        // axis() zwraca -1, 0 lub 1: 90 pikseli na sekundę
        $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]);
        // wbudowana czcionka (5 × 7 pikseli), powiększona 2 razy, wyśrodkowana, z czarnym cieniem
        $this->font()->draw($r, 'HELLO WORLD!', $this->x, $this->y, 2, [255, 220, 80], 'center', [0, 0, 0]);
    }
}

Prawdziwy plik dodaje gwiazdki tryskające przy każdym dźwięku, tekst zmieniający kolor i tryb demo do testów: przeczytasz go w kodzie źródłowym gry.

Wypróbuj

  • W piaskownicy: zmień tekst, kolor [255, 220, 80], prędkość, dźwięk (Synth::tone(220, 0.3, 'triangle')), a potem ▶ Testuj.
  • U siebie: bin/jumphp run hello-world, bin/jumphp test hello-world.

Dalej: postać, która się porusza i animuje.