79 lines
2.5 KiB
TypeScript
79 lines
2.5 KiB
TypeScript
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);
|
||
}
|
||
}
|