87 lines
1.9 KiB
JavaScript
87 lines
1.9 KiB
JavaScript
import SAT from 'sat'
|
|
import SATX from './satx.js'
|
|
import { Vector2 } from 'three'
|
|
|
|
export default class Projectile {
|
|
id = crypto.randomUUID()
|
|
after = null
|
|
speed = 1000
|
|
radius = 5
|
|
owner = null
|
|
onCollide = null
|
|
visualHeight = 50
|
|
|
|
#position = new Vector2()
|
|
#dest = null
|
|
#game = null
|
|
|
|
get collider() {
|
|
return new SAT.Circle(new SAT.Vector(this.x, this.y), this.radius)
|
|
}
|
|
|
|
constructor(...options) {
|
|
Object.entries(options).forEach((value, key) => this[key] = value)
|
|
}
|
|
|
|
get game() { return this.#game }
|
|
get position() { return this.#position }
|
|
get x() { return this.position.x }
|
|
get y() { return this.position.y }
|
|
set game(value) { this.#game = value }
|
|
set x(value) { this.position.x = value }
|
|
set y(value) { this.position.y = value }
|
|
set destination(value) { this.#dest = value }
|
|
|
|
checkCollisions() {
|
|
(this.game?.entities ?? []).filter((e) => e.id != this.id).forEach((e) => {
|
|
if (e.id == this.owner) { return }
|
|
|
|
if (SATX.collideObject(this.collider, e.collider)) {
|
|
this.onCollide(this, e)
|
|
}
|
|
})
|
|
}
|
|
|
|
checkIfArrived() {
|
|
if (!this.#position.equals(this.#dest)) { return }
|
|
|
|
if (this.after != null) {
|
|
this.after(this)
|
|
}
|
|
|
|
this.despawn()
|
|
}
|
|
|
|
despawn() {
|
|
this.game?.despawn(this)
|
|
}
|
|
|
|
state() {
|
|
return {
|
|
...this,
|
|
position: {
|
|
x: this.x,
|
|
y: this.y,
|
|
},
|
|
}
|
|
}
|
|
|
|
takeStep() {
|
|
const speed = (this.speed / (this.game?.tickBudget ?? 1000))
|
|
const destination = this.#dest
|
|
const difference = destination.clone().sub(this.position)
|
|
const distance = difference.length()
|
|
const direction = difference.clone().normalize()
|
|
const stepTaken = this.position.clone().add(direction.multiplyScalar(speed))
|
|
const position = distance <= speed ? destination : stepTaken
|
|
|
|
this.position.copy(position)
|
|
}
|
|
|
|
update() {
|
|
this.takeStep()
|
|
if (this.onCollide != null) { this.checkCollisions() }
|
|
this.checkIfArrived()
|
|
}
|
|
}
|