Files
pixelheros/.qoder/repowiki/zh/content/地图系统/怪物系统/怪物实体/怪物实体初始化流程.md
panw 4235e3b776 refactor(game): 移除已弃用的事件常量
- 删除 UpdateHero 和 UpdateFightHero 事件
- 移除 MISSION_UPDATE 事件常量
- 优化游戏事件枚举定义
2025-10-28 16:15:47 +08:00

16 KiB
Raw Blame History

怪物实体初始化流程

**本文档中引用的文件** - [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)

目录

  1. 概述
  2. 项目结构分析
  3. 核心组件架构
  4. Monster类load方法详解
  5. hero_init方法深度解析
  6. 资源加载与预制体管理
  7. 场景节点挂载机制
  8. 消息事件系统
  9. 异常处理与调试策略
  10. 实际应用示例
  11. 总结

概述

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类采用ECSEntity-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);
}

事件处理流程

  1. FightReady事件: 准备战斗阶段
  2. NewWave事件: 新一波怪物生成
  3. 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方法构成了游戏怪物系统的核心基础设施通过以下关键技术实现了灵活而强大的怪物生成机制

核心技术特点

  1. 动态资源加载: 基于UUID的预制体动态加载支持运行时配置
  2. 属性倍率系统: 通过strengthMultiplier参数实现怪物强度的灵活调整
  3. ECS架构模式: 清晰的组件分离,便于维护和扩展
  4. 事件驱动通信: 松耦合的消息系统,支持复杂的业务逻辑
  5. 异常处理机制: 完善的错误处理和恢复策略

性能优化要点

  • 预制体缓存: 利用Oops Framework的资源管理系统
  • 延迟初始化: 碰撞体的延迟启用减少初始化开销
  • 批量操作: MissionMonComp中的批量怪物生成
  • 内存管理: 及时清理不再使用的怪物实体

扩展建议

  1. 配置系统增强: 支持更多的怪物类型和属性变体
  2. AI行为系统: 集成更复杂的怪物AI逻辑
  3. 视觉效果: 添加更多的怪物特效和动画
  4. 平衡性调整: 提供更精细的难度调节机制

通过深入理解这些机制,开发者可以更好地维护和扩展游戏的怪物系统,为玩家提供更加丰富和有趣的游戏体验。