教程 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(方向键、回车、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]]));
}
}
/** 各行:[标签, 右侧显示的值, 按回车时的动作, 按左 / 右时的动作] */
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 像素),放大 2 倍,居中,带黑色阴影
$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。
下一篇:会移动、会动画的角色。