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
+301
View File
@@ -0,0 +1,301 @@
# AudioManager 音效系统说明文档
> **文件路径**: `js/managers/AudioManager.js`
> **运行环境**: 微信小游戏 (WeChat Mini Game)
> **依赖 API**: `wx.createWebAudioContext()` (Web Audio API)
> **外部资源**: 无 — 所有音效通过 PCM 程序化合成生成
---
## 1. 架构概述
`AudioManager` 是坦克大战微信小游戏的音效管理模块,采用 **程序化音频合成** 方案,通过 Web Audio API 在运行时生成所有游戏音效的 PCM 缓冲区,无需加载任何外部音频文件。
### 设计决策
| 方案 | 优点 | 缺点 |
|------|------|------|
| ~~外部音频文件~~ | 音质高、可定制 | 需要额外资源文件,增加包体积 |
| **程序化合成 ✅** | 零资源依赖、包体极小、即时可用 | 音效较简单,适合复古风格游戏 |
### 模块关系
```
game.js (初始化)
└── AudioManager.init() ← 创建 WebAudioContext + 预生成所有音效缓冲区
├── GameScene.js (游戏场景)
│ ├── _playerFire() → playSFX('shoot')
│ ├── _enemyFire() → playSFX('shoot')
│ ├── _spawnExplosion() → playSFX('explosion_big' | 'explosion_small')
│ ├── _checkPowerUpPickup() → playSFX('powerup')
│ ├── _handlePlayerDestroyed() → playSFX('gameover')
│ ├── _handleBaseDestroyed() → playSFX('gameover')
│ └── _checkVictory() → playSFX('victory')
└── CollisionManager.js (碰撞管理)
└── 子弹击中装甲坦克(未摧毁) → playSFX('hit')
```
---
## 2. 生命周期
```mermaid
sequenceDiagram
participant G as game.js
participant AM as AudioManager
participant GS as GameScene
G->>AM: new AudioManager()
G->>G: GameGlobal.audioManager = audioManager
G->>AM: audioManager.init()
AM->>AM: wx.createWebAudioContext()
AM->>AM: _generateSounds() 预生成9种音效
Note over AM: 初始化完成,_initialized = true
GS->>AM: playSFX('shoot')
AM->>AM: createBufferSource() → connect → start
Note over AM: 播放音效
G->>AM: pauseAll() / resumeAll()
Note over AM: 前后台切换时暂停/恢复
G->>AM: destroy()
AM->>AM: audioCtx.close() + buffers.clear()
```
---
## 3. 音效目录
### 3.1 完整音效列表
| 音效名 | 用途 | 时长 | 波形特征 | 触发位置 |
|--------|------|------|----------|----------|
| `shoot` | 坦克射击 | 80ms | 800→400Hz 下降正弦波 + 线性衰减 | `GameScene._playerFire()` / `_enemyFire()` |
| `explosion_small` | 小爆炸(子弹击中地形) | 200ms | 白噪声 + 120Hz 正弦波,二次衰减 | `GameScene._spawnExplosion(x, y, false)` |
| `explosion_big` | 大爆炸(坦克被摧毁) | 400ms | 白噪声 + 60Hz/90Hz 双正弦波,二次衰减 | `GameScene._spawnExplosion(x, y, true)` |
| `hit` | 子弹击中装甲(未摧毁) | 100ms | 1200Hz + 2400Hz 双正弦波,金属质感 | `CollisionManager` 子弹命中装甲坦克 |
| `hit_wall` | 子弹击中墙壁 | 60ms | 噪声 + 300Hz 正弦波混合 | 预留(当前未调用) |
| `powerup` | 拾取道具 | 250ms | 400→1200Hz 上升正弦波 + 泛音 | `GameScene._checkPowerUpPickup()` |
| `gameover` | 游戏结束 | 600ms | 400→150Hz 下降正弦波 | `GameScene._handlePlayerDestroyed()` / `_handleBaseDestroyed()` |
| `victory` | 通关胜利 | 500ms | C5→E5→G5 三音阶上升和弦 | `GameScene._checkVictory()` |
| `move` | 坦克移动 | 50ms | 80Hz 低频正弦波 | 预留(当前未调用) |
### 3.2 音效波形参数详解
#### shoot(射击)
```
时长: 0.08s
频率: 800Hz → 400Hz (线性下降)
包络: 线性衰减 (1 → 0)
振幅: 0.3
```
#### explosion_big(大爆炸)
```
时长: 0.4s
成分: 白噪声(50%) + 60Hz正弦(30%) + 90Hz正弦(20%)
包络: 二次衰减 (1-t)²
振幅: 0.4
```
#### victory(胜利)
```
时长: 0.5s
音符: C5(523Hz) → E5(659Hz) → G5(784Hz)
每段: 0.167s, 含 attack(10%) + decay(90%)
泛音: 基频 × 2, 振幅 0.15
```
---
## 4. API 参考
### 构造函数
```javascript
const audioManager = new AudioManager();
```
创建实例,默认 `soundEnabled = true`, `musicEnabled = true`
自动监听 `GameGlobal.eventBus``settings:changed` 事件。
### init()
```javascript
audioManager.init();
```
初始化 WebAudio 上下文并预生成所有音效缓冲区。
- 幂等调用:多次调用只执行一次
- 如果 `wx.createWebAudioContext` 不可用,静默降级(无音效)
### playSFX(name)
```javascript
GameGlobal.audioManager.playSFX('shoot');
```
播放指定名称的音效。
- **参数**: `name` — 音效名称,见上方音效目录
- 如果音效未找到或音效已禁用,静默忽略
- 每次调用创建新的 `BufferSource`,支持同一音效并发播放
### register(name, path)
```javascript
audioManager.register('custom', 'path/to/file.mp3');
```
向后兼容接口,当前为空操作(No-op)。
### playBGM(path) / stopBGM()
背景音乐接口,当前未实现(需要外部音频文件)。
### pauseAll() / resumeAll()
暂停/恢复所有音频,用于应用前后台切换。
### destroy()
销毁音频上下文,释放所有缓冲区资源。
### 属性
| 属性 | 类型 | 说明 |
|------|------|------|
| `soundEnabled` | `boolean` | 音效开关(getter/setter |
| `musicEnabled` | `boolean` | 音乐开关(getter/setter |
---
## 5. 集成指南
### 5.1 初始化(game.js
```javascript
// game.js 第39行
const audioManager = new AudioManager();
// 第48行 - 挂载到全局
GameGlobal.audioManager = audioManager;
// 第131行 - LoadingScene._startLoading() 中初始化
audioManager.init();
```
### 5.2 在游戏逻辑中播放音效
```javascript
// 射击时
GameGlobal.audioManager.playSFX('shoot');
// 爆炸时(根据大小选择音效)
GameGlobal.audioManager.playSFX(isBig ? 'explosion_big' : 'explosion_small');
// 拾取道具
GameGlobal.audioManager.playSFX('powerup');
// 游戏结束
GameGlobal.audioManager.playSFX('gameover');
// 胜利
GameGlobal.audioManager.playSFX('victory');
```
### 5.3 添加新音效
`_generateSounds()` 方法中添加新的缓冲区生成:
```javascript
// 示例:添加一个"警报"音效
this._buffers.set('alarm', this._generateBuffer(sampleRate, 0.3, (i, len) => {
const t = i / len;
const freq = 600 + Math.sin(t * 20) * 200; // 颤音效果
const envelope = 1 - t;
return Math.sin(2 * Math.PI * freq * i / sampleRate) * envelope * 0.3;
}));
```
然后在需要的地方调用:
```javascript
GameGlobal.audioManager.playSFX('alarm');
```
### 5.4 前后台切换处理
```javascript
// game.js 中已配置
wx.onHide(() => { audioManager.pauseAll(); });
wx.onShow(() => { audioManager.resumeAll(); });
```
---
## 6. 技术细节
### 6.1 PCM 缓冲区生成原理
每个音效通过 `_generateBuffer()` 方法生成:
1. 根据 `sampleRate`(通常 44100Hz)和 `duration` 计算总采样数
2. 创建单声道 `AudioBuffer`
3. 逐采样调用 `generator(sampleIndex, totalSamples)` 函数
4. 每个采样值范围 `[-1.0, 1.0]`
```
采样数 = sampleRate × duration
例: 44100 × 0.08 = 3528 个采样点 (shoot 音效)
```
### 6.2 播放机制
```javascript
playSFX(name) createBufferSource() connect(destination) start(0)
```
- 每次播放创建新的 `BufferSource` 节点(Web Audio API 要求,BufferSource 是一次性的)
- 支持同一音效的多实例并发播放(如连续射击)
- 播放完成后 `BufferSource` 自动被垃圾回收
### 6.3 性能考量
| 指标 | 数值 |
|------|------|
| 预生成缓冲区数量 | 9 个 |
| 最大单个缓冲区大小 | ~26KB (explosion_big, 0.4s × 44100 × 4bytes) |
| 总内存占用 | ~80KB |
| 初始化耗时 | < 10ms |
| 播放延迟 | < 1ms (预生成缓冲区,无需解码) |
### 6.4 降级策略
```
wx.createWebAudioContext 可用?
├── 是 → 正常初始化,生成所有音效
└── 否 → _initialized = false, 所有 playSFX() 静默返回
```
---
## 7. 已知限制与后续规划
### 当前限制
1. **无背景音乐**`playBGM()` 为空实现,需要外部音频文件支持
2. **音效较简单** — 程序化合成适合复古风格,无法达到高保真音质
3. **`hit_wall``move` 音效已生成但未集成** — 预留接口,可在后续版本中启用
4. **`pauseAll()` / `resumeAll()` 为空实现** — WebAudio 的 suspend/resume 可在后续补充
### 后续可优化方向
- [ ] 实现 `pauseAll()` / `resumeAll()` 使用 `audioCtx.suspend()` / `audioCtx.resume()`
- [ ] 集成 `hit_wall` 音效到 `CollisionManager` 的墙壁碰撞逻辑
- [ ] 集成 `move` 音效到坦克移动逻辑(需注意节流,避免频繁触发)
- [ ] 添加音量控制(通过 `GainNode`
- [ ] 支持外部音频文件加载,用于背景音乐
- [ ] 音效参数可配置化(从 JSON 配置文件读取波形参数)
@@ -0,0 +1,79 @@
# 坦克大战经典游戏 - 极简商业化方案
## 前言
针对“坦克大战”这类经典小游戏,其核心魅力在于**简单爽快**的玩法体验。在微信小游戏生态中,商业化必须做减法,坚持**“轻数值、重体验”**的原则。以下是一个极简化的商业化方案,旨在不破坏原版游戏“味道”的前提下实现变现。
---
## 一、 核心原则:做减法
- **去复杂化**:砍掉“坦克升级”、“技能树”、“装备强化”等重数值成长系统。
- **保留原味**:玩家玩的是“一发子弹消灭一个敌人”的爽快感,不是数值碾压。
- **变现隐形**:商业化不干扰核心玩法循环(移动 → 射击 → 躲避)。
---
## 二、 唯一的货币:金币(Gold)
**只保留一种货币**,彻底砍掉钻石、赛季币、碎片等复杂体系。
- **定位**:纯功能性货币,用于“续命”和“爽局”。
- **获取**:主要靠**看广告**(IAA),其次靠对局结算(少量)。
---
## 三、 极简商业化三板斧
### 1. 复活续关(核心变现点)
- **场景**:玩家坦克被击毁,弹出选项。
- **选项A(看广告)**:立即复活,保留当前关卡进度。
- **选项B(花金币)**:支付 **200金币** 立即复活(为不想看广告的玩家提供出口)。
- **逻辑**:这是玩家**付费意愿最强**的时刻(沉没成本高),转化率最高。
### 2. 局前Buff(小额消耗)
- **机制**:开局前可购买一次性增益(仅生效一局)。
- **道具**
- **护盾(100金币)**:开局自带一层护盾。
- **双倍火力(150金币)**:开局10秒内子弹威力翻倍。
- **目的**:制造小额金币缺口,促使用户看广告赚金币。
### 3. 去广告特权(唯一内购)
- **商品****¥18 永久去广告**。
- **权益**:免除所有激励视频(复活仍需消耗金币)。
- **目标用户**:真正热爱这款游戏、讨厌打断的核心玩家。
---
## 四、 广告与获取闭环
### 1. 赚金币的广告(IAA
- **双倍金币**:结算页面,看广告使本局金币收益×2。
- **免费金币**:主城“领金币”按钮,每日看3次广告,每次得100金。
### 2. 经济循环设计
玩游戏 → 死亡/想变强 → 看广告赚金币/充值买金币 → 购买复活/Buff → 继续游戏
- **免费玩家**:通过看广告(双倍/每日)获得金币,用于复活和Buff。
- **付费玩家**:直接充值购买金币包(如 ¥6=1000金),或购买“去广告特权”。
---
## 五、 数值设定(极简版)
| 项目 | 数值 | 说明 |
| :--- | :--- | :--- |
| **单局基础金币** | 50 | 通关奖励 |
| **复活消耗** | 200 | 约等于4局收益,制造缺口 |
| **广告双倍** | 100 | 极具吸引力 |
| **新手礼包** | ¥1=500金 | 破冰首充,送一次复活 |
---
## 六、 为什么这套方案更优?
1. **符合认知**:老玩家只关心“命”和“火力”,金币只用来买命,逻辑自洽。
2. **开发极快**:无需设计复杂的成长线和赛季任务。
3. **风险最低**:没有抽奖、宝箱等概率性玩法,合规性极高。
4. **体验无损**:广告是可选的(你可以选择慢慢攒金币),不会强迫玩家。
---
## 总结
对于经典坦克大战,**不要试图教育玩家接受复杂系统**。用“复活”和“Buff”这两个最原始的需求驱动广告与内购,才是最高效的商业化路径。这套方案在保持游戏原汁原味的同时,实现了IAA与IAP的双轨变现,适合快速验证和迭代。
+168
View File
@@ -0,0 +1,168 @@
# 《坦克大作战》微信小游戏商业化方案
## 一、 商业化总策略
采用 **“IAA(激励广告)+ IAP(内购)+ 社交裂变”** 三轨并行模式,以**非强制性、高转化**为核心原则,确保免费玩家体验,激励付费转化。
## 二、 激励视频广告(IAA)设计
### 1. 广告场景与收益估算
| 广告场景 | 触发时机 | 用户收益 | 预估eCPM | 预估日展示/用户 | 策略说明 |
| :--- | :--- | :--- | :--- | :--- | :--- |
| **复活续关** | 关卡失败时弹出 | 立即复活,保留当前火力 | ¥80-120 | 0.3-0.5次 | 核心收益点,转化率可达8-12% |
| **双倍结算** | 关卡胜利后结算前 | 本局金币/经验×2 | ¥60-100 | 0.2-0.4次 | 利用胜利喜悦心理 |
| **宝箱加速** | 开启稀有宝箱(4小时冷却) | 立即打开,无需等待 | ¥70-110 | 0.1-0.3次 | 时间焦虑型设计 |
| **体力恢复** | 体力耗尽时(每日上限5) | 恢复5点体力 | ¥50-80 | 0.5-0.8次 | 卡点设计,促活跃 |
| **免费礼包** | 每日签到/活动页面 | 随机道具包 | ¥40-70 | 0.5-1次 | 低压力广告入口 |
**收益测算**
假设 DAU 10万,人均日广告展示 2.5次,eCPM ¥80
- 日广告收入 = 100,000 × 2.5 × (80/1000) = **¥20,000/天**
- 月广告收入 ≈ ¥600,000
### 2. 广告体验优化
- **预加载**:在关卡加载时预载广告,减少等待时间
- **频次控制**:同一场景15分钟内不重复展示相同广告
- **奖励立即发放**:广告结束瞬间发放奖励,建立正反馈
## 三、 应用内购买(IAP)设计
### 1. 商品体系
| 商品类型 | 价格(微信代币) | 实际价值 | 目标用户 | 购买场景 |
| :--- | :--- | :--- | :--- | :--- |
| **去广告特权** | ¥30/永久 | 免除所有激励视频等待 | 核心玩家 | 游戏中期,广告频次较高时 |
| **月卡** | ¥12/月 | 每日领100钻石+专属头像框 | 中度玩家 | 新手期后,有留存意愿 |
| **钻石包** | ¥6/60钻<br>¥30/360钻<br>¥68/880钻 | 1:10兑换游戏币 | 所有玩家 | 皮肤购买、体力补充等 |
| **皮肤礼包** | ¥18-68 | 限定坦克皮肤+配套技能 | 外观党 | 赛季更新/节日活动 |
| **新手礼包** | ¥1 | 价值¥30道具组合 | 新用户 | 首次进入游戏24小时内 |
### 2. 内购转化策略
- **首充双倍**:首次充值任意金额,额外赠送等值钻石
- **连续累充**:连续7天每日充值,第7天送稀有皮肤
- **订阅制**:月卡自动续费,前3天可无条件退款
**收入测算**
假设付费率 3%ARPPU ¥50
- 月内购收入 = 100,000 DAU × 30 × 3% × 50 = **¥450,000/月**
## 四、 战斗通行证(Battle Pass)系统
### 1. 赛季设计
- **赛季时长**:4周(28天),契合微信小游戏用户节奏
- **免费通行证**:20级,基础奖励(金币、普通皮肤)
- **高级通行证**:¥18/赛季,40级,含:
- 3款限定坦克皮肤
- 专属头像框、聊天气泡
- 双倍任务经验加成
- 赛季结算额外30%金币
### 2. 任务体系
| 任务类型 | 免费版 | 高级版 | 设计目的 |
| :--- | :--- | :--- | :--- |
| 每日任务 | 3个,100经验/个 | 额外2个 | 促日活 |
| 每周任务 | 5个,500经验/个 | 额外3个 | 促周活 |
| 赛季成就 | 10个,1000经验/个 | 无差异 | 长期目标 |
**转化策略**
- 前10级免费体验高级奖励
- 赛季最后3天限时8折
- 分享给3位好友可获5折优惠券
**收入测算**
假设高级通行证购买率 5%
- 赛季收入 = 100,000 DAU × 5% × 18 = ¥90,000
- 年收入(13赛季)= ¥1,170,000
## 五、 社交裂变与分享变现
### 1. 分享激励体系
| 分享场景 | 分享者奖励 | 被邀请者奖励 | 防作弊机制 |
| :--- | :--- | :--- | :--- |
| **每日首次分享** | 50金币 | 无 | IP+设备去重 |
| **邀请新用户** | 200金币/人(上限5人) | 双倍经验卡(3天) | 需完成新手引导 |
| **分享战绩** | 概率得稀有道具 | 观看广告得金币 | 每日上限3次 |
| **组队成功** | 与好友组队完成3局,各得100钻石 | 同上 | 需对局时长>2分钟 |
### 2. 裂变活动
- **老带新活动**:邀请3位新用户,送永久限定皮肤
- **战队招募**:创建战队并招募10人,队长得500钻石
- **节日助力**:集齐5种道具可兑换大奖,需好友互赠
## 六、 数值与经济系统
### 1. 货币体系
| 货币 | 获取途径 | 主要消耗 | 兑换比例(设计) |
| :--- | :--- | :--- | :--- |
| **金币** | 对局奖励、每日任务、广告 | 升级坦克、购买基础道具 | 100金币 ≈ ¥0.1 |
| **钻石** | 充值、高级通行证、活动 | 购买皮肤、稀有道具、体力 | 1钻石 ≈ ¥0.1 |
| **赛季币** | 赛季任务、段位奖励 | 兑换往季限定皮肤 | 无直接充值 |
### 2. 付费节奏
| 阶段 | 商业化重点 | 付费点设计 |
| :--- | :--- | :--- |
| **新手期**<br>1-3天) | 建立付费习惯 | 1元首充礼包、去广告特权推荐 |
| **成长期**<br>4-14天) | 提高付费深度 | 月卡、钻石充值、皮肤促销 |
| **成熟期**<br>15天+) | 稳定收入 | 赛季通行证、限量皮肤、定制化内容 |
## 七、 商业化功能排期
| 版本 | 核心功能 | 预估收入贡献 | 开发周期 |
| :--- | :--- | :--- | :--- |
| **V1.0 基础版** | 激励视频(复活、双倍)、插屏广告 | 100%广告收入 | 2周 |
| **V1.5 内购版** | 钻石充值、去广告特权、基础皮肤 | 广告60% + 内购40% | 3周 |
| **V2.0 赛季版** | 战斗通行证、赛季任务、段位系统 | 广告40% + 内购40% + 通行证20% | 4周 |
| **V2.5 社交版** | 分享裂变、战队系统、社交皮肤 | 增加用户基数20-30% | 3周 |
## 八、 风险控制与合规
### 1. 未成年人保护
- **时间限制**22:00-8:00无法登录
- **消费限制**:月消费上限 ¥400,单次消费提示
- **广告频控**:未成年人每日广告展示不超过5次
### 2. 合规要点
- **概率公示**:所有抽奖、宝箱概率明确公示
- **退款政策**:符合微信小游戏退款规范
- **数据隐私**:明确告知数据收集范围,提供关闭选项
### 3. 反作弊策略
- **广告反刷**:同一广告源IP限制、设备指纹识别
- **交易监控**:异常大额充值人工审核
- **外挂检测**:对局数据上报,异常行为封禁
## 九、 收入预测模型
| 收入来源 | 月收入预测 | 占比 | 备注 |
| :--- | :--- | :--- | :--- |
| 激励视频广告 | ¥600,000 | 50% | 基于10万DAUeCPM ¥80 |
| 内购(充值+特权) | ¥450,000 | 37.5% | 付费率3%ARPPU ¥50 |
| 战斗通行证 | ¥90,000 | 7.5% | 购买率5%,单价¥18 |
| 其他(插屏等) | ¥60,000 | 5% | 补充收入 |
| **月总收入** | **¥1,200,000** | 100% | |
| **年化收入** | **¥14,400,000** | | 保守估计 |
**关键假设**
- DAU 10万,月留存 25%
- 人均日广告展示 2.5次
- 付费率 3%ARPPU ¥50
- 高级通行证购买率 5%
## 十、 优化与迭代策略
### 1. 数据监控指标
- **商业化漏斗**:曝光 → 点击 → 转化 → 付费
- **LTV/CAC**:生命周期价值/获客成本 > 3
- **付费分布**:鲸鱼用户(付费>¥1000)占比<1%
### 2. A/B测试策略
| 测试项 | 方案A | 方案B | 评估指标 |
| :--- | :--- | :--- | :--- |
| 广告位 | 结算前插屏+激励 | 仅激励视频 | ARPDAU |
| 定价 | 月卡¥12 | 月卡¥8 | 付费率、总收入 |
| 通行证 | 40级,¥18 | 30级,¥12 | 购买率、完赛率 |
### 3. 长期规划
- **季度**:稳定IAA+IAP双轨,ARPU达¥1.5
- **半年**:引入品牌广告、轻度联运
- **年度**:IP授权、周边衍生,非游戏收入占比>20%
**总结**:本方案通过**分层付费设计**(免费看广告→小额内购→订阅通行证)覆盖全用户层级,利用微信社交链**降低获客成本**,在保持玩法核心乐趣的同时,实现**月流水超百万**的商业目标。关键成功因素在于平衡广告频次与用户体验,通过赛季内容持续拉动活跃与付费。