Files
test1/.docs/tasks/task-2ab-gameplay-completion.md

224 lines
8.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Task 2A+2B: 周报结算系统 + 特殊技能完善 + 胜利失败界面 + 怪物语录
## 任务概要
在已完成的游戏基础框架上实现周报结算弹窗每3波触发、完善各塔特殊技能、实现胜利/失败结算界面、以及怪物头顶语录飘字系统。
**前置条件**Task 1A+1B+1C+1D 已完成,完整的游戏框架已运行。
## 需要了解的已有文件
先读取以下文件了解现有实现:
- `game/GameManager.ts`(游戏状态,了解事件系统接口)
- `game/GameScene.ts`主场景了解如何集成新UI
- `game/ui/HUD.ts`已有HUD了解胜利/失败通知已有实现)
- `game/enemies/WaveManager.ts`(了解波次完成事件是如何触发的)
## 实现内容
### 1. 周报结算弹窗(`game/ui/WeeklyReportModal.ts`
**触发时机**第3波结束后WaveManager 已有 `onWeeklyReport` 回调)
**弹窗设计**(全屏覆盖 DOM 层,仿钉钉/飞书全屏通知):
```
[全屏黑色半透明背景z-index: 9999]
[中央弹窗卡片,深色背景 #1a1a2e霓虹紫边框]
标题:"📊 周报提交时间!"(用 img/SVG 图标代替 emoji或纯文字
副标题:"请选择正确的互联网黑话,提交本周工作总结"
[10秒倒计时进度条] — 顶部红色进度条,从满到空
3个选项卡片随机从黑话题库选3个其中1个是"正确答案"
[选项A] [选项B] [选项C]
答题结果区域(答题后显示):
- 选对:绿色提示 "正确!获得奖励:+80 HC" 或 "全场精力已补满"
- 选错/超时:红色提示 "答错了老板视察3秒全场塔禁锢"
```
**黑话题库**(在 `game/data/buzzwords.ts` 中定义100条
```typescript
// 分为两类:正确答案类(互联网常见黑话)+ 干扰项
export const BUZZWORDS = [
// 正确答案(真实大厂黑话)
"赋能", "对齐", "颗粒度", "打通", "闭环", "抓手", "生态", "赛道",
"护城河", "降维打击", "底层逻辑", "顶层设计", "方法论", "复盘",
"迭代", "串联", "拉齐", "落地", "沉淀", "跑通", "MVP", "ROI",
"私域流量", "增量市场", "存量竞争", "心智占位", "势能积累",
"组织赋能", "生态打通", "战略对齐", "价值共创", "协同增效",
"降本增效", "提质增效", "精益管理", "敏捷开发", "极致体验",
"用户心智", "品牌溢价", "流量变现", "私域运营", "全渠道",
"中台建设", "数字化转型", "智能升级", "生态圈", "护城河",
"弯道超车", "换道超车", "破圈", "出圈", "刷屏", "爆款",
"现象级", "标杆案例", "对标", "copy from", "跑模型",
// 干扰项(故意写错/不通顺的)
"增熵赋能", "横向闭环", "负向对齐", "反底层逻辑",
]
// 每次从 BUZZWORDS 随机取3个其中第一个是"正确答案"
// 随机打乱顺序后展示
export function generateWeeklyOptions(): { options: string[], correctIndex: number } {
const shuffled = [...BUZZWORDS].sort(() => Math.random() - 0.5)
const correct = shuffled[0]
const options = [correct, shuffled[1], shuffled[2]].sort(() => Math.random() - 0.5)
return {
options,
correctIndex: options.indexOf(correct)
}
}
```
**倒计时逻辑**
- 10秒倒计时使用 `setInterval`
- 超时自动触发"选错"结果
- 选择后立即停止倒计时,显示结果 2 秒后自动关闭弹窗
**结果逻辑**
```typescript
// 选对随机50%概率给HC50%概率补满精力
if (Math.random() > 0.5) {
gameManager.addHC(50 + Math.floor(Math.random() * 50))
showResult('success', `获得 ${reward} HC继续加油`)
} else {
// 通知所有塔补满精力(通过 GameScene 的回调)
onFullStamina()
showResult('success', '全场精力已补满!')
}
// 选错/超时触发全场塔禁锢3秒
onBossInspection() // 调用 GameScene 的回调,禁锢所有塔
showResult('error', '老板来视察了全场禁锢3秒')
```
### 2. 完善胜利/失败界面(更新 `game/ui/HUD.ts` 或单独文件)
当前 HUD 可能已有简单的胜利/失败提示,需要升级为完整的模态弹窗。
**失败弹窗**KPI 归零时触发,仿钉钉退群通知):
```
[弹窗容器,白色背景,仿钉钉卡片样式]
[顶部蓝色条] 系统通知
[钉钉风格图标]
正文:
鉴于您近期的表现未能达成业务闭环,
经公司管理层研究决定,
对您进行"毕业"处理。
请于5分钟内归还工牌不要带走办公文具。
[领取 N+1] (重新开始,刷新页面)
[申请仲裁] (返回主页,跳转 /)
```
**胜利弹窗**全6波清空后仿绩效评级系统
```
[弹窗容器,深色背景,金色边框]
标题:绩效评级公示
最终KPI: XX%
消灭怪物: XX只
剩余HC: XX
绩效等级:
- KPI >= 80%: S级 "超出预期"
- KPI >= 60%: A级 "达成预期"
- KPI >= 40%: B级 "基本达成"
- KPI < 40%: C级 "未达预期"
等级对应奖励描述(黑色幽默):
- S级"恭喜晋升为高级打工人!福报已在路上..."
- A级"表现良好明年涨薪3%(扣去通胀后-2%"
- B级"还需努力下月开始996"
- C级"已被纳入待优化名单"
[再战一局] (重新开始)
[见好就收] (返回主页)
```
### 3. 怪物头顶语录飘字(更新 `game/enemies/EnemyBase.ts`
EnemyBase 中的 `quoteText` 字段已预留。现在实现完整的语录系统:
**`game/data/quotes.ts`**100条语录分怪物类型
```typescript
export const QUOTES = {
FreshGraduate: [
"求转正!", "我愿意加班!", "卷!卷!卷!",
"内推有名额吗?", "实习补贴够买咖啡吗?",
"我会CRUD", "熟练掌握Word和Excel",
"我有五年实习经验!", "大厂梦...", "期待来公司学习!",
"我不需要工资,只需要经验!", "比同龄人卷!",
],
OldEmployee: [
"我为公司立过功!", "我有10年经验",
"年龄不是问题!", "那时候还是我搭的架构",
"当年我一个人顶三个人!", "这个需求做不了",
"怎么可能这么快做完!", "文档?从来没有!",
"测试QA负责的", "这是历史遗留问题",
],
TroubleMaker: [
"录音笔已开启", "这是违法的!",
"我要仲裁!", "劳动法第X条规定...",
"我已咨询过律师", "保留证据中...",
"你们的违规操作我都记录了", "看我不告你们!",
],
BossVP: [
"我来教大家怎么做事", "你们缺乏战略眼光",
"这不是执行力的问题", "格局太小了",
"你们都不懂商业本质", "要有全局思维",
"小事不过手,大事全拍板", "你们的方案需要颠覆性重构",
"我在BAT做过这个", "先对齐一下认知",
],
}
```
**语录飘字动效**
- 怪物出生后 0.5 秒显示语录(随机从该类型的语录库中取)
- 字体VT323白色
- 文字在怪物头顶30px处显示
- 3秒后淡出alpha 从1到0的 Tween 动画)
- 文字跟随怪物移动
### 4. 全场塔禁锢效果(`GameScene` 中添加)
当周报答错/超时时,触发"老板视察"
```typescript
// 在 GameScene 中添加
freezeAllTowers(duration: number = 3000): void {
this.towerManager.getAllTowers().forEach(tower => {
tower.isFrozen = true
// 视觉:塔变灰色
setTimeout(() => {
tower.isFrozen = false
// 视觉:恢复正常颜色
}, duration)
})
}
refillAllStamina(): void {
this.towerManager.getAllTowers().forEach(tower => {
tower.stamina = tower.maxStamina
tower.isActive = true
})
}
```
在 TowerBase 的 `update()` 中检查 `isFrozen` 状态,如果为 true 则跳过攻击。
## 验收标准
1. 第3波全部怪物消灭后弹出周报弹窗有10秒倒计时
2. 选对答案随机给予HC奖励或补满精力
3. 选错/超时全场塔3秒无法攻击显示灰色
4. KPI归零时弹出仿钉钉失败弹窗两个按钮功能正确
5. 第6波全部消灭后弹出绩效评级胜利弹窗根据最终KPI显示正确等级
6. 所有怪物头顶有飘字语录随怪物移动3秒后淡出
## 相关上下文
- 设计系统:`design-system/大厂保卫战/MASTER.md`
- PRD`.docs/prd-tower-defense-game.md`
- 计划文档:`.docs/plans/2026-03-21-tower-defense-game.md`
- 开发规范:`@rules/dev-best-practices.md`**必须先阅读**
- 原子提交规范:`@rules/atomic-commit.md`
完成开发后,按 `@rules/atomic-commit.md` 规范,将变更按逻辑模块分组提交(禁止 `git add .`),确保所有文件均已 commit 后再结束任务。