first commit

This commit is contained in:
jakciehan
2026-04-10 22:59:39 +08:00
commit cc2e7b9bb0
89 changed files with 23631 additions and 0 deletions
@@ -0,0 +1,260 @@
# 需求文档:UI文案国际化(i18n)
## 引言
《坦克探险》微信小游戏需要支持中英文双语UI。根据用户所在区域自动展示对应语言的文案,中文地区显示中文,其他地区显示英文。
---
## 技术方案
### 1. i18n 模块结构
`js/i18n/` 目录下创建以下文件:
- **`I18n.js`** — 核心管理器,负责语言检测和文案获取
- **`zh.js`** — 中文语言包
- **`en.js`** — 英文语言包
### 2. 语言检测
通过微信 `wx.getSystemInfoSync().language` 自动检测:
- `zh_CN``zh_TW``zh_HK` 等以 `zh` 开头 → 使用中文
- 其他 → 使用英文(默认 fallback)
### 3. 使用方式
各场景文件通过 `const { t } = require('../i18n/I18n');` 引入翻译函数:
- 简单文案:`t('menu.title')``'坦克探险'` / `'Tank Adventure'`
- 带参数模板:`t('pvp.hp', { count: 3 })``'生命 x3'` / `'HP x3'`
### 4. Key 命名规范
按场景分组,使用点号分隔:
- `menu.*` — 主菜单
- `room.*` — 双人对战房间
- `teamRoom.*` — 3v3团队房间
- `pvp.*` — 双人对战游戏
- `team.*` — 3v3团队游戏
- `pvpResult.*` — 双人对战结算
- `teamResult.*` — 3v3团队结算
- `game.*` — 经典模式
- `common.*` — 通用文案
---
## 需求
### 需求 1:创建 i18n 核心模块
**用户故事:** 作为开发者,我需要一个 i18n 模块来管理多语言文案,支持自动语言检测和带参数的文案模板。
#### 验收标准
1. 创建 `js/i18n/I18n.js`,提供 `t(key, params)` 函数
2. 创建 `js/i18n/zh.js`,包含所有中文文案
3. 创建 `js/i18n/en.js`,包含所有英文文案
4. 通过 `wx.getSystemInfoSync().language` 自动检测语言
5. 支持 `{variable}` 占位符插值
6. 缺失 key 时 fallback 到英文,仍缺失则返回 key 本身
---
### 需求 2:主菜单场景(MenuScenei18n 化
#### 验收标准
| Key | 中文 | 英文 |
|-----|------|------|
| `menu.title` | 坦克探险 | Tank Adventure |
| `menu.subtitle` | 经典坦克对战 | TANK WAR |
| `menu.classic` | 经典模式 | Classic |
| `menu.endless` | 无尽模式 | Endless |
| `menu.pvp` | 双人对战 | PVP |
| `menu.team3v3` | 3v3 对战 | 3v3 Battle |
| `menu.ranking` | 排行榜 | Ranking |
| `menu.settings` | 设置 | Settings |
---
### 需求 3:双人对战房间场景(RoomScenei18n 化
#### 验收标准
| Key | 中文 | 英文 |
|-----|------|------|
| `room.title` | 双人对战 | PVP Battle |
| `room.idleHint` | 创建房间或输入房间号加入 | Create a room or join with a code |
| `room.create` | 创建房间 | Create Room |
| `room.join` | 加入房间 | Join Room |
| `room.connecting` | 连接中{dots} | Connecting{dots} |
| `room.roomCode` | 房间号: | Room Code: |
| `room.waiting` | 等待对手加入{dots} | Waiting for opponent{dots} |
| `room.shareHint` | 将房间号分享给好友 | Share the room code with your friend |
| `room.inputCode` | 输入房间号: | Enter Room Code: |
| `room.opponentFound` | 对手已找到! | Opponent found! |
| `room.starting` | 即将开始... | Game starting... |
| `room.tapBack` | 点击任意位置返回 | Tap anywhere to go back |
| `common.back` | ← 返回 | ← Back |
| `common.joinBtn` | 加入 | Join |
| `common.cannotConnect` | 无法连接服务器 | Cannot connect to server |
| `common.connectFailed` | 连接失败 | Connection failed |
| `common.disconnected` | 与服务器断开连接 | Disconnected from server |
---
### 需求 43v3 团队房间场景(TeamRoomScenei18n 化
#### 验收标准
| Key | 中文 | 英文 |
|-----|------|------|
| `teamRoom.title` | 3v3 团队对战 | 3v3 Team Battle |
| `teamRoom.chooseMode` | 选择游戏方式 | Choose how to play |
| `teamRoom.createTeam` | 🎮 组队开黑 | 🎮 Create Team |
| `teamRoom.soloMatch` | ⚡ 快速匹配 | ⚡ Quick Match |
| `teamRoom.teamId` | 队伍:{id} | Team: {id} |
| `teamRoom.leader` | 队长 | Leader |
| `teamRoom.ready` | ✓ 已准备 | ✓ Ready |
| `teamRoom.notReady` | 未准备 | Not Ready |
| `teamRoom.emptySlot` | 空位 | Empty |
| `teamRoom.invite` | 📨 邀请好友 | 📨 Invite |
| `teamRoom.startMatch` | 🔍 开始匹配 | 🔍 Start Match |
| `teamRoom.disband` | 解散队伍 | Disband |
| `teamRoom.readyBtn` | ✓ 准备 | ✓ Ready |
| `teamRoom.cancelReady` | 取消准备 | Cancel Ready |
| `teamRoom.leaveTeam` | 退出队伍 | Leave Team |
| `teamRoom.matching` | 匹配中{dots} | Matching{dots} |
| `teamRoom.waitTime` | 已等待 {seconds} 秒 | Waited {seconds}s |
| `teamRoom.cancelMatch` | 取消匹配 | Cancel Match |
| `teamRoom.matchFound` | 对手已找到! | Match found! |
| `teamRoom.enterBattle` | 即将进入战斗... | Entering battle... |
| `teamRoom.tapBack` | 点击任意位置返回 | Tap anywhere to go back |
| `teamRoom.shareTitle` | 坦克3v3,速来开黑! | Tank 3v3, join the battle! |
| `common.kicked` | 你已被踢出队伍 | You have been kicked from the team |
---
### 需求 5:双人对战游戏场景(PvpGameScenei18n 化
#### 验收标准
| Key | 中文 | 英文 |
|-----|------|------|
| `pvp.playerLabel` | P{slot} (我方) | P{slot} (You) |
| `pvp.hp` | 生命 x{count} | HP x{count} |
| `pvp.kills` | 击杀:{count} | Kills: {count} |
| `common.paused` | 暂停 | PAUSED |
| `common.tapContinue` | 点击继续 | Tap to continue |
| `pvp.youWin` | 你赢了! | YOU WIN! |
| `pvp.draw` | 平局 | DRAW |
| `pvp.youLose` | 你输了 | YOU LOSE |
---
### 需求 63v3 团队对战游戏场景(TeamGameScenei18n 化
#### 验收标准
| Key | 中文 | 英文 |
|-----|------|------|
| `team.teamA` | A队 | Team A |
| `team.teamB` | B队 | Team B |
| `team.myTeam` | 我方:{team}队 | You: {team} Team |
| `team.killDeath` | 杀:{kills} 亡:{deaths} | K:{kills} D:{deaths} |
| `team.respawn` | {seconds}秒后重生 | Respawning in {seconds}s |
| `team.victory` | 胜利! | VICTORY! |
| `team.defeat` | 失败 | DEFEAT |
| `team.baseHpSummary` | A队:{hpA} 生命 \| B队:{hpB} 生命 | Team A: {hpA} HP \| Team B: {hpB} HP |
| `team.disconnectTitle` | ⚠ 连接断开 | ⚠ Connection Lost |
| `team.reconnecting` | 重连中{dots} ({attempts}/{max}) | Reconnecting{dots} ({attempts}/{max}) |
| `team.reconnectHint` | 请稍候,您的坦克将由AI代管 | Please wait, your tank will be controlled by AI |
---
### 需求 7:双人对战结算场景(PvpResultScenei18n 化
#### 验收标准
| Key | 中文 | 英文 |
|-----|------|------|
| `pvpResult.title` | 对战结果 | MATCH RESULT |
| `pvpResult.victory` | 🏆 胜利! | 🏆 VICTORY! |
| `pvpResult.draw` | ⚔️ 平局 | ⚔️ DRAW |
| `pvpResult.defeat` | 💀 失败 | 💀 DEFEAT |
| `pvpResult.kills` | 击杀 | Kills |
| `pvpResult.lives` | 生命 | Lives |
| `pvpResult.timeRemaining` | 剩余时间:{time} | Time remaining: {time} |
| `pvpResult.rematch` | 再来一局 | Rematch |
| `pvpResult.backMenu` | 返回菜单 | Back to Menu |
---
### 需求 83v3 团队结算场景(TeamResultScenei18n 化
#### 验收标准
| Key | 中文 | 英文 |
|-----|------|------|
| `teamResult.title` | 3v3 对战结果 | 3v3 MATCH RESULT |
| `teamResult.victory` | 🏆 胜利! | 🏆 VICTORY! |
| `teamResult.defeat` | 💀 失败 | 💀 DEFEAT |
| `teamResult.teamAHp` | A队:{hp} 生命 | Team A: {hp} HP |
| `teamResult.teamBHp` | B队:{hp} 生命 | Team B: {hp} HP |
| `teamResult.baseDestroyed` | 基地被摧毁 | Base Destroyed |
| `teamResult.disconnectedReason` | 断线 | Disconnected |
| `teamResult.teamAHeader` | A队 | Team A |
| `teamResult.teamBHeader` | B队 | Team B |
| `teamResult.myTeamSuffix` | (我方) | (You) |
| `teamResult.player` | 玩家 | Player |
| `teamResult.k` | 杀 | K |
| `teamResult.d` | 亡 | D |
| `teamResult.a` | 助 | A |
| `teamResult.dmg` | 伤害 | DMG |
| `teamResult.bot` | 🤖 机器人 | 🤖 Bot |
| `teamResult.duration` | 对战时长:{time} | Match duration: {time} |
| `teamResult.mvp` | ⭐ MVP{name}{kills} 击杀) | ⭐ MVP: {name} ({kills} kills) |
| `teamResult.rankUp` | 📈 积分 +{points} | 📈 Rank +{points} |
| `teamResult.mvpBonus` | MVP加成 +5 | (MVP bonus +5) |
| `teamResult.rankDown` | 📉 积分 -{points} | 📉 Rank -{points} |
| `teamResult.rematch` | 再来一局 | Rematch |
| `teamResult.backMenu` | 返回菜单 | Back to Menu |
---
### 需求 9:经典模式游戏场景(GameScenei18n 化
#### 验收标准
| Key | 中文 | 英文 |
|-----|------|------|
| `game.level` | 第 {level} 关 | Level {level} |
| `game.hp` | 生命 x{count} | HP x{count} |
| `game.fireLevel` | LV{level} | LV{level} |
| `game.enemies` | 敌人: {count} | Enemies: {count} |
| `game.score` | {score}分 | {score}pts |
| `game.gameOver` | 游戏结束 | GAME OVER |
| `game.stageClear` | 关卡通过! | STAGE CLEAR! |
---
## 边界情况与技术约束
### 边界情况
1. **中文字体渲染**Canvas 中使用 `'Arial'` 字体渲染中文时,微信小游戏环境下系统会自动 fallback 到系统中文字体,无需额外处理。
2. **文案长度变化**:中英文文案长度不同,替换后需确认UI布局不会溢出或错位。
3. **`GameScene` 中的字符串比较**`text === '游戏结束'` 改为 `text === t('game.gameOver')`,确保逻辑不受语言影响。
4. **错误消息来源**:部分错误消息可能来自服务端(如 `data.message`),本次仅替换客户端硬编码的文案。
### 技术约束
1. 所有文案替换涉及 `js/scenes/` 目录下的场景文件和新建的 `js/i18n/` 模块。
2. 替换操作不应影响游戏逻辑,仅修改展示层的字符串。
3. 不需要在设置页面增加语言切换选项,完全依赖微信系统语言自动检测。
### 成功标准
1. 中文区域用户看到全中文UI,非中文区域用户看到全英文UI。
2. 替换后游戏功能正常,无因文案修改导致的逻辑错误。
3. 文案在各场景中布局合理,无溢出或错位现象。
@@ -0,0 +1,75 @@
# 实施计划:UI英文文案统一替换为中文
- [ ] 1. MenuScene 主菜单英文文案中文化
- 将副标题 `'TANK WAR'` 替换为 `'经典坦克对战'`
- 检查替换后文本居中是否正常,必要时调整绘制坐标
- _需求:1.1_
- [ ] 2. RoomScene 双人对战房间英文文案中文化
- 替换空闲状态提示 `'Create a room or join with a code'``'创建房间或输入房间号加入'`
- 替换连接状态 `'Connecting...'``'连接中...'`
- 替换等待状态 `'Room Code:'``'房间号:'``'Waiting for opponent...'``'等待对手加入...'``'Share the room code with your friend'``'将房间号分享给好友'`
- 替换输入状态 `'Enter Room Code:'``'输入房间号:'`
- 替换倒计时状态 `'Opponent found!'``'对手已找到!'``'Game starting...'``'即将开始...'`
- 替换错误状态 `'Tap anywhere to go back'``'点击任意位置返回'`
- 替换错误消息 `'Cannot connect to server'``'无法连接服务器'``'Connection failed'``'连接失败'``'Disconnected from server'``'与服务器断开连接'`
- _需求:2.1 ~ 2.12_
- [ ] 3. TeamRoomScene 3v3团队房间英文文案中文化
- 替换模式选择提示 `'Choose how to play'``'选择游戏方式'`
- 替换队伍ID显示 `'Team: xxx'``'队伍:xxx'`
- 替换错误消息 `'Cannot connect to server'``'无法连接服务器'``'You have been kicked from the team'``'你已被踢出队伍'``'Connection failed'``'连接失败'``'Disconnected from server'``'与服务器断开连接'`
- _需求:3.1 ~ 3.6_
- [ ] 4. PvpGameScene 双人对战游戏场景英文文案中文化
- 替换暂停覆盖层 `'PAUSED'``'暂停'``'Tap to continue'``'点击继续'`
- 替换游戏结束覆盖层 `'YOU WIN!'``'你赢了!'``'DRAW'``'平局'``'YOU LOSE'``'你输了'`
- 替换HUD玩家标识 `'P1 (You)'` / `'P2 (You)'``'P1 (我方)'` / `'P2 (我方)'`
- 替换HUD生命值 `'HP'``'生命'`
- 替换HUD击杀数 `'Kills:'``'击杀:'`
- _需求:4.1 ~ 4.8_
- [ ] 5. TeamGameScene 3v3团队对战游戏场景英文文案中文化
- 替换暂停覆盖层 `'PAUSED'``'暂停'``'Tap to continue'``'点击继续'`
- 替换游戏结束覆盖层 `'VICTORY!'``'胜利!'``'DEFEAT'``'失败'`
- 替换游戏结束基地HP显示 `'Team A: x HP | Team B: x HP'``'A队:x 生命 | B队:x 生命'`
- 替换HUD队伍标签 `'Team A'``'A队'``'Team B'``'B队'`
- 替换HUD玩家所属队伍 `'You: Team A'``'我方:A队'`
- 替换HUD队伍统计 `'K:x D:x'``'杀:x 亡:x'`
- 替换重生倒计时 `'Respawning in Xs'``'X秒后重生'`
- _需求:5.1 ~ 5.9_
- [ ] 6. PvpResultScene 双人对战结算场景英文文案中文化
- 替换结算标题 `'MATCH RESULT'``'对战结果'`
- 替换胜负结果 `'🏆 VICTORY!'``'🏆 胜利!'``'⚔️ DRAW'``'⚔️ 平局'``'💀 DEFEAT'``'💀 失败'`
- 替换玩家标识 `'P1 (You)'` / `'P2 (You)'``'P1 (我方)'` / `'P2 (我方)'`
- 替换统计表头 `'Kills'``'击杀'``'Lives'``'生命'`
- 替换剩余时间 `'Time remaining:'``'剩余时间:'`
- _需求:6.1 ~ 6.7_
- [ ] 7. TeamResultScene 3v3团队结算场景英文文案中文化
- 替换结算标题 `'3v3 MATCH RESULT'``'3v3 对战结果'`
- 替换胜负结果 `'🏆 VICTORY!'``'🏆 胜利!'``'💀 DEFEAT'``'💀 失败'`
- 替换基地HP `'Team A: x HP'``'A队:x 生命'``'Team B: x HP'``'B队:x 生命'`
- 替换胜负原因 `'Base Destroyed'``'基地被摧毁'``'Disconnected'``'断线'`
- 替换统计表头 `'Team A (You)'` / `'Team B (You)'``'A队 (我方)'` / `'B队 (我方)'`
- 替换列标题 `'Player'``'玩家'``'K'``'杀'``'D'``'亡'``'A'``'助'``'DMG'``'伤害'`
- 替换对战时长 `'Match duration:'``'对战时长:'`
- 替换MVP信息 `'⭐ MVP: xxx (x kills)'``'⭐ MVPxxxx 击杀)'`
- 替换段位积分 `'📈 Rank +x'``'📈 积分 +x'``'(MVP bonus +5)'``'MVP加成 +5'``'📉 Rank -x'``'📉 积分 -x'`
- 替换Bot名称 `'Bot'``'机器人'`
- _需求:7.1 ~ 7.11_
- [ ] 8. GameScene 经典模式游戏场景英文文案中文化
- 替换HUD生命值 `'HP'``'生命'`
- 替换游戏结束文案 `'GAME OVER'``'游戏结束'``'STAGE CLEAR'``'关卡通过'`(如存在)
- **注意**:同步修改代码中 `text === 'GAME OVER'` 等字符串比较逻辑,改为 `text === '游戏结束'`
- 火力等级 `'LV'` 为通用缩写,可保留不改
- _需求:8.1 ~ 8.3_
- [ ] 9. 全局UI布局验证与字体适配
- 检查所有场景中 Canvas 字体设置,确认中文渲染正常(如 `'Arial'` 字体对中文的支持)
- 验证中文文案替换后各场景的文本居中、按钮宽度、布局间距是否正常
- 对文案长度变化较大的位置(如 `'Share the room code with your friend'``'将房间号分享给好友'`)重点检查是否溢出
- 确保模板字符串中的动态变量插值逻辑未被破坏
- _需求:边界情况 1、2、3、5_