diff --git a/src/ability.js b/src/ability.js index 18cfe03..9dad9ed 100644 --- a/src/ability.js +++ b/src/ability.js @@ -4,7 +4,6 @@ import Projectile from './projectile.js' export default class Ability { static skillshot({ range, radius, speed, onCollide, after }) { return function(x, y) { - console.log(this) const projectile = new Projectile() const destination = this.position.clone().add(new Vector2(x, y).sub(this.position).normalize().multiplyScalar(range)) projectile.owner = this.id @@ -17,4 +16,31 @@ export default class Ability { this.game?.spawnProjectile(projectile) } } + + static homingProjectile({ range, radius, speed, onCollide, after }) { + return function(x, y) { + const cursor = new Vector2(x, y) + let closest = null + let distance = Infinity + this.game?.entities.filter((e) => e.id != this.id && e.position.clone().sub(this.position).length() < range).forEach((e) => { + const newDistance = e.position.clone().sub(cursor).length() < distance + if (newDistance < distance) { + closest = e + distance = newDistance + } + }) + + if (closest == null) { return } // TODO: refund + + const projectile = new Projectile() + projectile.owner = this.id + projectile.position.copy(this.position) + projectile.homingTarget = closest + projectile.radius = radius + projectile.speed = speed + projectile.after = after + projectile.onCollide = onCollide + this.game?.spawnProjectile(projectile) + } + } } diff --git a/src/entity.js b/src/entity.js index 4c1b913..e266bde 100644 --- a/src/entity.js +++ b/src/entity.js @@ -12,7 +12,7 @@ export default class Entity { health = 1 maxHealth = 1 abilities = [ - () => {}, + Ability.homingProjectile({ range: 600, radius: 3, speed: 500, onCollide: Effect.damage({ despawn: true }) }), Ability.skillshot({ range: 800, radius: 5, speed: 3000, onCollide: Effect.damage({ despawn: true }) }), () => {}, () => {}, diff --git a/src/projectile.js b/src/projectile.js index d363d0b..4adcc24 100644 --- a/src/projectile.js +++ b/src/projectile.js @@ -13,12 +13,25 @@ export default class Projectile { #position = new Vector2() #dest = null + #homingTarget = null #game = null get collider() { return new SAT.Circle(new SAT.Vector(this.x, this.y), this.radius) } + get homing() { + return !!this.#homingTarget + } + + get destination() { + return this.#dest ?? this.#homingTarget?.position + } + + set homingTarget(value) { + this.#homingTarget = value + } + constructor(...options) { Object.entries(options).forEach((value, key) => this[key] = value) } @@ -43,7 +56,7 @@ export default class Projectile { } checkIfArrived() { - if (!this.#position.equals(this.#dest)) { return } + if (!this.#position.equals(this.destination)) { return } if (this.after != null) { this.after(this) @@ -68,7 +81,7 @@ export default class Projectile { takeStep() { const speed = (this.speed / (this.game?.tickBudget ?? 1000)) - const destination = this.#dest + const destination = this.destination const difference = destination.clone().sub(this.position) const distance = difference.length() const direction = difference.clone().normalize()