refactor(hero): 优化英雄对象池管理及视图初始化
- 在Monster类中实现多键对象池管理,提升英雄节点复用效率 - 将HeroViewComp的初始化逻辑提取到独立init方法,便于对象池复用时重置状态 - 移除HeroSpine中冗余的onDestroy方法 - 修复HeroViewComp中方向缩放计算问题,确保scale.x为正 - 优化碰撞体启用逻辑,延迟一帧确保物理系统正确注册 - 清理HeroViewComp中残留的定时器和缓动
This commit is contained in:
@@ -12,11 +12,11 @@ const { ccclass, property } = _decorator;
|
|||||||
@ccclass('Main')
|
@ccclass('Main')
|
||||||
export class Main extends Root {
|
export class Main extends Root {
|
||||||
start() {
|
start() {
|
||||||
// PhysicsSystem2D.instance.debugDrawFlags = EPhysics2DDrawFlags.Aabb
|
PhysicsSystem2D.instance.debugDrawFlags = EPhysics2DDrawFlags.Aabb
|
||||||
// |EPhysics2DDrawFlags.Pair
|
|EPhysics2DDrawFlags.Pair
|
||||||
// |EPhysics2DDrawFlags.CenterOfMass
|
|EPhysics2DDrawFlags.CenterOfMass
|
||||||
// |EPhysics2DDrawFlags.Joint
|
|EPhysics2DDrawFlags.Joint
|
||||||
// |EPhysics2DDrawFlags.Shape;
|
|EPhysics2DDrawFlags.Shape;
|
||||||
}
|
}
|
||||||
protected async run() {
|
protected async run() {
|
||||||
smc.initialize = ecs.getEntity<Initialize>(Initialize);
|
smc.initialize = ecs.getEntity<Initialize>(Initialize);
|
||||||
|
|||||||
@@ -85,8 +85,5 @@ export class HeroSpine extends Component {
|
|||||||
this.status="move"
|
this.status="move"
|
||||||
this.anm.move()
|
this.anm.move()
|
||||||
}
|
}
|
||||||
onDestroy() {
|
|
||||||
this.node.destroy();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Vec3, _decorator , v3,Collider2D,Contact2DType,Label ,Node,Prefab,instantiate,ProgressBar, Component, Material, Sprite, math, clamp, Game, tween, Color, BoxCollider2D, UITransform} from "cc";
|
import { Vec3, _decorator , v3,Collider2D,Contact2DType,Label ,Node,Prefab,instantiate,ProgressBar, Component, Material, Sprite, math, clamp, Game, tween, Tween, Color, BoxCollider2D, UITransform} from "cc";
|
||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||||
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
import { CCComp } from "../../../../extensions/oops-plugin-framework/assets/module/common/CCComp";
|
||||||
import { HeroSpine } from "./HeroSpine";
|
import { HeroSpine } from "./HeroSpine";
|
||||||
@@ -88,23 +88,29 @@ export class HeroViewComp extends CCComp {
|
|||||||
}
|
}
|
||||||
/** 视图层逻辑代码分离演示 */
|
/** 视图层逻辑代码分离演示 */
|
||||||
start () {
|
start () {
|
||||||
|
this.init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化/重置视图状态 */
|
||||||
|
init() {
|
||||||
this.as.idle()
|
this.as.idle()
|
||||||
|
|
||||||
// 初始化 UI 节点
|
// 初始化 UI 节点
|
||||||
this.initUINodes();
|
this.initUINodes();
|
||||||
|
|
||||||
/** 方向 */
|
/** 方向 */
|
||||||
this.node.setScale(this.scale*this.node.scale.x,1*this.node.scale.y);
|
this.node.setScale(this.scale*Math.abs(this.node.scale.x), 1*this.node.scale.y); // 确保 scale.x 为正后再乘方向
|
||||||
this.top_node.setScale(this.scale*this.top_node.scale.x,1*this.top_node.scale.y);
|
this.top_node.setScale(this.scale*this.top_node.scale.x,1*this.top_node.scale.y);
|
||||||
|
|
||||||
/* 显示角色血*/
|
/* 显示角色血*/
|
||||||
this.top_node.getChildByName("hp").active = true;
|
this.top_node.getChildByName("hp").active = true;
|
||||||
// 🔥 怪物不显示蓝条
|
// 🔥 怪物不显示蓝条
|
||||||
this.top_node.getChildByName("mp").active = this.model.fac === FacSet.HERO;
|
if (this.model) {
|
||||||
|
this.top_node.getChildByName("mp").active = this.model.fac === FacSet.HERO;
|
||||||
|
}
|
||||||
this.top_node.getChildByName("shield").active = false;
|
this.top_node.getChildByName("shield").active = false;
|
||||||
// 初始隐藏血条(有更新时才显示)
|
// 初始隐藏血条(有更新时才显示)
|
||||||
this.top_node.active = false;
|
this.top_node.active = false;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** 初始化 UI 节点引用 */
|
/** 初始化 UI 节点引用 */
|
||||||
@@ -513,6 +519,10 @@ export class HeroViewComp extends CCComp {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
reset() {
|
reset() {
|
||||||
|
// 清理残留的定时器和缓动
|
||||||
|
this.unscheduleAllCallbacks();
|
||||||
|
Tween.stopAllByTarget(this.node);
|
||||||
|
|
||||||
// 清理碰撞器事件监听
|
// 清理碰撞器事件监听
|
||||||
const collider = this.getComponent(Collider2D);
|
const collider = this.getComponent(Collider2D);
|
||||||
if (collider) {
|
if (collider) {
|
||||||
@@ -525,10 +535,10 @@ export class HeroViewComp extends CCComp {
|
|||||||
this.damageQueue.length = 0;
|
this.damageQueue.length = 0;
|
||||||
this.isProcessingDamage = false;
|
this.isProcessingDamage = false;
|
||||||
|
|
||||||
// 延迟销毁节点
|
// 节点生命周期由 Monster 对象池管理,此处不再销毁
|
||||||
this.scheduleOnce(() => {
|
// if (this.node && this.node.isValid) {
|
||||||
this.node.destroy();
|
// this.node.destroy();
|
||||||
}, 0.1);
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { instantiate, Node, Prefab, Vec3 ,v3,resources,SpriteFrame,Sprite,SpriteAtlas, BoxCollider2D} from "cc";
|
import { instantiate, Node, Prefab, Vec3 ,v3,resources,SpriteFrame,Sprite,SpriteAtlas, BoxCollider2D, NodePool} from "cc";
|
||||||
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
import { oops } from "../../../../extensions/oops-plugin-framework/assets/core/Oops";
|
||||||
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
import { ecs } from "../../../../extensions/oops-plugin-framework/assets/libs/ecs/ECS";
|
||||||
import { smc } from "../common/SingletonModuleComp";
|
import { smc } from "../common/SingletonModuleComp";
|
||||||
@@ -19,6 +19,26 @@ export class Monster extends ecs.Entity {
|
|||||||
HeroView!: HeroViewComp;
|
HeroView!: HeroViewComp;
|
||||||
MonMove!: MonMoveComp;
|
MonMove!: MonMoveComp;
|
||||||
|
|
||||||
|
// 多键对象池:Map<prefabPath, NodePool>
|
||||||
|
static pools: Map<string, NodePool> = new Map();
|
||||||
|
|
||||||
|
static getFromPool(path: string): Node | null {
|
||||||
|
if (this.pools.has(path)) {
|
||||||
|
const pool = this.pools.get(path)!;
|
||||||
|
if (pool.size() > 0) {
|
||||||
|
return pool.get();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
static putToPool(path: string, node: Node) {
|
||||||
|
if (!this.pools.has(path)) {
|
||||||
|
this.pools.set(path, new NodePool());
|
||||||
|
}
|
||||||
|
this.pools.get(path)!.put(node);
|
||||||
|
}
|
||||||
|
|
||||||
protected init() {
|
protected init() {
|
||||||
this.addComponents<ecs.Comp>(
|
this.addComponents<ecs.Comp>(
|
||||||
MonMoveComp,
|
MonMoveComp,
|
||||||
@@ -28,6 +48,14 @@ export class Monster extends ecs.Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
destroy(): void {
|
destroy(): void {
|
||||||
|
// 回收节点到对象池
|
||||||
|
const model = this.get(HeroAttrsComp);
|
||||||
|
const view = this.get(HeroViewComp);
|
||||||
|
if (model && view && view.node && view.node.isValid) {
|
||||||
|
const path = "game/heros/" + HeroInfo[model.hero_uuid].path;
|
||||||
|
Monster.putToPool(path, view.node);
|
||||||
|
}
|
||||||
|
|
||||||
this.remove(HeroViewComp);
|
this.remove(HeroViewComp);
|
||||||
this.remove(HeroAttrsComp);
|
this.remove(HeroAttrsComp);
|
||||||
this.remove(HeroSkillsComp);
|
this.remove(HeroSkillsComp);
|
||||||
@@ -40,8 +68,14 @@ export class Monster extends ecs.Entity {
|
|||||||
let size=1
|
let size=1
|
||||||
var scene = smc.map.MapView.scene;
|
var scene = smc.map.MapView.scene;
|
||||||
var path = "game/heros/"+HeroInfo[uuid].path;
|
var path = "game/heros/"+HeroInfo[uuid].path;
|
||||||
var prefab: Prefab = oops.res.get(path, Prefab)!;
|
|
||||||
var node = instantiate(prefab);
|
// 尝试从池中获取
|
||||||
|
let node = Monster.getFromPool(path);
|
||||||
|
if (!node) {
|
||||||
|
var prefab: Prefab = oops.res.get(path, Prefab)!;
|
||||||
|
node = instantiate(prefab);
|
||||||
|
}
|
||||||
|
|
||||||
let LINE1=scene.entityLayer!.node!.getChildByName("LINE1")!;
|
let LINE1=scene.entityLayer!.node!.getChildByName("LINE1")!;
|
||||||
let LINE2=scene.entityLayer!.node!.getChildByName("LINE2")!;
|
let LINE2=scene.entityLayer!.node!.getChildByName("LINE2")!;
|
||||||
let LINE3=scene.entityLayer!.node!.getChildByName("LINE3")!;
|
let LINE3=scene.entityLayer!.node!.getChildByName("LINE3")!;
|
||||||
@@ -49,11 +83,22 @@ export class Monster extends ecs.Entity {
|
|||||||
// 🔥 设置初始 SiblingIndex - 防止溢出
|
// 🔥 设置初始 SiblingIndex - 防止溢出
|
||||||
const baseLane = lane === 0 ? LINE1 : lane === 1 ? LINE2 : lane === 2 ? LINE3 : LINE4;
|
const baseLane = lane === 0 ? LINE1 : lane === 1 ? LINE2 : lane === 2 ? LINE3 : LINE4;
|
||||||
node.parent = baseLane
|
node.parent = baseLane
|
||||||
|
var view = node.getComponent(HeroViewComp)!;
|
||||||
const collider = node.getComponent(BoxCollider2D);
|
const collider = node.getComponent(BoxCollider2D);
|
||||||
if (collider) collider.enabled = false; // 先禁用 // 延迟一帧启用碰撞体
|
if (collider) {
|
||||||
|
// 先禁用,下一帧启用,确保物理系统能正确注册新激活的节点
|
||||||
|
collider.enabled = false;
|
||||||
|
view.scheduleOnce(() => {
|
||||||
|
if (node && node.isValid) {
|
||||||
|
collider.enabled = true;
|
||||||
|
collider.group = BoxSet.MONSTER; // 确保碰撞组正确
|
||||||
|
collider.apply(); // 强制应用更改(如果需要)
|
||||||
|
}
|
||||||
|
}, 0); // 0延迟等于下一帧执行
|
||||||
|
}
|
||||||
|
|
||||||
node.setScale(size*node.scale.x,size*node.scale.y);
|
node.setScale(size*node.scale.x,size*node.scale.y);
|
||||||
node.setPosition(pos)
|
node.setPosition(pos)
|
||||||
var view = node.getComponent(HeroViewComp)!;
|
|
||||||
const model = this.get(HeroAttrsComp);
|
const model = this.get(HeroAttrsComp);
|
||||||
const skillsComp = this.get(HeroSkillsComp);
|
const skillsComp = this.get(HeroSkillsComp);
|
||||||
let hero = HeroInfo[uuid]; // 共用英雄数据
|
let hero = HeroInfo[uuid]; // 共用英雄数据
|
||||||
@@ -87,6 +132,9 @@ export class Monster extends ecs.Entity {
|
|||||||
skillsComp.initSkills(hero.skills, uuid, this);
|
skillsComp.initSkills(hero.skills, uuid, this);
|
||||||
|
|
||||||
this.add(view);
|
this.add(view);
|
||||||
|
// 重置视图状态(对象池复用时必须)
|
||||||
|
view.init();
|
||||||
|
|
||||||
oops.message.dispatchEvent("monster_load",this)
|
oops.message.dispatchEvent("monster_load",this)
|
||||||
|
|
||||||
// 初始化移动参数,包括线路和生成顺序
|
// 初始化移动参数,包括线路和生成顺序
|
||||||
|
|||||||
Reference in New Issue
Block a user