KO

튜토리얼 5 — 메뉴, 옵션, 일시정지, 언어

메뉴

MenuScene을 상속하는 장면은 모두 메뉴예요. $title과 items()의 항목들로 구성돼요.

protected function items(): array
{
    return [
        // [라벨, 오른쪽 값, Enter를 눌렀을 때, 좌우 키를 눌렀을 때]
        ['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')를 호출해요.