16 KiB
16 KiB
怪物实体初始化流程
**本文档中引用的文件** - [Mon.ts](file://assets/script/game/hero/Mon.ts) - [MissionMonComp.ts](file://assets/script/game/map/MissionMonComp.ts) - [heroSet.ts](file://assets/script/game/common/config/heroSet.ts) - [SkillSet.ts](file://assets/script/game/common/config/SkillSet.ts) - [HeroAttrs.ts](file://assets/script/game/common/config/HeroAttrs.ts) - [EntityLayer.ts](file://assets/script/game/map/view/map/layer/entityLayer.ts) - [BoxSet.ts](file://assets/script/game/common/config/BoxSet.ts) - [GameEvent.ts](file://assets/script/game/common/config/GameEvent.ts)目录
概述
Monster类是游戏中的核心怪物实体管理器,负责怪物的完整生命周期管理,包括预制体加载、属性初始化、技能配置、碰撞体控制等关键功能。本文档将深入解析Monster类中load方法的完整初始化流程,重点阐述其动态加载机制、属性调整逻辑以及与其他系统的集成方式。
项目结构分析
graph TB
subgraph "怪物系统架构"
A[Monster类] --> B[load方法]
A --> C[hero_init方法]
B --> D[预制体加载]
B --> E[节点挂载]
B --> F[碰撞体控制]
C --> G[属性初始化]
C --> H[技能配置]
C --> I[Buff系统]
end
subgraph "配置系统"
J[HeroInfo配置] --> K[基础属性]
J --> L[技能列表]
M[SkillSet配置] --> N[技能数据]
O[BoxSet配置] --> P[碰撞组]
end
subgraph "场景系统"
Q[EntityLayer] --> R[节点管理]
S[MapView] --> T[场景容器]
end
A --> J
A --> M
B --> Q
B --> S
图表来源
章节来源
核心组件架构
Monster类采用ECS(Entity-Component-System)架构模式,继承自ecs.Entity基类,包含以下核心组件:
classDiagram
class Monster {
+HeroModel! MonModelComp
+HeroView! HeroViewComp
+BattleMove! BattleMoveComp
+init() void
+destroy() void
+load(pos, scale, uuid, is_boss, is_call, strengthMultiplier) void
+hero_init(uuid, node, scale, box_group, is_boss, is_call, strengthMultiplier) void
}
class MonModelComp {
+reset() void
}
class HeroViewComp {
+scale number
+fac FacSet
+type HType
+is_boss boolean
+box_group BoxSet
+hero_uuid number
+hero_name string
+base_hp number
+base_mp number
+base_ap number
+base_def number
+skills Skill[]
+Attrs Attrs
+initAttrs() void
}
class BattleMoveComp {
+direction number
+targetX number
}
Monster --> MonModelComp : "包含"
Monster --> HeroViewComp : "包含"
Monster --> BattleMoveComp : "包含"
图表来源
章节来源
Monster类load方法详解
load方法是Monster类的核心初始化入口,负责完整的怪物实体创建流程:
方法签名与参数说明
| 参数名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| pos | Vec3 | Vec3.ZERO | 怪物初始位置坐标 |
| scale | number | 1 | 怪物缩放比例 |
| uuid | number | 1001 | 怪物唯一标识符 |
| is_boss | boolean | false | 是否为Boss怪物 |
| is_call | boolean | false | 是否为召唤怪物 |
| strengthMultiplier | number | 1.0 | 强度倍率 |
完整初始化流程
flowchart TD
A[开始load方法] --> B[设置缩放参数]
B --> C[确定碰撞组]
C --> D[获取场景引用]
D --> E[构建资源路径]
E --> F[加载预制体]
F --> G{预制体加载成功?}
G --> |否| H[抛出异常]
G --> |是| I[创建节点实例]
I --> J[设置父节点]
J --> K[禁用碰撞体]
K --> L[设置初始位置]
L --> M[调用hero_init]
M --> N[派发monster_load事件]
N --> O[初始化移动参数]
O --> P[更新怪物计数]
P --> Q[结束]
H --> R[错误处理]
R --> Q
图表来源
关键实现细节
1. 动态资源路径构建
// 资源路径格式:game/heros/{hero.path}
var path = "game/heros/" + HeroInfo[uuid].path;
2. 碰撞体延迟启用机制
// 先禁用碰撞体,延迟一帧启用
const collider = node.getComponent(BoxCollider2D);
if (collider) collider.enabled = false;
3. 缩放与方向控制
// Boss怪物特殊处理
let scale = -1; // 默认向左朝向
if (is_boss) scale = 1; // Boss面向右侧
章节来源
hero_init方法深度解析
hero_init方法负责怪物的基础属性初始化和技能配置,是怪物能力系统的核心:
属性初始化流程
sequenceDiagram
participant MI as Monster Instance
participant HV as HeroViewComp
participant HI as HeroInfo
participant SS as SkillSet
participant AS as Attrs System
MI->>HV : 获取HeroView组件
MI->>HI : 查询怪物配置
MI->>HV : 设置基础属性
MI->>MI : 计算强度倍率属性
MI->>SS : 遍历技能列表
SS-->>MI : 返回技能配置
MI->>HV : 添加技能到技能列表
MI->>AS : 初始化属性系统
MI->>HV : 调用initAttrs()
MI->>MI : 添加到实体组件
图表来源
强度倍率动态调整机制
hero_init方法的核心特性是根据strengthMultiplier参数动态调整怪物属性:
基础属性计算公式
// 根据强度倍率调整基础属性
const baseHp = Math.floor(hero.hp * strengthMultiplier);
const baseAp = Math.floor(hero.ap * strengthMultiplier);
const baseDef = Math.floor(hero.def * strengthMultiplier);
属性倍率影响范围
| 属性类型 | 基础值 | 强度倍率影响 | 说明 |
|---|---|---|---|
| HP | hero.hp | × strengthMultiplier | 生命值线性增长 |
| AP | hero.ap | × strengthMultiplier | 物理攻击力线性增长 |
| DEF | hero.def | × strengthMultiplier | 物理防御力线性增长 |
| MP | hero.mp | 不受影响 | 魔法值保持不变 |
技能系统初始化
技能配置转换
// 将HeroInfo中的技能ID转换为完整的技能配置
for (let i = 0; i < hero.skills.length; i++) {
let skill = {
uuid: SkillSet[hero.skills[i]].uuid,
cd_max: SkillSet[hero.skills[i]].cd,
cost: SkillSet[hero.skills[i]].cost,
cd: 0
}
hv.skills.push(skill);
}
技能冷却系统
每个技能初始化时:
cd_max: 技能最大冷却时间cost: 技能消耗值cd: 当前冷却计时器(初始为0)
章节来源
资源加载与预制体管理
资源加载机制
游戏采用Oops Framework的资源管理系统,通过oops.res.get方法加载预制体:
flowchart LR
A[资源请求] --> B[oops.res.get]
B --> C{资源是否存在?}
C --> |是| D[返回预制体]
C --> |否| E[抛出错误]
D --> F[实例化预制体]
F --> G[返回节点实例]
E --> H[异常处理]
图表来源
常见资源路径错误
错误类型与解决方案
| 错误类型 | 症状 | 解决方案 |
|---|---|---|
| 路径不存在 | 预制体加载失败 | 检查HeroInfo配置中的path字段 |
| 文件损坏 | 实例化时报错 | 重新导入预制体资源 |
| 资源未打包 | 运行时找不到资源 | 确保资源已正确打包到构建中 |
UUID越界检查
// UUID有效性验证
let hero = HeroInfo[uuid];
if (!hero) {
console.error(`[Monster] 无效的怪物UUID: ${uuid}`);
throw new Error(`怪物配置不存在: ${uuid}`);
}
章节来源
场景节点挂载机制
EntityLayer节点管理
EntityLayer作为场景中的物体层,负责管理所有动态物体的渲染顺序和生命周期:
graph TB
A[Scene] --> B[EntityLayer]
B --> C[怪物节点]
B --> D[技能特效]
B --> E[UI元素]
C --> F[Monster实例]
F --> G[HeroViewComp]
F --> H[MonModelComp]
F --> I[BattleMoveComp]
图表来源
挂载流程详解
1. 场景引用获取
var scene = smc.map.MapView.scene;
2. 父节点设置
node.parent = scene.entityLayer!.node!;
3. 深度排序机制
EntityLayer实现了定时器驱动的深度排序:
private timer: Timer = new Timer(0.2);
update(dt: number) {
this.timer.update(dt);
// 深度排序逻辑
}
章节来源
消息事件系统
monster_load事件派发
游戏通过oops.message系统实现松耦合的消息通信:
sequenceDiagram
participant M as Monster
participant EM as Event Manager
participant MC as MissionMonComp
participant SM as Scene Manager
M->>EM : dispatchEvent("monster_load", monster)
EM->>MC : 通知怪物加载完成
MC->>SM : 更新场景状态
SM->>M : 可能的后续处理
图表来源
事件监听与处理
MissionMonComp中的事件处理
onLoad() {
this.on(GameEvent.FightReady, this.fight_ready, this);
this.on(GameEvent.NewWave, this.fight_ready, this);
}
事件处理流程
- FightReady事件: 准备战斗阶段
- NewWave事件: 新一波怪物生成
- monster_load事件: 怪物实体加载完成
事件系统优势
| 优势 | 说明 | 应用场景 |
|---|---|---|
| 松耦合 | 组件间无需直接依赖 | 怪物生成与场景管理 |
| 可扩展 | 易于添加新的事件处理器 | 新增功能模块 |
| 异步处理 | 支持异步事件流 | 怪物AI行为 |
章节来源
异常处理与调试策略
常见异常类型
1. 资源加载异常
try {
var prefab: Prefab = oops.res.get(path, Prefab)!;
var node = instantiate(prefab);
} catch (error) {
console.error(`[Monster] 预制体加载失败: ${path}`, error);
// 回退到默认预制体或显示错误界面
}
2. UUID越界异常
if (!HeroInfo[uuid]) {
console.error(`[Monster] 未知的怪物UUID: ${uuid}`);
// 使用默认怪物配置
uuid = 5201; // 兽人战士作为默认值
}
3. 节点层级缺失异常
if (!scene.entityLayer || !scene.entityLayer.node) {
console.error('[Monster] 场景实体层不存在');
// 创建默认场景结构
}
调试策略
1. 日志记录系统
// 详细日志级别
console.log("[Mon] mission_data.mon_num:", smc.vmdata.mission_data.mon_num);
console.log("[Monster] 加载怪物:", uuid, "类型:", HeroInfo[uuid].type);
2. 断点调试技巧
// 在关键位置设置断点
if (process.env.NODE_ENV === 'development') {
debugger;
}
3. 性能监控
// 性能计时器
const startTime = performance.now();
// ... 执行加载操作
const endTime = performance.now();
console.log(`[Monster] 加载耗时: ${endTime - startTime}ms`);
异常恢复机制
资源回退策略
// 1. 尝试加载指定资源
// 2. 如果失败,尝试加载备用资源
// 3. 如果仍然失败,使用默认资源
配置验证
// 验证HeroInfo配置完整性
function validateHeroConfig(hero: heroInfo): boolean {
return hero &&
hero.hp > 0 &&
hero.ap > 0 &&
hero.def > 0 &&
hero.skills.length > 0;
}
章节来源
实际应用示例
生成普通怪物
// 创建普通怪物实例
let monster = ecs.getEntity<Monster>(Monster);
let pos: Vec3 = v3(240, 100, 0);
let scale = -1;
monster.load(
pos, // 初始位置
scale, // 缩放比例
5201, // 兽人战士UUID
false, // 非Boss
false, // 非召唤
1.0 // 强度倍率
);
生成Boss怪物
// 创建Boss怪物实例
let boss = ecs.getEntity<Monster>(Monster);
let bossPos: Vec3 = v3(400, 100, 0);
boss.load(
bossPos, // Boss专用位置
1, // 正向缩放
5201, // 使用相同基础配置
true, // Boss标志
false, // 非召唤
2.0 // 双倍强度
);
MissionMonComp中的批量生成
// 在MissionMonComp中批量生成怪物
private addMonster(
uuid: number = 1001,
i: number = 0,
is_boss: boolean = false,
is_call: boolean = false,
lv: number = 1,
strengthMultiplier: number = 1.0
) {
let mon = ecs.getEntity<Monster>(Monster);
let scale = -1;
let pos: Vec3 = v3(MonSet[i].pos);
mon.load(pos, scale, uuid, is_boss, is_call, strengthMultiplier);
}
强度倍率的实际效果
基础属性对比表
| 属性类型 | 基础值(1.0倍) | 1.5倍 | 2.0倍 | 2.5倍 |
|---|---|---|---|---|
| HP | 25 | 37 | 50 | 62 |
| AP | 5 | 7 | 10 | 12 |
| DEF | 5 | 7 | 10 | 12 |
| MP | 100 | 100 | 100 | 100 |
章节来源
总结
Monster类的load方法和hero_init方法构成了游戏怪物系统的核心基础设施,通过以下关键技术实现了灵活而强大的怪物生成机制:
核心技术特点
- 动态资源加载: 基于UUID的预制体动态加载,支持运行时配置
- 属性倍率系统: 通过strengthMultiplier参数实现怪物强度的灵活调整
- ECS架构模式: 清晰的组件分离,便于维护和扩展
- 事件驱动通信: 松耦合的消息系统,支持复杂的业务逻辑
- 异常处理机制: 完善的错误处理和恢复策略
性能优化要点
- 预制体缓存: 利用Oops Framework的资源管理系统
- 延迟初始化: 碰撞体的延迟启用减少初始化开销
- 批量操作: MissionMonComp中的批量怪物生成
- 内存管理: 及时清理不再使用的怪物实体
扩展建议
- 配置系统增强: 支持更多的怪物类型和属性变体
- AI行为系统: 集成更复杂的怪物AI逻辑
- 视觉效果: 添加更多的怪物特效和动画
- 平衡性调整: 提供更精细的难度调节机制
通过深入理解这些机制,开发者可以更好地维护和扩展游戏的怪物系统,为玩家提供更加丰富和有趣的游戏体验。