Tutorial 1 — Hello world: un menu, un testo, un suono
Il gioco JumPHP più piccolo possibile: una schermata del titolo con un menu (gioca, suono, esci), poi un testo che si
sposta con le frecce e un suono alla pressione di Spazio. Due file. Puoi modificarlo subito nella
sandbox, oppure crearlo a casa tua con bin/jumphp new hello-world.
La configurazione: config/game.yaml
game:
id: hello-world
title: "HELLO WORLD"
width: 320 # la risoluzione del gioco, ingrandita alle dimensioni dello schermo
height: 180
start_scene: App\Scene\TitleScene
touch: { a: Space, b: Escape, start: Return } # i pulsanti del pad sul telefono
smoke: # ciò che `bin/jumphp test` gioca da solo, senza schermo
scene: App\Scene\HelloScene
params: { demo: true }
I tasti: il motore definisce già up down left right confirm back pause (frecce, Invio, Esc, il
gamepad, il touch screen). Si aggiunge un'azione in config/input.yaml:
actions:
jump: [Space, pad0:a, touch:tap]
La schermata del titolo: src/Scene/TitleScene.php
Un menu si scrive ereditando da MenuScene: si danno il titolo e le righe, il motore pensa al resto
(disegno, spostamento con tastiera / gamepad / dito, suoni del menu).
final class TitleScene extends MenuScene
{
protected string $title = 'HELLO WORLD';
public function enter(array $params = []): void
{
parent::enter($params);
// suoni fabbricati in PHP: nessun file audio necessario
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]]));
}
}
/** Le righe: [etichetta, valore mostrato a destra, azione su Invio, azione su sinistra / destra] */
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()]; // niente «esci» nel browser
}
return $items;
}
private function toggleSound(): void
{
$this->sound()->setMuted(!$this->sound()->isMuted());
$this->refresh(); // il menu mostra di nuovo il nuovo valore
}
}
I suoni menu_move e menu_confirm vengono riprodotti automaticamente dal menu. Le etichette sono tradotte
con config/lang.yaml (fr: { PLAY: JOUER }).
Il gioco: src/Scene/HelloScene.php
Una scena ha tre metodi essenziali:
enter($params): la scena inizia. Azzera tutto qui: la stessa scena viene riutilizzata più volte;update($dt): 60 volte al secondo si cambia lo stato del gioco.$dtè il tempo trascorso in secondi;render($r): si disegna, e nient'altro.
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» che sale
}
}
public function update(float $dt): void
{
if ($this->actions()->isPressed('back')) { // Esc: ritorno al titolo
$this->scenes()->switchTo(TitleScene::class);
return;
}
// axis() vale -1, 0 o 1: 90 pixel al secondo
$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]);
// il font integrato (5 × 7 pixel), ingrandito 2 volte, centrato, con un'ombra nera
$this->font()->draw($r, 'HELLO WORLD!', $this->x, $this->y, 2, [255, 220, 80], 'center', [0, 0, 0]);
}
}
Il file vero aggiunge stelle che sprizzano a ogni suono, un testo che cambia colore e una modalità demo per i test: leggilo nei sorgenti del gioco.
Provare
- Nella sandbox: cambia il testo, il colore
[255, 220, 80], la velocità, il suono (Synth::tone(220, 0.3, 'triangle')), poi ▶ Testa. - A casa tua:
bin/jumphp run hello-world,bin/jumphp test hello-world.
Prossimo passo: un personaggio che si muove e si anima.