feat: i18n achievement UI labels and data layer title/description

This commit is contained in:
2026-06-10 16:36:24 +08:00
parent e51b5e234e
commit 2f9f9a4117
10 changed files with 66 additions and 7 deletions

View File

@@ -86,7 +86,9 @@ export interface ChapterInfo {
export interface AchievementDef { export interface AchievementDef {
id: string id: string
title: string title: string
titleKey?: string
description: string description: string
descKey?: string
icon?: string icon?: string
hidden?: boolean hidden?: boolean
condition: Condition condition: Condition

View File

@@ -70,5 +70,19 @@
"trust_end": "Trusted Ally", "trust_end": "Trusted Ally",
"alone_end": "Lone Path", "alone_end": "Lone Path",
"continue_end": "Keep Moving Forward" "continue_end": "Keep Moving Forward"
},
"achievement": {
"qte_master": {
"title": "Reaction Master",
"desc": "Successfully complete a QTE"
},
"explorer": {
"title": "Explorer",
"desc": "Search every corner of the room"
},
"game_finished": {
"title": "Completed",
"desc": "Complete the game once"
}
} }
} }

View File

@@ -65,5 +65,19 @@
"trust_end": "信頼の仲間", "trust_end": "信頼の仲間",
"alone_end": "孤独の道", "alone_end": "孤独の道",
"continue_end": "前進を続ける" "continue_end": "前進を続ける"
},
"achievement": {
"qte_master": {
"title": "反射神経の達人",
"desc": "QTEを成功させる"
},
"explorer": {
"title": "探索者",
"desc": "部屋の隅々まで調べる"
},
"game_finished": {
"title": "クリア達成",
"desc": "ゲームを一度クリアする"
}
} }
} }

View File

@@ -70,5 +70,19 @@
"trust_end": "信任的伙伴", "trust_end": "信任的伙伴",
"alone_end": "独行之路", "alone_end": "独行之路",
"continue_end": "继续前行" "continue_end": "继续前行"
},
"achievement": {
"qte_master": {
"title": "反应达人",
"desc": "成功完成一次 QTE"
},
"explorer": {
"title": "探索者",
"desc": "搜索过房间的所有角落"
},
"game_finished": {
"title": "通关达成",
"desc": "完成一次游戏"
}
} }
} }

View File

@@ -16,7 +16,9 @@
{ {
"id": "qte_master", "id": "qte_master",
"title": "反应达人", "title": "反应达人",
"titleKey": "achievement.qte_master.title",
"description": "成功完成一次 QTE", "description": "成功完成一次 QTE",
"descKey": "achievement.qte_master.desc",
"icon": "", "icon": "",
"hidden": false, "hidden": false,
"condition": { "variable": "qte_succeeded", "op": ">=", "value": 1 } "condition": { "variable": "qte_succeeded", "op": ">=", "value": 1 }
@@ -24,7 +26,9 @@
{ {
"id": "explorer", "id": "explorer",
"title": "探索者", "title": "探索者",
"titleKey": "achievement.explorer.title",
"description": "搜索过房间的所有角落", "description": "搜索过房间的所有角落",
"descKey": "achievement.explorer.desc",
"icon": "", "icon": "",
"hidden": false, "hidden": false,
"condition": { "variable": "investigation", "op": ">=", "value": 2 } "condition": { "variable": "investigation", "op": ">=", "value": 2 }
@@ -32,7 +36,9 @@
{ {
"id": "game_finished", "id": "game_finished",
"title": "通关达成", "title": "通关达成",
"titleKey": "achievement.game_finished.title",
"description": "完成一次游戏", "description": "完成一次游戏",
"descKey": "achievement.game_finished.desc",
"icon": "", "icon": "",
"hidden": false, "hidden": false,
"condition": { "variable": "completed_game", "op": ">=", "value": 1 } "condition": { "variable": "completed_game", "op": ">=", "value": 1 }

View File

@@ -1,5 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import type { AchievementDef } from '@engine/types' import type { AchievementDef } from '@engine/types'
import { useI18n } from '@/composables/useI18n'
const { t } = useI18n()
defineProps<{ defineProps<{
definitions: AchievementDef[] definitions: AchievementDef[]
@@ -14,7 +17,7 @@ const emit = defineEmits<{
<template> <template>
<div class="ach-overlay" @click.self="emit('close')" @keydown.escape="emit('close')"> <div class="ach-overlay" @click.self="emit('close')" @keydown.escape="emit('close')">
<div class="ach-panel"> <div class="ach-panel">
<h2 class="ach-title">成就</h2> <h2 class="ach-title">{{ t('ui.achievements') }}</h2>
<div class="ach-list"> <div class="ach-list">
<div <div
@@ -29,16 +32,16 @@ const emit = defineEmits<{
</div> </div>
<div class="ach-body"> <div class="ach-body">
<div class="ach-title-text"> <div class="ach-title-text">
{{ !unlockedIds.has(ach.id) && ach.hidden ? '???' : ach.title }} {{ !unlockedIds.has(ach.id) && ach.hidden ? '???' : t(ach.titleKey || ach.title) }}
</div> </div>
<div class="ach-desc-text"> <div class="ach-desc-text">
{{ !unlockedIds.has(ach.id) && ach.hidden ? '' : ach.description }} {{ !unlockedIds.has(ach.id) && ach.hidden ? '' : t(ach.descKey || ach.description) }}
</div> </div>
</div> </div>
</div> </div>
</div> </div>
<button class="ach-close" @click="emit('close')">关闭</button> <button class="ach-close" @click="emit('close')">{{ t('ui.close') }}</button>
</div> </div>
</div> </div>
</template> </template>

View File

@@ -1,6 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, watch, ref } from 'vue' import { computed, watch, ref } from 'vue'
import type { AchievementDef } from '@engine/types' import type { AchievementDef } from '@engine/types'
import { useI18n } from '@/composables/useI18n'
const { t } = useI18n()
const props = defineProps<{ const props = defineProps<{
achievementId: string achievementId: string
@@ -32,9 +35,9 @@ watch(() => props.achievementId, (id) => {
<span v-else class="toast-star"></span> <span v-else class="toast-star"></span>
</div> </div>
<div class="toast-body"> <div class="toast-body">
<div class="toast-label">成就解锁</div> <div class="toast-label">{{ t('ui.achievementUnlocked') }}</div>
<div class="toast-title">{{ def.title }}</div> <div class="toast-title">{{ def ? t(def.titleKey || def.title) : '' }}</div>
<div class="toast-desc">{{ def.description }}</div> <div class="toast-desc">{{ def ? t(def.descKey || def.description) : '' }}</div>
</div> </div>
</div> </div>
</template> </template>

View File

@@ -24,6 +24,7 @@
"quitToMenu": "Back to Menu", "quitToMenu": "Back to Menu",
"pauseHint": "Esc = Resume", "pauseHint": "Esc = Resume",
"achievements": "Achievements", "achievements": "Achievements",
"achievementUnlocked": "Achievement Unlocked",
"gallery": "Gallery", "gallery": "Gallery",
"story": "Story Progress", "story": "Story Progress",
"startChapter": "Start", "startChapter": "Start",

View File

@@ -24,6 +24,7 @@
"quitToMenu": "メニューに戻る", "quitToMenu": "メニューに戻る",
"pauseHint": "Esc = 再開", "pauseHint": "Esc = 再開",
"achievements": "実績", "achievements": "実績",
"achievementUnlocked": "実績解除",
"gallery": "ギャラリー", "gallery": "ギャラリー",
"story": "ストーリー進行", "story": "ストーリー進行",
"startChapter": "開始", "startChapter": "開始",

View File

@@ -24,6 +24,7 @@
"quitToMenu": "返回主菜单", "quitToMenu": "返回主菜单",
"pauseHint": "Esc = 继续", "pauseHint": "Esc = 继续",
"achievements": "成就", "achievements": "成就",
"achievementUnlocked": "成就解锁",
"gallery": "画廊", "gallery": "画廊",
"story": "故事进度", "story": "故事进度",
"startChapter": "开始", "startChapter": "开始",