ES

Tutorial 1 — Hello world: un menú, un texto, un sonido

El juego JumPHP más pequeño: una pantalla de título con un menú (jugar, sonido, salir) y después un texto que se mueve con las flechas y un sonido al pulsar Espacio. Dos archivos. Puedes modificarlo ahora mismo en el sandbox, o crearlo en tu equipo con bin/jumphp new hello-world.

La configuración: config/game.yaml

game:
  id: hello-world
  title: "HELLO WORLD"
  width: 320                    # la resolución del juego, ampliada al tamaño de la pantalla
  height: 180
  start_scene: App\Scene\TitleScene
  touch: { a: Space, b: Escape, start: Return }    # los botones del pad en el móvil
  smoke:                        # lo que `bin/jumphp test` juega solo, sin pantalla
    scene: App\Scene\HelloScene
    params: { demo: true }

Las teclas: el motor ya define up down left right confirm back pause (flechas, Intro, Esc, el mando, la pantalla táctil). Se añade una acción en config/input.yaml:

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

La pantalla de título: src/Scene/TitleScene.php

Un menú se escribe heredando de MenuScene: das el título y las líneas, y el motor se encarga del resto (dibujo, movimiento con teclado / mando / dedo, sonidos del menú).

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

    public function enter(array $params = []): void
    {
        parent::enter($params);
        // sonidos fabricados en PHP: no hace falta ningún archivo de audio
        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]]));
        }
    }

    /** Las líneas: [etiqueta, valor mostrado a la derecha, acción con Intro, acción con izquierda / derecha] */
    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()];   // no hay «salir» en el navegador
        }
        return $items;
    }

    private function toggleSound(): void
    {
        $this->sound()->setMuted(!$this->sound()->isMuted());
        $this->refresh();    // el menú vuelve a mostrar el nuevo valor
    }
}

Los sonidos menu_move y menu_confirm los reproduce automáticamente el menú. Las etiquetas se traducen con config/lang.yaml (fr: { PLAY: JOUER }).

El juego: src/Scene/HelloScene.php

Una escena tiene tres métodos esenciales:

  • enter($params): la escena empieza. Pon todo a cero aquí: la misma escena se usa varias veces;
  • update($dt): 60 veces por segundo, se cambia el estado del juego. $dt es el tiempo transcurrido en segundos;
  • render($r): se dibuja, y nada más.
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));   // un «bip» que sube
        }
    }

    public function update(float $dt): void
    {
        if ($this->actions()->isPressed('back')) {          // Esc: volver al título
            $this->scenes()->switchTo(TitleScene::class);
            return;
        }
        // axis() vale -1, 0 o 1: 90 píxeles por segundo
        $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]);
        // la fuente integrada (5 × 7 píxeles), ampliada 2 veces, centrada, con una sombra negra
        $this->font()->draw($r, 'HELLO WORLD!', $this->x, $this->y, 2, [255, 220, 80], 'center', [0, 0, 0]);
    }
}

El archivo real añade estrellas que salen disparadas con cada sonido, un texto que cambia de color y un modo demo para las pruebas: léelo en el código fuente del juego.

Probarlo

  • En el sandbox: cambia el texto, el color [255, 220, 80], la velocidad, el sonido (Synth::tone(220, 0.3, 'triangle')) y pulsa ▶ Probar.
  • En tu equipo: bin/jumphp run hello-world, bin/jumphp test hello-world.

Siguiente: un personaje que se mueve y se anima.