docs: 为游戏地图模块添加详细的代码注释
为游戏地图模块的脚本文件添加全面的注释,说明每个组件的职责、关键设计、依赖关系和使用方式。注释覆盖了英雄信息面板、技能卡槽位管理器、排行榜弹窗、卡牌控制器、背景滚动组件等核心功能模块,提高了代码的可读性和维护性。 同时修复了英雄预制体的激活状态和技能效果预制体的尺寸参数。
This commit is contained in:
@@ -1,3 +1,30 @@
|
||||
/**
|
||||
* @file SkillBoxComp.ts
|
||||
* @description 单个技能卡效果控制组件(UI 视图层 + 逻辑层)
|
||||
*
|
||||
* 职责:
|
||||
* 1. 表示一张已使用的技能卡在战场上的 **可视化实体**。
|
||||
* 2. 管理技能的 **触发逻辑**:即时触发 vs 定时触发(战斗中按间隔触发)。
|
||||
* 3. 显示技能图标和剩余触发次数。
|
||||
* 4. 触发结束后自动销毁。
|
||||
*
|
||||
* 关键设计:
|
||||
* - is_instant=true(即时技能):init 时立即触发一次,播放后延迟销毁。
|
||||
* - is_instant=false(持续技能):战斗中每隔 trigger_interval 秒触发一次,
|
||||
* 共触发 trigger_times 次后销毁。
|
||||
* - 新一波(NewWave)时如果持续技能的次数已用完则销毁。
|
||||
* - 销毁时通过 GameEvent.RemoveSkillBox 通知 MissSkillsComp 回收槽位。
|
||||
*
|
||||
* 触发技能的方式:
|
||||
* - 通过 GameEvent.TriggerSkill 事件,将技能 UUID、卡牌等级、
|
||||
* 触发位置等信息分发给技能系统。
|
||||
*
|
||||
* 依赖:
|
||||
* - CardPoolList(CardSet)—— 查询技能卡的触发配置(t_times / t_inv / is_inst)
|
||||
* - SkillSet —— 技能静态配置(icon 字段)
|
||||
* - GameEvent —— 各类游戏事件
|
||||
* - smc.mission —— 游戏运行状态
|
||||
*/
|
||||
import { mLogger } from "../common/Logger";
|
||||
import { _decorator, Node, Prefab, Sprite, Label, Vec3, resources, SpriteAtlas } from "cc";
|
||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||
@@ -9,27 +36,53 @@ import { GameEvent } from "../common/config/GameEvent";
|
||||
import { smc } from "../common/SingletonModuleComp";
|
||||
const { ccclass, property } = _decorator;
|
||||
|
||||
/** 视图层对象 */
|
||||
/**
|
||||
* SkillBoxComp —— 单个技能卡效果视图 + 逻辑组件
|
||||
*
|
||||
* 由 MissSkillsComp.addSkill() 实例化并初始化。
|
||||
* 在战场上以图标 + 剩余次数的形式呈现。
|
||||
*/
|
||||
@ccclass('SkillBoxComp')
|
||||
@ecs.register('SkillBoxComp', false)
|
||||
export class SkillBoxComp extends CCComp {
|
||||
/** 调试日志开关 */
|
||||
private debugMode: boolean = true;
|
||||
|
||||
/** 技能图标节点 */
|
||||
@property({type: Node})
|
||||
private icon_node:Node= null;
|
||||
|
||||
/** 剩余次数标签 */
|
||||
@property(Label)
|
||||
private info_label: Label = null;
|
||||
|
||||
// ======================== 技能配置 ========================
|
||||
|
||||
/** 技能 UUID */
|
||||
private s_uuid: number = 0;
|
||||
/** 卡牌等级 */
|
||||
private card_lv: number = 1;
|
||||
/** 是否为即时技能(true=使用后立即触发,false=战斗中定时触发) */
|
||||
private is_instant: boolean = true;
|
||||
/** 总触发次数 */
|
||||
private trigger_times: number = 1;
|
||||
/** 触发间隔(秒,仅持续技能有效) */
|
||||
private trigger_interval: number = 0;
|
||||
|
||||
// ======================== 运行时状态 ========================
|
||||
|
||||
/** 已触发次数 */
|
||||
private current_trigger_times: number = 0;
|
||||
/** 当前计时器(秒) */
|
||||
private timer: number = 0;
|
||||
/** 是否处于战斗中(仅战斗中持续技能才计时) */
|
||||
private in_combat: boolean = false;
|
||||
/** 是否已初始化 */
|
||||
private initialized: boolean = false;
|
||||
|
||||
// ======================== 生命周期 ========================
|
||||
|
||||
/** 注册战斗开始、任务结束、新一波等事件 */
|
||||
onLoad() {
|
||||
oops.message.on(GameEvent.FightStart, this.onFightStart, this);
|
||||
oops.message.on(GameEvent.MissionEnd, this.onMissionEnd, this);
|
||||
@@ -37,19 +90,30 @@ export class SkillBoxComp extends CCComp {
|
||||
oops.message.on(GameEvent.NewWave, this.onNewWaveGlobal, this);
|
||||
}
|
||||
|
||||
/** 销毁时移除所有事件监听并通知槽位管理器回收 */
|
||||
onDestroy() {
|
||||
oops.message.off(GameEvent.FightStart, this.onFightStart, this);
|
||||
oops.message.off(GameEvent.MissionEnd, this.onMissionEnd, this);
|
||||
this.node.off(GameEvent.NewWave, this.onNewWave, this);
|
||||
oops.message.off(GameEvent.NewWave, this.onNewWaveGlobal, this);
|
||||
// 通知 MissSkillsComp 回收该节点占用的槽位
|
||||
oops.message.dispatchEvent(GameEvent.RemoveSkillBox, this.node);
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化技能卡效果:
|
||||
* 1. 从 CardPoolList 查询技能卡的触发配置。
|
||||
* 2. 更新 UI 显示(图标 + 次数)。
|
||||
* 3. 即时技能立即触发一次;若次数已满则延迟销毁。
|
||||
*
|
||||
* @param uuid 技能 UUID
|
||||
* @param card_lv 技能卡等级
|
||||
*/
|
||||
init(uuid: number, card_lv: number) {
|
||||
// this.node.parent=smc.map.MapView.scene.entityLayer!.node!
|
||||
this.s_uuid = uuid;
|
||||
this.card_lv = card_lv;
|
||||
|
||||
// 查询触发配置
|
||||
const config = CardPoolList.find(c => c.uuid === uuid);
|
||||
if (config) {
|
||||
this.is_instant = config.is_inst ?? true;
|
||||
@@ -64,18 +128,25 @@ export class SkillBoxComp extends CCComp {
|
||||
this.updateUI();
|
||||
|
||||
if (this.is_instant) {
|
||||
// 即时起效:立即触发
|
||||
// 即时技能:立即触发
|
||||
this.triggerSkill();
|
||||
this.current_trigger_times++;
|
||||
if (this.current_trigger_times >= this.trigger_times) {
|
||||
// 次数已满 → 延迟 1 秒后销毁(保留短暂视觉反馈)
|
||||
this.scheduleOnce(() => {
|
||||
this.node.destroy();
|
||||
}, 1.0); // 稍微延迟销毁,保证表现
|
||||
}, 1.0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新 UI:
|
||||
* - 图标:从 uicons 图集获取。
|
||||
* - 剩余次数:持续技能显示剩余数字,即时技能不显示。
|
||||
*/
|
||||
updateUI() {
|
||||
// 加载技能图标
|
||||
if (this.icon_node) {
|
||||
const iconId = SkillSet[this.s_uuid]?.icon || `${this.s_uuid}`;
|
||||
resources.load("gui/uicons", SpriteAtlas, (err, atlas) => {
|
||||
@@ -88,6 +159,7 @@ export class SkillBoxComp extends CCComp {
|
||||
});
|
||||
}
|
||||
|
||||
// 更新剩余次数标签
|
||||
if (this.info_label) {
|
||||
if (!this.is_instant) {
|
||||
const remain = Math.max(0, this.trigger_times - this.current_trigger_times);
|
||||
@@ -98,40 +170,56 @@ export class SkillBoxComp extends CCComp {
|
||||
}
|
||||
}
|
||||
|
||||
// ======================== 战斗状态事件 ========================
|
||||
|
||||
/** 战斗开始:标记进入战斗状态,持续技能开始计时 */
|
||||
private onFightStart() {
|
||||
if (!this.initialized) return;
|
||||
this.in_combat = true;
|
||||
|
||||
if (!this.is_instant) {
|
||||
// 战斗开始时,计时归0,重新计时
|
||||
this.timer = 0;
|
||||
this.timer = 0; // 重置计时器
|
||||
}
|
||||
}
|
||||
|
||||
/** 节点级新一波事件处理 */
|
||||
private onNewWave() {
|
||||
this.handleNewWave();
|
||||
}
|
||||
|
||||
/** 全局级新一波事件处理 */
|
||||
private onNewWaveGlobal() {
|
||||
this.handleNewWave();
|
||||
}
|
||||
|
||||
/**
|
||||
* 新一波:退出战斗状态。
|
||||
* 持续技能:若总次数已用完则销毁。
|
||||
*/
|
||||
private handleNewWave() {
|
||||
if (!this.initialized) return;
|
||||
this.in_combat = false;
|
||||
|
||||
if (!this.is_instant) {
|
||||
// 每回合不再重置次数,由全局次数进行控制
|
||||
if (this.current_trigger_times >= this.trigger_times) {
|
||||
this.node.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** 任务结束:强制销毁 */
|
||||
private onMissionEnd() {
|
||||
this.node.destroy();
|
||||
}
|
||||
|
||||
// ======================== 帧更新 ========================
|
||||
|
||||
/**
|
||||
* 每帧更新(仅对持续技能生效):
|
||||
* - 累加计时器,达到 trigger_interval 时触发一次技能。
|
||||
* - 触发后重置计时器并更新 UI。
|
||||
* - 总次数用完后延迟销毁。
|
||||
*/
|
||||
update(dt: number) {
|
||||
if (!this.initialized || !this.in_combat || this.is_instant) return;
|
||||
if (!smc.mission.play || smc.mission.pause) return;
|
||||
@@ -139,14 +227,13 @@ export class SkillBoxComp extends CCComp {
|
||||
if (this.current_trigger_times < this.trigger_times) {
|
||||
this.timer += dt;
|
||||
if (this.timer >= this.trigger_interval) {
|
||||
this.timer = 0; // 触发后重新计时
|
||||
this.timer = 0;
|
||||
this.triggerSkill();
|
||||
this.current_trigger_times++;
|
||||
this.updateUI(); // 触发后更新界面显示的剩余次数
|
||||
this.updateUI();
|
||||
|
||||
// 如果在战斗中就达到触发次数上限,则可以在此回合战斗结束或者立即销毁
|
||||
// 次数用完 → 延迟销毁
|
||||
if (this.current_trigger_times >= this.trigger_times) {
|
||||
// 可以选择直接销毁,不等到下一回合
|
||||
this.scheduleOnce(() => {
|
||||
if (this.node.isValid) this.node.destroy();
|
||||
}, 0.5);
|
||||
@@ -155,10 +242,14 @@ export class SkillBoxComp extends CCComp {
|
||||
}
|
||||
}
|
||||
|
||||
// ======================== 技能触发 ========================
|
||||
|
||||
/**
|
||||
* 触发技能效果:
|
||||
* - 计算触发位置(节点局部坐标 + 父节点偏移)。
|
||||
* - 通过 GameEvent.TriggerSkill 事件将技能数据分发给技能系统。
|
||||
*/
|
||||
private triggerSkill() {
|
||||
// 获取自身在父节点下的局部坐标
|
||||
// UI 的局部坐标在 2D 相机中和实际的游戏逻辑坐标存在偏移关系,
|
||||
// 可以结合自身局部坐标做一次偏移,此处直接读取自身的 localPosition 加上父节点的偏移
|
||||
let targetPos = new Vec3();
|
||||
const localPos = this.node.position;
|
||||
const parentPos = this.node.parent ? this.node.parent.position : new Vec3(0, 0, 0);
|
||||
@@ -166,13 +257,13 @@ export class SkillBoxComp extends CCComp {
|
||||
|
||||
oops.message.dispatchEvent(GameEvent.TriggerSkill, {
|
||||
s_uuid: this.s_uuid,
|
||||
isCardSkill: true,
|
||||
isCardSkill: true, // 标记为卡牌技能(区别于英雄自身技能)
|
||||
card_lv: this.card_lv,
|
||||
targetPos: targetPos
|
||||
});
|
||||
}
|
||||
|
||||
/** 视图对象通过 ecs.Entity.remove(ModuleViewComp) 删除组件是触发组件处理自定义释放逻辑 */
|
||||
/** ECS 组件移除时销毁节点 */
|
||||
reset() {
|
||||
this.node.destroy();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user