152 lines
13 KiB
Markdown
152 lines
13 KiB
Markdown
# 实施计划:坦克大作战(微信小游戏版)
|
||
|
||
> **技术栈**:纯 JavaScript + 原生 Canvas API(微信小游戏环境),不依赖 Cocos Creator 等重型引擎。
|
||
> **参考需求文档**:`.codebuddy/plan/tankwar/requirements.md`
|
||
|
||
---
|
||
|
||
- [x] 1. 搭建微信小游戏项目基础框架与游戏主循环
|
||
- 创建微信小游戏项目结构(`game.js`、`game.json`、`project.config.json` 等)
|
||
- 实现 Canvas 初始化、屏幕适配(获取设备宽高,计算游戏区域缩放比例)
|
||
- 实现游戏主循环(`requestAnimationFrame`),包含 `update(dt)` 和 `render(ctx)` 两阶段
|
||
- 实现场景管理器(SceneManager),支持主菜单、游戏关卡、结算界面等场景的注册与切换
|
||
- 实现对象池(ObjectPool)工具类,用于子弹、爆炸特效等高频对象的复用
|
||
- 实现资源管理器(ResourceManager),使用 `wx.createImage` 预加载图片资源,支持加载进度回调
|
||
- _需求:1.1、1.2、1.3、1.4_
|
||
|
||
- [x] 2. 实现地图系统与地形渲染
|
||
- 定义地图数据结构(13×21 网格,每格用数字编码表示地形类型:空地/砖块/钢铁/河流/森林/基地)
|
||
- 编写至少 5 个预设关卡的地图配置数据(JSON 格式),包含教学关、河流关、重甲关等
|
||
- 实现 MapManager 类,负责从关卡配置加载地图、渲染地形 Tile、管理地形状态(砖块可被摧毁)
|
||
- 实现各地形类型的碰撞属性:砖块(可破坏/阻挡)、钢铁(Lv3可破/阻挡)、河流(阻挡坦克/子弹穿越)、森林(遮挡层/可通行)
|
||
- 实现基地区域渲染(老鹰图标 + 砖块围墙),基地被击中即摧毁的判定逻辑
|
||
- _需求:2.1、2.2、2.3、2.4、2.5、2.6、2.7、6.1_
|
||
|
||
- [x] 3. 实现玩家坦克与触控操作系统
|
||
- 实现 Tank 基类(位置、方向、速度、血量、渲染、碰撞盒等通用属性和方法)
|
||
- 实现 PlayerTank 子类,包含火力等级(Lv1-Lv3)、生命数、无敌状态、重生逻辑
|
||
- 实现虚拟摇杆组件(Joystick):监听 `touchstart/touchmove/touchend` 事件,左下角渲染摇杆UI,输出四方向(上/下/左/右)
|
||
- 实现发射按钮组件(FireButton):右下角渲染按钮UI,点击触发发射,根据火力等级限制同屏子弹数(Lv1=1颗,Lv2/Lv3=2颗)
|
||
- 实现坦克与地形的碰撞检测(矩形碰撞),阻止坦克进入不可通行区域
|
||
- _需求:3.1、3.2、3.3、3.4、3.5、3.6、3.7_
|
||
|
||
- [x] 4. 实现子弹系统与碰撞检测引擎
|
||
- 实现 Bullet 类(位置、方向、速度、所属阵营、是否破钢),从对象池获取/回收
|
||
- 实现碰撞检测管理器(CollisionManager),每帧检测:子弹↔地形、子弹↔坦克、子弹↔子弹、子弹↔基地、坦克↔坦克
|
||
- 实现子弹击中砖块的破坏逻辑(普通子弹破坏1格砖块,Lv3子弹破坏更大范围)
|
||
- 实现子弹击中钢铁的逻辑(Lv1/Lv2反弹/消失,Lv3摧毁钢铁)
|
||
- 实现敌我子弹对撞抵消逻辑
|
||
- 实现爆炸特效(帧动画),使用对象池管理
|
||
- _需求:2.2、2.3、3.6、4.8、6.1_
|
||
|
||
- [x] 5. 实现敌方坦克AI与刷新系统
|
||
- 实现 EnemyTank 子类,支持4种类型配置:普通(标准属性)、快速(高速/1HP)、重甲(低速/2-4HP)、精英BOSS(高HP/智能AI)
|
||
- 实现敌方坦克刷新管理器(SpawnManager):从地图顶部3个出生点轮流刷新,控制同屏最大数量和刷新间隔,每关总计约20辆
|
||
- 实现基础AI状态机:巡逻状态(随机方向移动+定时射击)→ 追击状态(朝基地方向移动)
|
||
- 实现进阶AI行为:A*简化寻路(方向权重算法),支持绕路偷家(关卡≥10)和集火基地(关卡≥15)
|
||
- 实现敌方坦克被击毁的判定、计数和特效
|
||
- _需求:4.1、4.2、4.3、4.4、4.5、4.6、4.7_
|
||
|
||
- [x] 6. 实现道具系统
|
||
- 实现 PowerUp 类(类型、位置、存在时间、闪烁动画),支持6种道具:星星、时钟、炸弹、钢盔、铲子、坦克+1
|
||
- 实现道具生成逻辑:击毁特定标记敌方坦克后在随机位置生成道具,15秒后消失
|
||
- 实现各道具拾取效果:星星(升级火力)、时钟(冻结敌人10秒)、炸弹(清屏)、钢盔(无敌15秒+护盾特效)、铲子(基地围墙变钢铁20秒)、坦克+1(加命)
|
||
- 实现道具掉落概率配置表,根据关卡编号动态调整(高关卡降低星星概率)
|
||
- _需求:5.1、5.2、5.3、5.4、5.5、5.6、5.7、5.8_
|
||
|
||
- [x] 7. 实现关卡流程、胜负判定与结算系统
|
||
- 实现 LevelManager 类:管理关卡加载、敌人波次、胜负条件检测、关卡切换
|
||
- 实现胜利判定(所有敌人被消灭+基地存活)和失败判定(基地被毁或生命归零)
|
||
- 实现关卡结算界面:展示击杀统计(各类型坦克数量)、得分计算(击杀数×系数 + 时间奖励 + 基地存活奖励)
|
||
- 实现关卡难度曲线配置:前3关教学→第5关河流→第10关重甲→第20关BOSS,通关后循环并提升难度
|
||
- 实现玩家死亡→复活/Game Over流程(含广告复活入口预留)
|
||
- _需求:6.1、6.2、6.3、6.4、7.1、7.2、7.3、7.4、7.5、7.6、7.7、3.8_
|
||
|
||
- [x] 8. 实现UI系统(主菜单、HUD、暂停、新手引导)
|
||
- 实现主菜单场景:游戏标题、经典模式/无尽模式/双人对战/排行榜/设置按钮,纯Canvas绘制
|
||
- 实现战斗HUD:顶部显示当前关卡、剩余敌人数(坦克小图标)、玩家生命数、火力等级指示
|
||
- 实现暂停功能:暂停按钮 + 暂停菜单弹窗(继续/重新开始/返回主菜单)
|
||
- 实现新手引导:首次进入游戏时展示2-3步操作提示(摇杆移动→射击按钮→保护基地)
|
||
- 实现设置界面:音效开关、音乐开关、振动开关,使用 `wx.setStorageSync` 持久化设置
|
||
- 实现音效系统:使用 `wx.createInnerAudioContext` 管理射击、爆炸、道具拾取、胜利/失败等音效
|
||
- _需求:12.1、12.2、12.3、12.4、12.5、12.6、1.1_
|
||
|
||
- [x] 9. 实现数据持久化与微信云排行榜
|
||
- 实现 StorageManager 类:封装 `wx.setStorageSync/getStorageSync`,管理本地存档(当前关卡、最高分、生命数、皮肤、设置项)
|
||
- 实现通关自动存档和启动时读档恢复逻辑
|
||
- 实现微信云开发接入:云数据库初始化、得分上传云函数、排行榜数据查询
|
||
- 实现开放数据域(子域)排行榜:通过 SharedCanvas 展示微信好友排名(按最高关卡/最高得分排序)
|
||
- 实现分享功能:通关后生成"挑战书"分享卡片(`wx.shareAppMessage`),支持带参数跳转
|
||
- 实现网络异常处理:上传失败时缓存数据,网络恢复后自动重试
|
||
- _需求:9.1、9.2、9.3、9.4、9.5、11.1、11.2、11.3、11.4_
|
||
|
||
- [x] 10. 实现商业化系统(广告、内购)与游戏模式扩展
|
||
- 实现广告管理器(AdManager):封装激励视频(`wx.createRewardedVideoAd`)和插屏广告(`wx.createInterstitialAd`)的创建、加载、展示、失败回调
|
||
- 实现广告触发点:死亡复活(激励视频)、结算双倍奖励(激励视频)、局间插屏(每3局最多1次频控)
|
||
- 实现广告加载失败的降级方案(提示稍后重试或给予少量奖励)
|
||
- 实现内购接口预留:永久去广告、皮肤包购买(`wx.requestMidasPayment` 或虚拟支付)
|
||
- 实现无尽模式:无限波次敌人刷新,记录最高击杀数,首次需观看广告解锁
|
||
- 实现双人对战模式框架:房间创建/加入UI、微信好友邀请、基于帧同步的实时对战基础通信(可作为后续迭代重点)
|
||
- 实现小游戏生命周期处理:`wx.onShow/onHide` 自动暂停/恢复,后台切换保护
|
||
- _需求:8.1、8.2、8.3、8.4、10.1、10.2、10.3、10.4、10.5、10.6、11.5_
|
||
|
||
- [ ] 11. 移除时间限制并修正全局常量与服务端胜负逻辑
|
||
- 在 `GameGlobal.js` 中移除 `TEAM_ROUND_TIME` 常量(或将其设为 0 / Infinity 表示不限时),确保不再作为对战时间限制使用
|
||
- 修改 `server/index.js` 中 `startTeamGame()` 函数:移除 `gameTimer`(setTimeout 超时结束对战的逻辑),对战不再因时间到期而结束
|
||
- 修改 `server/index.js` 中 `endTeamGame()` 函数:移除 `timeout` 分支的基地血量比较逻辑,唯一的结束原因为 `base_destroyed`(某方基地被摧毁)
|
||
- 修改 `server/index.js` 中 `startTeamGame()` 发送的 `gameData`:移除 `roundTime` 字段,或将其设为 0 表示不限时
|
||
- 确认 `TeamRoom` 类中 `this.roundTime = 300` 不再影响游戏逻辑,可移除或保留为无效值
|
||
- _需求:13.12_
|
||
|
||
- [ ] 12. 修改客户端 TeamGameScene 移除倒计时并适配纯基地摧毁胜负
|
||
- 修改 `TeamGameScene.js` 中 `enter()` 方法:移除 `_roundTimer` 的初始化和使用
|
||
- 修改 `TeamGameScene.js` 中 `update()` 方法:移除 `_roundTimer -= dt` 倒计时逻辑及 `_roundTimer <= 0` 的超时判断
|
||
- 修改 `TeamGameScene.js` 中 HUD 渲染:移除顶部倒计时显示,改为显示对战已进行时间(正计时,仅作参考信息)
|
||
- 确保 `_handleTeamGameOver` 回调中正确处理 `reason === 'base_destroyed'` 的唯一胜负场景,移除 `timeout` / `draw` 相关的结果处理
|
||
- 修改 `TeamRoomScene.js` 中 `_startTeamGame()` 传参:不再传递 `roundTime`
|
||
- _需求:13.12_
|
||
|
||
- [ ] 13. 修正 3v3 对战地图为双方各 1 个基地的对称布局
|
||
- 检查 `LevelData.js` 中 `TEAM_MAPS` 数据:确保每张地图双方各只有 1 个基地(`TERRAIN.BASE`),分别位于地图左右两端
|
||
- 确保基地周围有砖块围墙保护(`TERRAIN.BASE_WALL`),地图中央为争夺区域
|
||
- 确保 `teamABase` 和 `teamBBase` 坐标正确指向各自唯一基地位置
|
||
- 验证 `MapManager` 对 3v3 地图中双基地的渲染和碰撞检测逻辑正确(两个基地分别可被对方子弹击中扣血)
|
||
- _需求:13.11_
|
||
|
||
- [ ] 14. 完善服务端 3v3 房间管理与匹配系统
|
||
- 检查并修复 `handleCreateTeam`、`handleJoinTeam`、`handleLeaveTeam`、`handleTeamReady`、`handleTeamKick`、`handleTeamDisband` 的边界情况处理
|
||
- 检查并修复 `handleMatchStart`、`handleMatchCancel`、`handleSoloMatch` 的匹配逻辑,确保队伍匹配和单人匹配正确配对
|
||
- 确保 `tryMatchTeams()` 中两队配对和散人组队逻辑正确,AI 填充在超时后正常触发
|
||
- 确保 `handleBaseHit` 中基地扣血和 `base_destroyed` 判定逻辑正确,且是唯一的游戏结束触发点
|
||
- 验证断线重连流程:`handleTeamPlayerDisconnect` → 60秒超时 → `BOT_TAKEOVER`,以及 `handleReconnect` 恢复逻辑
|
||
- _需求:13.1、13.2、13.3、13.5、13.6、13.7、13.8、13.9、13.10、13.15、13.16_
|
||
|
||
- [ ] 15. 完善客户端 TeamRoomScene 队伍房间交互
|
||
- 检查并修复 `TeamRoomScene.js` 中组队开黑流程:创建队伍 → 邀请好友 → 队员准备 → 队长开始匹配
|
||
- 检查并修复快速匹配(单人匹配)流程:点击快速匹配 → 进入匹配池 → 匹配成功/超时AI填充
|
||
- 确保队长权限按钮(邀请、踢人、开始匹配、解散)和队员按钮(准备/取消、退出)的交互逻辑正确
|
||
- 确保微信邀请卡片生成(`wx.shareAppMessage`)携带 `teamId` 参数,好友点击后能正确加入队伍
|
||
- 确保匹配状态UI(匹配中倒计时、取消匹配按钮)正确显示和响应
|
||
- 确保网络事件监听(`TEAM_STATE`、`TEAM_GAME_START`、`ROOM_ERROR`、`TEAM_DISBAND`)正确处理
|
||
- _需求:13.1、13.2、13.3、13.4、13.5、13.6、13.7、13.8、13.9、13.10_
|
||
|
||
- [ ] 16. 完善 TeamGameScene 对战核心逻辑与 HUD
|
||
- 确保 6 辆坦克(3v3)的创建、渲染、碰撞检测正确运行,己方子弹不伤害己方坦克
|
||
- 确保网络同步:本地玩家输入发送、远程玩家状态接收与插值平滑、子弹同步
|
||
- 确保基地血量系统正确:子弹击中基地 → 发送 `BASE_HIT` → 服务端扣血广播 → 客户端更新血量条
|
||
- 确保无限重生机制:被击毁后 3 秒在己方出生点重生,重生后 3 秒无敌
|
||
- 实现 HUD:双方基地血量条(顶部左右对称)、对战已进行时间(正计时)、本方队伍击杀/死亡统计
|
||
- 实现队友/敌方坦克颜色区分:己方蓝色系、敌方红色系、本地玩家金色高亮
|
||
- 实现 AI 机器人(`BotTank`)在对战中的行为:匹配填充的 AI 和断线接管的 AI 正常移动和射击
|
||
- _需求:13.11、13.12、13.13、13.14、13.15_
|
||
|
||
- [ ] 17. 实现 TeamResultScene 结算与主菜单入口集成
|
||
- 完善 `TeamResultScene.js` 结算界面:展示胜负结果(仅"胜利/失败",无平局)、双方各玩家击杀数/死亡数/助攻数/对阵地伤害
|
||
- 移除结算界面中与时间相关的展示(如"超时平局"等),胜负原因统一为"基地被摧毁"
|
||
- 实现段位积分变化显示:胜方加分、败方扣分、MVP 额外加分
|
||
- 实现结算后操作按钮:「再来一局」(返回队伍房间)、「返回主菜单」
|
||
- 确保 `MenuScene.js` 中「3v3 对战」按钮正确跳转到 `TeamRoomScene`
|
||
- 确保 `NetworkManager.js` 中 3v3 专用方法(`createTeam`、`joinTeam`、`teamReady`、`startMatch`、`kickPlayer`、`disbandTeam`)正确发送消息
|
||
- 确保 `game.js` 中 `wx.onShow` 的 `teamId` 检测逻辑正确,从邀请卡片进入游戏后自动加入队伍
|
||
- _需求:13.4、13.5、13.14、13.16_
|