教程 5 — 菜单、选项、暂停与多语言
菜单
任何继承 MenuScene 的场景都是菜单:一个 $title,加上 items() 返回的若干行。
protected function items(): array
{
return [
// [标签, 右侧的值, 按回车时, 按左 / 右时]
['PLAY', null, fn () => $this->scenes()->switchTo(PlayScene::class, ['level' => 1])],
['VOLUME', fn () => round($this->sound()->getSfxVolume() * 100) . '%', null,
fn (int $dir) => $this->sound()->setSfxVolume($this->sound()->getSfxVolume() + $dir / 10)],
['OPTIONS', null, fn () => $this->scenes()->push(OptionsScene::class)],
];
}
protected function back(): void
{
$this->scenes()->pop(); // 子菜单中按 Esc
}
switchTo() 会替换当前画面(带淡入淡出),push() 会在其上再打开一个,pop() 则返回上一个。
暂停
暂停就是盖在游戏之上的菜单:isOverlay() 返回 true,下方的游戏画面依然会被绘制。
final class PauseScene extends MenuScene
{
protected string $title = 'PAUSE';
public function isOverlay(): bool
{
return true;
}
protected function items(): array
{
return [
['RESUME', null, fn () => $this->scenes()->pop()],
['TITLE SCREEN', null, fn () => $this->scenes()->switchTo(TitleScene::class)],
];
}
}
// 在游戏中:
if ($this->actions()->isPressed('pause')) {
$this->scenes()->push(PauseScene::class);
return;
}
在 game.yaml 中设置 pause_scene: App\Scene\PauseScene 后,当标签页被隐藏或窗口失去焦点时,暂停菜单也会自动打开。
多语言
config/lang.yaml 负责翻译文本(菜单标签会自动翻译):
fr:
PLAY: JOUER
'{n} COINS': '{n} PIECES'
代码中:Lang::t('{n} COINS', ['n' => $this->coins]);切换语言:
$this->engine->lang->setLang('fr')。