272 lines
11 KiB
Markdown
272 lines
11 KiB
Markdown
# 奖励机制
|
||
|
||
<cite>
|
||
**本文档引用文件**
|
||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts)
|
||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts)
|
||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts)
|
||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
|
||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts)
|
||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts)
|
||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts)
|
||
- [Design.md](file://assets/script/Design.md)
|
||
</cite>
|
||
|
||
## 目录
|
||
1. [奖励系统概述](#奖励系统概述)
|
||
2. [三选一奖励机制](#三选一奖励机制)
|
||
3. [FightSet常量配置与奖励类型](#fightset常量配置与奖励类型)
|
||
4. [奖励数据结构与流程](#奖励数据结构与流程)
|
||
5. [掉落处理与数据更新](#掉落处理与数据更新)
|
||
6. [奖励界面触发与数据传递](#奖励界面触发与数据传递)
|
||
7. [扩展新奖励类型](#扩展新奖励类型)
|
||
|
||
## 奖励系统概述
|
||
|
||
本游戏采用肉鸽(Roguelike)塔防玩法,奖励系统是核心成长机制之一。玩家通过击败怪物获得金币,并在每波战斗结束后从三个奖励选项中选择一个,用于强化英雄能力。奖励类型包括属性提升、技能升级、装备获取、新技能解锁等,不同奖励具有不同的战力评分和金币消耗,玩家需要根据当前局势进行策略性选择。
|
||
|
||
奖励系统通过事件驱动机制实现,主要由`MissionComp`组件负责奖励数据的收集与分发,`VictoryComp`组件负责奖励界面的展示与交互。系统采用ECS架构,通过事件总线(`oops.message`)进行组件间通信,确保了高内聚低耦合的设计原则。
|
||
|
||
**Section sources**
|
||
- [Design.md](file://assets/script/Design.md#L0-L40)
|
||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L1-L150)
|
||
|
||
## 三选一奖励机制
|
||
|
||
三选一奖励机制是游戏的核心决策系统,其触发条件为每波怪物被全部击败后。当`MissionMonComp`组件检测到当前波次怪物全部死亡时,会触发`FightEnd`事件,进而启动奖励选择流程。
|
||
|
||
该机制的实现逻辑如下:
|
||
1. 战斗结束时,`MissionComp`组件监听到`FightEnd`事件
|
||
2. 收集本局战斗的奖励数据(金币、经验、钻石等)
|
||
3. 构建奖励选项数组,通常包含三个不同强度的奖励
|
||
4. 通过GUI系统打开胜利界面(Victory界面),并传递奖励数据
|
||
5. 玩家在界面中选择一个奖励,系统应用对应效果
|
||
|
||
奖励选项的设计遵循"弱、一般、强"的梯度原则,不同选项消耗的金币数量不同,战力评分也不同,鼓励玩家进行策略性决策。
|
||
|
||
```mermaid
|
||
sequenceDiagram
|
||
participant MissionMonComp as MissionMonComp
|
||
participant MissionComp as MissionComp
|
||
participant VictoryComp as VictoryComp
|
||
participant GUI as GUI系统
|
||
MissionMonComp->>MissionComp : MonDead事件(最后一只怪物死亡)
|
||
MissionComp->>MissionComp : 检查怪物数量是否为0
|
||
MissionComp->>MissionComp : 触发FightEnd事件
|
||
MissionComp->>MissionComp : 收集game_data(金币、经验等)
|
||
MissionComp->>GUI : 打开Victory界面并传递数据
|
||
GUI->>VictoryComp : 初始化奖励界面
|
||
VictoryComp->>Player : 显示三个奖励选项
|
||
Player->>VictoryComp : 选择奖励
|
||
VictoryComp->>MissionComp : 应用所选奖励效果
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L23-L70)
|
||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L19-L37)
|
||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L102-L136)
|
||
|
||
## FightSet常量配置与奖励类型
|
||
|
||
`FightSet`枚举定义在`Mission.ts`文件中,包含了游戏的核心配置常量,其中与奖励系统直接相关的配置项包括:
|
||
|
||
- `GREEN_GOLD=1`:绿色金币,基础奖励单位
|
||
- `BLUE_GOLD=2`:蓝色金币,中级奖励单位
|
||
- `PURPLE_GOLD=3`:紫色金币,高级奖励单位
|
||
- `ORANGE_GOLD=4`:橙色金币,稀有奖励单位
|
||
- `ATK_ADD_GLOD=1`:伙伴攻击力增加对应的金币奖励值
|
||
|
||
这些常量定义了不同品质奖励的数值基准,系统根据这些基准值计算实际奖励数量。例如,普通怪物可能掉落`GREEN_GOLD`数量的金币,而精英怪物或Boss可能掉落`PURPLE_GOLD`或`ORANGE_GOLD`数量的金币。
|
||
|
||
此外,`FightSet`还定义了其他影响奖励获取的参数,如`MORE_RC=10`表示通过观看广告可获得的额外次数,这与奖励系统的双倍奖励功能相关联。
|
||
|
||
**Section sources**
|
||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L35)
|
||
|
||
## 奖励数据结构与流程
|
||
|
||
### 数据结构分析
|
||
|
||
`MissionComp`组件中定义了两个关键数据结构:
|
||
|
||
1. **rewards数组**:用于存储掉落物品列表
|
||
```typescript
|
||
rewards:any[]=[]
|
||
```
|
||
|
||
2. **game_data对象**:用于存储游戏数据
|
||
```typescript
|
||
game_data:any={
|
||
exp:0,
|
||
gold:0,
|
||
diamond:0
|
||
}
|
||
```
|
||
|
||
`rewards`数组存储具体的物品奖励,如装备、技能书等;`game_data`对象则存储基础资源类奖励,包括经验值、金币和钻石。
|
||
|
||
### 奖励收集流程
|
||
|
||
奖励数据的收集与分发流程如下:
|
||
|
||
1. **初始化阶段**:在`data_init()`方法中,重置`rewards`数组和`game_data`对象
|
||
2. **战斗阶段**:通过监听`MonDead`事件,逐步累积奖励数据
|
||
3. **结束阶段**:当战斗结束时,将收集到的奖励数据传递给胜利界面
|
||
|
||
数据流从怪物死亡事件开始,经过`MissionComp`组件的收集处理,最终传递给`VictoryComp`组件进行展示,形成了完整的奖励数据流转闭环。
|
||
|
||
```mermaid
|
||
flowchart TD
|
||
A[怪物死亡] --> B{是否为最后一只}
|
||
B --> |是| C[触发FightEnd事件]
|
||
B --> |否| D[继续战斗]
|
||
C --> E[收集奖励数据]
|
||
E --> F[填充rewards数组和game_data]
|
||
F --> G[打开Victory界面]
|
||
G --> H[展示奖励选项]
|
||
H --> I[玩家选择奖励]
|
||
I --> J[应用奖励效果]
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L23-L33)
|
||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L133-L135)
|
||
|
||
## 掉落处理与数据更新
|
||
|
||
`do_drop`方法是处理掉落物品和更新游戏数据的核心方法。该方法接收两个参数:`drop_item`数组和`game_data`对象,分别表示掉落的物品列表和基础资源奖励。
|
||
|
||
```typescript
|
||
do_drop(drop_item:any[],game_data:any={exp:0,gold:0,diamond:0}){
|
||
// console.log("[MissionComp] do_drop",drop_item,game_data)
|
||
|
||
}
|
||
```
|
||
|
||
虽然当前实现为空,但从方法签名可以看出其设计意图:
|
||
- `drop_item`参数接收掉落的物品数组,可能包含装备、道具等
|
||
- `game_data`参数接收基础资源奖励,默认值为零
|
||
- 方法内部应实现将掉落物品添加到`rewards`数组,并将资源奖励累加到`game_data`对象中
|
||
|
||
在`MissionMonComp`组件中,可以找到实际的奖励发放逻辑。当关卡类型为"event"(事件关卡)时,会触发随机事件,其中`EventType.TREASURE`(宝藏事件)会直接增加50金币:
|
||
```typescript
|
||
switch (this.currentEvent) {
|
||
case EventType.TREASURE:
|
||
smc.vmdata.mission_data.gold += 50; // 增加50金币
|
||
break;
|
||
}
|
||
```
|
||
|
||
这种设计模式表明,实际的奖励发放可能分散在多个组件中,最终由`MissionComp`统一收集和管理。
|
||
|
||
**Section sources**
|
||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L60-L63)
|
||
- [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts#L145-L148)
|
||
|
||
## 奖励界面触发与数据传递
|
||
|
||
### 事件监听机制
|
||
|
||
`MissionComp`组件通过事件监听机制触发奖励界面的展示。在`onLoad`方法中,注册了对`FightEnd`事件的监听:
|
||
|
||
```typescript
|
||
this.on(GameEvent.FightEnd,this.fight_end,this)
|
||
```
|
||
|
||
当战斗结束时,`fight_end`方法会被调用,该方法通过`oops.gui.open`方法打开胜利界面,并传递奖励数据:
|
||
|
||
```typescript
|
||
oops.gui.open(UIID.Victory,{victory:false,rewards:this.rewards,game_data:this.game_data})
|
||
```
|
||
|
||
### 数据传递机制
|
||
|
||
数据传递通过`open`方法的参数实现,传递了三个关键数据:
|
||
- `victory`:布尔值,表示战斗结果
|
||
- `rewards`:奖励物品数组
|
||
- `game_data`:基础资源数据对象
|
||
|
||
在`VictoryComp`组件的`onAdded`方法中接收这些数据:
|
||
|
||
```typescript
|
||
onAdded(args: any) {
|
||
if(args.game_data){
|
||
this.game_data=args.game_data
|
||
}
|
||
}
|
||
```
|
||
|
||
这种事件驱动的数据传递机制确保了组件间的松耦合,`MissionComp`只需关注奖励数据的收集,而`VictoryComp`只需关注奖励数据的展示,职责分离清晰。
|
||
|
||
```mermaid
|
||
classDiagram
|
||
class MissionComp {
|
||
+rewards : any[]
|
||
+game_data : any
|
||
+onLoad()
|
||
+fight_end()
|
||
+do_drop()
|
||
}
|
||
class VictoryComp {
|
||
+rewards : any[]
|
||
+game_data : any
|
||
+onAdded(args)
|
||
+victory_end()
|
||
}
|
||
class GameEvent {
|
||
+FightEnd : "FightEnd"
|
||
+MissionEnd : "MissionEnd"
|
||
}
|
||
class UIID {
|
||
+Victory : 2
|
||
}
|
||
MissionComp --> GameEvent : "监听"
|
||
MissionComp --> UIID : "使用"
|
||
MissionComp --> VictoryComp : "传递数据"
|
||
VictoryComp --> GameEvent : "触发"
|
||
```
|
||
|
||
**Diagram sources**
|
||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L23-L33)
|
||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L35-L37)
|
||
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L43)
|
||
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L30)
|
||
|
||
## 扩展新奖励类型
|
||
|
||
### 配置修改步骤
|
||
|
||
1. **在Mission.ts中添加常量**:在`FightSet`枚举中添加新的奖励类型常量
|
||
```typescript
|
||
NEW_REWARD_TYPE=5 // 新奖励类型
|
||
```
|
||
|
||
2. **在RogueConfig.ts中定义事件**:如果涉及新事件类型,需在`EventType`枚举中添加
|
||
```typescript
|
||
NEW_EVENT = "new_event"
|
||
```
|
||
|
||
3. **更新事件概率配置**:在`EventConfig`中添加新事件的触发概率
|
||
|
||
### 代码集成步骤
|
||
|
||
1. **修改MissionComp.ts**:
|
||
- 在`game_data`对象中添加新奖励字段
|
||
- 在`do_drop`方法中处理新奖励类型的逻辑
|
||
- 确保`rewards`数组能正确存储新类型的奖励物品
|
||
|
||
2. **更新VictoryComp.ts**:
|
||
- 在`onAdded`方法中处理新奖励数据
|
||
- 更新界面展示逻辑以支持新奖励类型的显示
|
||
|
||
3. **添加事件处理**:在`MissionMonComp`或相关组件中添加对新奖励事件的处理逻辑
|
||
|
||
4. **更新UI配置**:确保GUI系统能正确加载和显示新奖励类型的界面元素
|
||
|
||
通过以上步骤,可以无缝集成新的奖励类型,系统的设计具有良好的扩展性,新增奖励类型不会影响现有功能的稳定性。
|
||
|
||
**Section sources**
|
||
- [Mission.ts](file://assets/script/game/common/config/Mission.ts#L0-L35)
|
||
- [RogueConfig.ts](file://assets/script/game/map/RogueConfig.ts#L47-L86)
|
||
- [MissionComp.ts](file://assets/script/game/map/MissionComp.ts#L23-L70)
|
||
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L19-L37) |