# 用户界面系统
**本文档中引用的文件**
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts)
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts)
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts)
- [TopComp.ts](file://assets/script/game/map/TopComp.ts)
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts)
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts)
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts)
- [MvvmInfo.md](file://doc/mvvm/MvvmInfo.md)
- [VMBase.md](file://doc/mvvm/VMBase.md)
- [gui.md](file://doc/core/gui/gui.md)
## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [UI层级架构](#ui层级架构)
4. [核心组件分析](#核心组件分析)
5. [MVVM框架集成](#mvvm框架集成)
6. [事件系统与数据绑定](#事件系统与数据绑定)
7. [使用示例](#使用示例)
8. [性能优化考虑](#性能优化考虑)
9. [故障排除指南](#故障排除指南)
10. [总结](#总结)
## 简介
本游戏采用基于Oops Framework的现代化UI系统架构,集成了MVVM设计模式和事件驱动的组件化开发方式。系统通过GameUIConfig.ts统一管理界面配置,支持多种UI层级和预制体路径配置,并通过MVVM框架实现数据与视图的自动绑定。
## 项目结构
UI系统的核心文件组织结构如下:
```mermaid
graph TB
subgraph "UI配置层"
A[GameUIConfig.ts] --> B[UIID枚举]
A --> C[UIConfigData配置]
end
subgraph "组件层"
D[HInfoComp.ts] --> E[英雄信息面板]
F[MInfoComp.ts] --> G[怪物信息组件]
H[TopComp.ts] --> I[顶部状态栏]
J[VictoryComp.ts] --> K[胜利界面]
L[SIconComp.ts] --> M[技能图标组件]
end
subgraph "框架层"
N[MVVM框架] --> O[ViewModel]
N --> P[VMBase组件]
Q[事件系统] --> R[GameEvent]
end
A --> D
A --> F
A --> H
A --> J
A --> L
N --> D
N --> F
N --> H
N --> J
N --> L
Q --> D
Q --> F
Q --> H
Q --> J
Q --> L
```
**图表来源**
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L1-L36)
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L1-L344)
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts#L1-L28)
**章节来源**
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L1-L36)
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L1-L344)
## UI层级架构
### 层级类型定义
系统采用分层的UI管理架构,通过LayerType枚举定义不同的界面层级:
| 层级类型 | 描述 | 使用场景 |
|---------|------|----------|
| UI层 | 主界面层级,常驻显示 | 英雄信息面板、顶部状态栏 |
| PopUp层 | 弹出式界面 | 网络不稳定提示、Toast消息 |
| Dialog层 | 模态对话框 | 弹窗界面、确认对话框 |
### 配置数据结构
```mermaid
classDiagram
class UIConfig {
+LayerType layer
+string prefab
+string bundle
}
class UIID {
<>
Loading
Netinstable
Role_Controller
Victory
Guide
}
class GameUIConfig {
+UIConfigData : {[key : number] : UIConfig}
+registerUI(id : number, config : UIConfig) : void
+getUIConfig(id : number) : UIConfig
}
UIID --> GameUIConfig : "配置"
UIConfig --> GameUIConfig : "管理"
```
**图表来源**
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L10-L35)
**章节来源**
- [GameUIConfig.ts](file://assets/script/game/common/config/GameUIConfig.ts#L1-L36)
## 核心组件分析
### HInfoComp - 英雄信息面板
英雄信息面板是最复杂的UI组件,负责展示和管理英雄选择、属性显示和交互功能。
#### 组件架构
```mermaid
classDiagram
class HInfoComp {
+number h_uuid
+Node[] heroNodes
+Vec3 hero_pos
+boolean isMoving
+any moveTimeoutId
+update_data(uuid : number) : void
+load_all_hero(uuid : number) : void
+load_hui(uuid : number, pos_index : number) : Node
+next_hero() : void
+prev_hero() : void
+buy_hero() : void
+start_mission() : void
+moveHeroesLeft() : void
+moveHeroesRight() : void
+show_lock() : void
+claear_hero() : void
}
class CCComp {
+onLoad() : void
+start() : void
+update(deltaTime : number) : void
+reset() : void
}
HInfoComp --|> CCComp : "继承"
```
**图表来源**
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L10-L344)
#### 英雄选择动画系统
组件实现了复杂的英雄选择动画系统,包括:
- **循环滚动算法**:支持无限循环的英雄选择
- **平滑动画过渡**:使用Tween实现流畅的移动效果
- **视觉焦点效果**:3号位置英雄显示1.5倍放大效果
- **动画锁定机制**:防止快速点击导致的动画冲突
#### 数据绑定与更新
```mermaid
sequenceDiagram
participant User as 用户
participant HInfo as HInfoComp
participant SM as SingletonModule
participant VM as ViewModel
User->>HInfo : 点击英雄选择
HInfo->>HInfo : 验证动画状态
HInfo->>HInfo : 计算下一个英雄
HInfo->>SM : updateFihgtHero(uuid)
SM->>VM : 更新战斗英雄
VM->>HInfo : 通知数据变更
HInfo->>HInfo : update_data(uuid)
HInfo->>HInfo : 执行动画过渡
```
**图表来源**
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L200-L344)
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L120-L140)
**章节来源**
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L1-L344)
### MInfoComp - 怪物信息组件
怪物信息组件负责显示当前关卡信息,采用简洁的设计模式。
#### 组件特性
- **事件驱动更新**:监听MISSION_UPDATE事件自动更新关卡信息
- **文本绑定**:直接绑定到Label组件的字符串属性
- **生命周期管理**:在onLoad中注册事件监听器,在start中初始化数据
**章节来源**
- [MInfoComp.ts](file://assets/script/game/map/MInfoComp.ts#L1-L28)
### TopComp - 顶部状态栏
顶部状态栏组件专注于显示玩家资源信息,特别是金币数量的动画效果。
#### 特色功能
- **资源动画效果**:金币数量变化时触发缩放动画
- **事件响应**:监听GOLD_UPDATE事件执行动画
- **轻量级设计**:专注于单一功能,避免过度复杂化
**章节来源**
- [TopComp.ts](file://assets/script/game/map/TopComp.ts#L1-L30)
### VictoryComp - 胜利界面
胜利界面组件处理战斗结算和奖励展示,包含复杂的奖励系统和动画效果。
#### 界面流程
```mermaid
flowchart TD
A[战斗胜利] --> B[显示胜利界面]
B --> C[展示奖励信息]
C --> D{玩家选择}
D --> |继续| E[下一关卡]
D --> |重新开始| F[重置关卡]
D --> |双倍奖励| G[观看广告]
E --> H[清理数据]
F --> H
G --> I[验证广告]
I --> J{验证结果}
J --> |成功| K[获得双倍奖励]
J --> |失败| L[显示错误]
K --> H
H --> M[返回主界面]
```
**图表来源**
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L30-L75)
**章节来源**
- [VictoryComp.ts](file://assets/script/game/map/VictoryComp.ts#L1-L75)
### SIconComp - 技能图标组件
技能图标组件负责显示技能的视觉图标,采用简单的数据绑定模式。
#### 组件特点
- **资源动态加载**:根据技能UUID动态加载对应的图标资源
- **路径配置**:通过SkillSet配置技能的资源路径
- **轻量级实现**:专注于单一职责,易于维护和扩展
**章节来源**
- [SIconComp.ts](file://assets/script/game/map/SIconComp.ts#L1-L28)
## MVVM框架集成
### 架构概览
系统采用MVVM(Model-View-ViewModel)架构模式,通过Oops Framework的ViewModel模块实现数据与视图的自动绑定。
```mermaid
graph LR
subgraph "Model层"
A[数据模型] --> B[SingletonModuleComp]
B --> C[vmdata对象]
end
subgraph "ViewModel层"
D[ViewModel] --> E[VMManager]
E --> F[数据监听]
end
subgraph "View层"
G[UI组件] --> H[VMBase组件]
H --> I[数据绑定]
end
C --> D
F --> H
I --> G
```
**图表来源**
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L50-L70)
- [MvvmInfo.md](file://doc/mvvm/MvvmInfo.md#L10-L15)
### 数据模型管理
系统通过SingletonModuleComp统一管理游戏数据,特别是VM数据模型:
```mermaid
classDiagram
class SingletonModuleComp {
+vmdata : any
+vmAdd() : void
+updateGold(gold : number) : void
+updateFihgtHero(heroId : number) : void
+addHero(hero_uuid : number) : void
}
class ViewModel {
+add(data : any, tag : string) : void
+get(tag : string) : ViewModel
+setValue(path : string, value : any) : void
+getValue(path : string) : any
}
SingletonModuleComp --> ViewModel : "管理"
```
**图表来源**
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L50-L70)
### VMBase组件基类
所有UI组件都继承自VMBase组件,实现自动的数据绑定功能:
| 属性 | 类型 | 描述 |
|------|------|------|
| watchPath | string | 需要监听的数据路径 |
| watchPathArr | string[] | 多路径监听数组 |
| templateMode | boolean | 启用模板模式 |
| VM | VMManager | ViewModel管理器引用 |
**章节来源**
- [VMBase.md](file://doc/mvvm/VMBase.md#L1-L39)
## 事件系统与数据绑定
### 事件类型定义
系统通过GameEvent枚举定义了完整的游戏事件体系:
```mermaid
graph TB
subgraph "战斗事件"
A[FightStart] --> B[FightEnd]
C[FightPause] --> D[FightResume]
end
subgraph "关卡事件"
E[MissionStart] --> F[MissionEnd]
G[MissionWin] --> H[MissionLoss]
end
subgraph "资源事件"
I[GOLD_UPDATE] --> J[DIAMOND_UPDATE]
K[MEAT_UPDATE] --> L[MISSION_UPDATE]
end
subgraph "选择事件"
M[HeroSelect] --> N[EnhancementSelect]
O[TalentSelect] --> P[FuncSelect]
end
```
**图表来源**
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L10-L70)
### 数据绑定流程
```mermaid
sequenceDiagram
participant Model as 数据模型
participant VM as ViewModel
participant View as UI组件
participant Event as 事件系统
Model->>VM : 数据变更
VM->>VM : 触发监听器
VM->>Event : 发送事件通知
Event->>View : 分发事件
View->>View : 更新UI显示
View->>Model : 响应用户交互
```
**图表来源**
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L150-L195)
**章节来源**
- [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts#L1-L70)
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L150-L195)
## 使用示例
### 注册新UI界面
以下是如何注册和使用新UI界面的完整示例:
```typescript
// 1. 在GameUIConfig.ts中添加UI配置
export enum UIID {
// ... 现有UI ID
CustomPanel = 2001,
}
export var UIConfigData: { [key: number]: UIConfig } = {
// ... 现有UI配置
[UIID.CustomPanel]: {
layer: LayerType.UI,
prefab: "custom/prefab/panel"
},
};
// 2. 创建UI组件
@ccclass('CustomPanelComp')
export class CustomPanelComp extends CCComp {
protected onLoad(): void {
// 注册事件监听
oops.message.on(GameEvent.CustomEvent, this.onCustomEvent, this);
}
onCustomEvent(event: string, data: any): void {
// 处理自定义事件
this.updateDisplay(data);
}
updateDisplay(data: any): void {
// 更新UI显示
const label = this.node.getChildByName("content")
.getComponent(Label);
label.string = data.message;
}
}
// 3. 打开UI界面
const callbacks: UICallbacks = {
onAdded: (node: Node, params: any) => {
const comp = node.getComponent(CustomPanelComp);
// 初始化界面
},
onRemoved: (node: Node | null, params: any) => {
// 清理资源
}
};
oops.gui.open(UIID.CustomPanel, null, callbacks);
```
### 处理按钮点击事件
```typescript
// 在UI组件中处理按钮点击
@ccclass('ButtonHandler')
export class ButtonHandler extends Component {
start(): void {
// 获取按钮节点
const button = this.node.getChildByName("action_button");
if (button) {
// 添加点击事件监听
button.on(Node.EventType.TOUCH_END, this.onButtonClick, this);
}
}
onButtonClick(event: EventTouch): void {
// 触发游戏事件
oops.message.dispatchEvent(GameEvent.ButtonClicked, {
buttonId: "action_button",
timestamp: Date.now()
});
// 执行业务逻辑
this.performAction();
}
performAction(): void {
// 实现具体业务逻辑
console.log("按钮被点击");
}
}
```
### 实现动态数据刷新
```typescript
// 使用MVVM框架实现自动数据刷新
@ccclass('DynamicDataComp')
export class DynamicDataComp extends VMBase {
@property({ type: Label })
public displayLabel: Label = null!;
@property(String)
public watchPath: string = "global.player.health";
onValueChanged(newValue: any, oldValue: any, pathArray: string[]): void {
// 自动更新UI显示
this.displayLabel.string = `生命值: ${newValue}`;
// 可选:添加视觉反馈
if (newValue < oldValue) {
this.showDamageEffect();
}
}
showDamageEffect(): void {
// 显示伤害特效
tween(this.node)
.to(0.1, { color: Color.RED })
.to(0.1, { color: Color.WHITE })
.start();
}
}
```
## 性能优化考虑
### 组件复用策略
1. **预制体池化**:对于频繁创建销毁的UI组件,实现预制体池化机制
2. **延迟加载**:非关键UI组件采用延迟加载策略
3. **内存管理**:及时清理事件监听器和定时器
### 动画性能优化
1. **批量动画**:将多个动画合并为批量操作
2. **硬件加速**:利用CSS3变换实现硬件加速
3. **帧率控制**:限制动画帧率避免过度消耗CPU
### 数据绑定优化
1. **路径简化**:避免过深的数据绑定路径
2. **防抖处理**:对高频数据更新实施防抖机制
3. **选择性更新**:只更新发生变化的UI部分
## 故障排除指南
### 常见问题及解决方案
#### UI组件无法显示
**问题症状**:UI组件创建后不显示或显示异常
**排查步骤**:
1. 检查预制体路径配置是否正确
2. 验证UI层级设置是否符合预期
3. 确认组件脚本是否正确注册
**解决方案**:
```typescript
// 检查UI配置
console.log("UI配置:", UIConfigData[UIID.CustomPanel]);
// 验证预制体加载
oops.res.get(UIConfigData[UIID.CustomPanel].prefab, Prefab, (err, prefab) => {
if (err) {
console.error("预制体加载失败:", err);
}
});
```
#### 数据绑定失效
**问题症状**:数据更新后UI不自动刷新
**排查步骤**:
1. 检查watchPath路径是否正确
2. 验证ViewModel是否正常工作
3. 确认事件系统是否正常
**解决方案**:
```typescript
// 手动测试数据绑定
VM.setValue("global.test.value", "测试数据");
console.log("当前值:", VM.getValue("global.test.value"));
```
#### 动画卡顿
**问题症状**:UI动画播放不流畅
**排查步骤**:
1. 检查动画复杂度
2. 验证硬件性能
3. 确认动画队列管理
**解决方案**:
```typescript
// 优化动画实现
tween(target)
.to(0.2, { position: newPosition })
.call(() => {
// 动画完成后清理
this.cleanupAnimation();
})
.start();
```
**章节来源**
- [HInfoComp.ts](file://assets/script/game/map/HInfoComp.ts#L200-L344)
- [SingletonModuleComp.ts](file://assets/script/game/common/SingletonModuleComp.ts#L150-L195)
## 总结
本UI系统通过模块化的架构设计,实现了高度可维护和可扩展的界面管理方案。系统的主要优势包括:
1. **统一的配置管理**:通过GameUIConfig.ts集中管理所有UI配置
2. **MVVM架构**:实现数据与视图的自动绑定,减少手动DOM操作
3. **事件驱动**:基于事件系统实现松耦合的组件通信
4. **性能优化**:通过合理的架构设计和优化策略保证良好的性能表现
5. **易于扩展**:模块化的设计使得添加新UI组件变得简单直观
该系统为游戏提供了稳定可靠的UI基础设施,支持复杂的交互逻辑和动态内容更新,是现代游戏开发中UI系统设计的优秀实践案例。