Files
heros/assets/script/game/skill/ProjectileComp.ts
2025-02-02 14:48:06 +08:00

79 lines
2.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Vec3 } from "cc";
import { ecs } from "db://oops-framework/libs/ecs/ECS";
import { HeroViewComp } from "../hero/HeroViewComp";
// 投射物组件
@ecs.register('Projectile')
export class ProjectileComp extends ecs.Comp {
speed: number = 500; // 飞行速度
direction: Vec3 = Vec3.RIGHT;// 飞行方向
maxDistance: number = 1000; // 最大射程
traveled: number = 0; // 已飞行距离
penetrate: number = 3; // 穿透次数
targets = new Set<ecs.Entity>(); // 已命中目标
reset() {
this.speed = 500;
this.direction.set(Vec3.RIGHT);
this.maxDistance = 1000;
this.traveled = 0;
this.penetrate = 3;
this.targets.clear();
}
}
// 投射物系统
@ecs.register('ProjectileSystem')
export class ProjectileSystem extends ecs.ComblockSystem implements ecs.ISystemUpdate {
filter(): ecs.IMatcher {
return ecs.allOf(ProjectileComp, HeroViewComp);
}
update(e: ecs.Entity): void {
const proj = e.get(ProjectileComp);
const view = e.get(HeroViewComp);
// 移动计算
const delta = proj.direction.multiplyScalar(proj.speed * this.dt);
view.node.position = view.node.position.add(delta);
proj.traveled += delta.length();
// 碰撞检测使用ECS组件检测
this.checkCollision(e);
// 超出射程销毁
if (proj.traveled >= proj.maxDistance) {
e.destroy();
}
}
private checkCollision(e: ecs.Entity) {
const proj = e.get(ProjectileComp);
const view = e.get(HeroViewComp);
// 获取范围内所有敌人
// const enemies = ecs.getEntities(HeroViewComp).filter(entity => {
// const enemyView = entity.get(HeroViewComp);
// return enemyView.boxGroup !== view.boxGroup &&
// Vec3.distance(view.node.position, enemyView.node.position) <= 50; // 碰撞半径
// });
// enemies.forEach(enemy => {
// if (!proj.targets.has(enemy)) {
// this.applyDamage(e, enemy);
// proj.targets.add(enemy);
// proj.penetrate--;
// }
// });
if (proj.penetrate <= 0) {
e.destroy();
}
}
private applyDamage(projectile: ecs.Entity, target: ecs.Entity) {
const projView = projectile.get(HeroViewComp);
const targetView = target.get(HeroViewComp);
// targetView.takeDamage(projView.attack);
}
}