UK

Посібник 1 — Hello world: меню, текст, звук

Найменша гра на JumPHP: титульний екран з меню (грати, звук, вийти), потім текст, що рухається стрілками, і звук на пробіл. Два файли. Ви можете змінити її просто зараз у пісочниці або створити в себе вдома командою bin/jumphp new hello-world.

Конфігурація: config/game.yaml

game:
  id: hello-world
  title: "HELLO WORLD"
  width: 320                    # роздільність гри, збільшується до розміру екрана
  height: 180
  start_scene: App\Scene\TitleScene
  touch: { a: Space, b: Escape, start: Return }    # кнопки пада на телефоні
  smoke:                        # те, що `bin/jumphp test` програє сам, без екрана
    scene: App\Scene\HelloScene
    params: { demo: true }

Клавіші: рушій уже визначає up down left right confirm back pause (стрілки, Enter, Esc, геймпад, сенсорний екран). Нову дію додаємо в config/input.yaml:

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

Титульний екран: src/Scene/TitleScene.php

Меню пишеться успадкуванням від MenuScene: ми задаємо заголовок і рядки, а рушій робить решту (малювання, навігацію клавіатурою / геймпадом / пальцем, звуки меню).

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

    public function enter(array $params = []): void
    {
        parent::enter($params);
        // звуки, створені на PHP: жодного аудіофайлу не потрібно
        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]]));
        }
    }

    /** Рядки: [підпис, значення праворуч, дія на Enter, дія на ліво / право] */
    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()];   // у браузері немає «вийти»
        }
        return $items;
    }

    private function toggleSound(): void
    {
        $this->sound()->setMuted(!$this->sound()->isMuted());
        $this->refresh();    // меню показує нове значення
    }
}

Звуки menu_move і menu_confirm меню відтворює автоматично. Підписи перекладаються через config/lang.yaml (fr: { PLAY: JOUER }).

Гра: src/Scene/HelloScene.php

Сцена має три основні методи:

  • enter($params): сцена починається. Скидайте тут усе в нуль: та сама сцена використовується багато разів;
  • update($dt): 60 разів на секунду ми змінюємо стан гри. $dt — час, що минув, у секундах;
  • render($r): ми малюємо, і більше нічого.
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));   // «біп», що йде вгору
        }
    }

    public function update(float $dt): void
    {
        if ($this->actions()->isPressed('back')) {          // Esc: повернення на титульний екран
            $this->scenes()->switchTo(TitleScene::class);
            return;
        }
        // axis() дорівнює -1, 0 або 1: 90 пікселів на секунду
        $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]);
        // вбудований шрифт (5 × 7 пікселів), збільшений удвічі, по центру, з чорною тінню
        $this->font()->draw($r, 'HELLO WORLD!', $this->x, $this->y, 2, [255, 220, 80], 'center', [0, 0, 0]);
    }
}

Справжній файл додає зірки, що розлітаються з кожним звуком, текст, що змінює колір, і демо-режим для тестів: прочитайте його в сирцях гри.

Спробувати

  • У пісочниці: змініть текст, колір [255, 220, 80], швидкість, звук (Synth::tone(220, 0.3, 'triangle')), потім ▶ Тестувати.
  • У себе вдома: bin/jumphp run hello-world, bin/jumphp test hello-world.

Далі: персонаж, що рухається й анімується.