feat: i18n system, lang switch component, english subtitles, UI improvements, roadmap update

This commit is contained in:
2026-06-09 15:40:51 +08:00
parent 6b4114af43
commit 59aed77199
16 changed files with 410 additions and 33 deletions

View File

@@ -3,11 +3,13 @@ import { Engine } from '@engine/core/Engine'
import { SaveSystem } from '@engine/systems/SaveSystem'
import type { GameData } from '@engine/types'
import { useGameStore } from '@/stores/gameStore'
import { useI18n } from '@/composables/useI18n'
export function useGameEngine(videoEls: () => [HTMLVideoElement | null, HTMLVideoElement | null]) {
const engine = new Engine()
const saveSystem = new SaveSystem()
const store = useGameStore()
const { t } = useI18n()
let lastThumbnail: string | undefined
if (import.meta.env.DEV) {
@@ -34,7 +36,11 @@ export function useGameEngine(videoEls: () => [HTMLVideoElement | null, HTMLVide
})
engine.on('choiceRequest', (choiceList) => {
store.setChoices(choiceList)
const translated = choiceList.map((c: any) => ({
...c,
text: c.textKey ? t(c.textKey) : c.text,
}))
store.setChoices(translated)
})
engine.on('choiceTimer', (timerState) => {

View File

@@ -0,0 +1,28 @@
import { ref } from 'vue'
import zh from '@/locales/zh.json'
import en from '@/locales/en.json'
const messages = { zh, en } as const
type Lang = 'zh' | 'en'
const currentLang = ref<Lang>(
(localStorage.getItem('lang') as Lang) || 'zh'
)
export function useI18n() {
function t(key: string): string {
const parts = key.split('.')
let result: any = messages[currentLang.value]
for (const p of parts) {
result = result?.[p]
}
return typeof result === 'string' ? result : key
}
function setLang(lang: Lang) {
currentLang.value = lang
localStorage.setItem('lang', lang)
}
return { t, currentLang, setLang }
}