使用ecs系统进行重构

This commit is contained in:
walkpan
2025-01-31 21:50:59 +08:00
parent 6ea3e9504d
commit c5c01c6cf4
18 changed files with 491 additions and 44 deletions

View File

@@ -0,0 +1,27 @@
@ecs.registerSystem()
export class DOTSystem extends ecs.System {
filter(): ecs.IMatcher {
return ecs.allOf(DOTComp);
}
update(entities: ecs.Entity[]) {
const delta = oops.timer.delta;
entities.forEach(hero => {
const dot = hero.get(DOTComp);
dot.duration -= delta;
// 每秒伤害
if (dot.accumulator >= 1) {
hero.get(HeroModelComp).hp -= dot.damagePerSec;
dot.accumulator -= 1;
}
dot.accumulator += delta;
// 效果结束
if (dot.duration <= 0) {
hero.remove(DOTComp);
}
});
}
}

View File

@@ -0,0 +1,19 @@
@ecs.registerSystem()
export class SkillCollisionSystem extends ecs.System {
filter(): ecs.IMatcher {
return ecs.allOf(SkillEffectComp, ColliderComp);
}
update(skills: ecs.Entity[]) {
skills.forEach(skill => {
const collider = skill.get(ColliderComp);
const collisionResult = skill.get(CollisionResultComp) || skill.add(CollisionResultComp);
// 检测碰撞(伪代码,实际使用物理引擎检测)
const hitHeroes = PhysicsSystem.overlap(collider.bounds, 'Hero');
// 转换为ECS实体
collisionResult.targets = hitHeroes.map(h => h.entity);
});
}
}

View File

@@ -0,0 +1,20 @@
// 技能效果组件
@ecs.register('SkillEffect')
export class SkillEffectComp extends ecs.Comp {
damage: number = 0; // 基础伤害
effectType: 'instant' | 'dot' = 'instant'; // 效果类型
duration: number = 0; // 持续时间DOT用
reset() {
this.damage = 0;
this.effectType = 'instant';
this.duration = 0;
}
}
// 碰撞结果组件
@ecs.register('CollisionResult')
export class CollisionResultComp extends ecs.Comp {
targets: ecs.Entity[] = []; // 碰撞到的英雄实体
reset() { this.targets = []; }
}

View File

@@ -0,0 +1,47 @@
@ecs.registerSystem()
export class SkillEffectSystem extends ecs.System {
filter(): ecs.IMatcher {
return ecs.allOf(SkillEffectComp, CollisionResultComp);
}
update(skills: ecs.Entity[]) {
skills.forEach(skill => {
const effect = skill.get(SkillEffectComp);
const targets = skill.get(CollisionResultComp).targets;
targets.forEach(hero => {
// 应用即时伤害
if (effect.effectType === 'instant') {
this.applyInstantDamage(hero, effect.damage);
}
// 应用持续效果
else if (effect.effectType === 'dot') {
this.applyDOT(hero, effect);
}
});
// 清除碰撞结果
skill.remove(CollisionResultComp);
});
}
private applyInstantDamage(hero: ecs.Entity, damage: number) {
const model = hero.get(HeroModelComp);
model.hp -= damage;
// 触发受击事件
oops.message.dispatch('HeroDamaged', {
hero,
damage,
currentHp: model.hp
});
}
private applyDOT(hero: ecs.Entity, effect: SkillEffectComp) {
// 添加持续伤害组件
hero.add(DOTComp, {
damagePerSec: effect.damage,
duration: effect.duration
});
}
}