Spaces:
Running
Running
File size: 1,895 Bytes
b29710c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
import * as THREE from "three";
export class Projectile {
constructor(pos, target, speed, scene, projectileEffect = null) {
this.position = pos.clone();
this.target = target;
this.speed = speed;
this.scene = scene;
this.damage = 0; // Will be set by tower
this.projectileEffect = projectileEffect;
const geo = new THREE.SphereGeometry(0.15, 8, 8);
const mat = new THREE.MeshStandardMaterial({
color:
projectileEffect && projectileEffect.color
? projectileEffect.color
: 0xffe082,
emissive:
projectileEffect && projectileEffect.emissive
? projectileEffect.emissive
: 0x553300,
});
const mesh = new THREE.Mesh(geo, mat);
mesh.castShadow = true;
mesh.position.copy(this.position);
this.mesh = mesh;
scene.add(mesh);
this.alive = true;
}
update(dt, spawnHitEffect) {
if (!this.alive) return "dead";
if (!this.target || this.target.isDead()) {
this.alive = false;
return "dead";
}
const toTarget = new THREE.Vector3().subVectors(
this.target.mesh.position,
this.position
);
const dist = toTarget.length();
if (dist < 0.4) {
this.target.takeDamage(this.damage);
// Apply on-hit effect if any
if (
this.projectileEffect &&
this.projectileEffect.type === "slow" &&
this.target.applySlow
) {
const mult = this.projectileEffect.mult ?? 1.0;
const duration = this.projectileEffect.duration ?? 0;
this.target.applySlow(mult, duration);
}
spawnHitEffect(this.position);
this.alive = false;
return "hit";
}
toTarget.normalize();
this.position.addScaledVector(toTarget, this.speed * dt);
this.mesh.position.copy(this.position);
return "ok";
}
destroy() {
this.scene.remove(this.mesh);
}
}
|