fix projectiles phasing through stuff
This commit is contained in:
+9
-7
@@ -24,21 +24,23 @@ export default class Ability {
|
|||||||
Object.entries(options).forEach(([key, value]) => this[key] = value)
|
Object.entries(options).forEach(([key, value]) => this[key] = value)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: skill seemingly going right through minions without a registered hit
|
|
||||||
static straightShot = new Ability({
|
static straightShot = new Ability({
|
||||||
id: 'straight_shot',
|
id: 'straight_shot',
|
||||||
name: 'Straight Shot',
|
name: 'Straight Shot',
|
||||||
castTime: 0.1,
|
castTime: 0.25,
|
||||||
cooldown: 1,
|
cooldown: 1,
|
||||||
damage: 10,
|
damage: 10,
|
||||||
radius: 7,
|
radius: 60,
|
||||||
range: 800,
|
range: 1200,
|
||||||
speed: 3000,
|
speed: 2000,
|
||||||
effect: function straightShotEffect(caster, cursor) {
|
effect: function straightShotEffect(caster, cursor) {
|
||||||
const ability = this
|
const ability = this
|
||||||
const straightShotCollision = function straightShotCollision(projectile, collidingEntity) {
|
const straightShotCollision = function straightShotCollision(projectile, collidingEntity) {
|
||||||
collidingEntity.damage(ability.damage)
|
if (!projectile.memory.hit) {
|
||||||
projectile.despawn()
|
collidingEntity.damage(ability.damage)
|
||||||
|
projectile.memory.hit = true
|
||||||
|
projectile.destination = collidingEntity.position.clone()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const projectile = new Projectile({
|
const projectile = new Projectile({
|
||||||
|
|||||||
+3
-2
@@ -88,7 +88,7 @@ export default class Entity {
|
|||||||
this.moveAction(cursor, true)
|
this.moveAction(cursor, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
castAction(slot, cursor, halt = true) {
|
castAction(slot, cursor, halt = false) {
|
||||||
const ability = this.abilities[slot]
|
const ability = this.abilities[slot]
|
||||||
|
|
||||||
if (this.casting != null) {
|
if (this.casting != null) {
|
||||||
@@ -120,6 +120,7 @@ export default class Entity {
|
|||||||
this.#moving = false
|
this.#moving = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: cancelable and uncancelable abilities
|
||||||
moveAction(cursor, attack = false) {
|
moveAction(cursor, attack = false) {
|
||||||
if (this.casting != null && (!this.#attacking || this.casting.ability.id != this.abilities[0].id)) {
|
if (this.casting != null && (!this.#attacking || this.casting.ability.id != this.abilities[0].id)) {
|
||||||
this.casting = null
|
this.casting = null
|
||||||
@@ -146,7 +147,7 @@ export default class Entity {
|
|||||||
}
|
}
|
||||||
|
|
||||||
collider() {
|
collider() {
|
||||||
return new SAT.Circle(new SAT.Vector(this.x, this.y), this.radius)
|
return new SAT.Circle(new SAT.Vector(this.position.x, this.position.y), this.radius)
|
||||||
}
|
}
|
||||||
|
|
||||||
colliders() {
|
colliders() {
|
||||||
|
|||||||
+15
-9
@@ -1,6 +1,5 @@
|
|||||||
import { Vector2 } from 'three'
|
import { Vector2 } from 'three'
|
||||||
import { WebSocketExpress } from 'websocket-express'
|
import { WebSocketExpress } from 'websocket-express'
|
||||||
import Ability from './ability.js'
|
|
||||||
import Entity from './entity.js'
|
import Entity from './entity.js'
|
||||||
import express from 'express'
|
import express from 'express'
|
||||||
import Game from './game.js'
|
import Game from './game.js'
|
||||||
@@ -69,13 +68,13 @@ function laneScenario() {
|
|||||||
game.spawnEntity(player1)
|
game.spawnEntity(player1)
|
||||||
player1.attackAction(new Vector2(500, 150))
|
player1.attackAction(new Vector2(500, 150))
|
||||||
|
|
||||||
const player2 = new Entity(Template.player({
|
// const player2 = new Entity(Template.player({
|
||||||
id: '2',
|
// id: '2',
|
||||||
spawnPosition: new Vector2(1600, 1800),
|
// spawnPosition: new Vector2(1600, 1800),
|
||||||
team: Team.red,
|
// team: Team.red,
|
||||||
}))
|
// }))
|
||||||
game.spawnEntity(player2)
|
// game.spawnEntity(player2)
|
||||||
player2.attackAction(new Vector2(1600, 1800))
|
// player2.attackAction(new Vector2(1600, 1800))
|
||||||
|
|
||||||
const midWallStart = new Vector2(600, 600)
|
const midWallStart = new Vector2(600, 600)
|
||||||
const midWallEnd = new Vector2(1400, 1400)
|
const midWallEnd = new Vector2(1400, 1400)
|
||||||
@@ -117,7 +116,7 @@ function laneScenario() {
|
|||||||
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: true, route: redRoute })))
|
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: true, route: redRoute })))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
game.logic = gameLogic
|
// game.logic = gameLogic
|
||||||
|
|
||||||
// const uBottomPoints = [
|
// const uBottomPoints = [
|
||||||
// midSouthWallPoints.at(0).clone().sub(midWallThickness),
|
// midSouthWallPoints.at(0).clone().sub(midWallThickness),
|
||||||
@@ -128,6 +127,13 @@ function laneScenario() {
|
|||||||
// const uBottom = new Terrain(uBottomPoints)
|
// const uBottom = new Terrain(uBottomPoints)
|
||||||
// uBottom.id = 'uBottom'
|
// uBottom.id = 'uBottom'
|
||||||
// game.addTerrain(uBottom)
|
// game.addTerrain(uBottom)
|
||||||
|
|
||||||
|
const minion = new Entity({...Template.minion(Team.red, { ranged: true }), logic: null})
|
||||||
|
minion.teleport(new Vector2(850, 250))
|
||||||
|
game.spawnEntity(minion)
|
||||||
|
|
||||||
|
player1.stopAction()
|
||||||
|
player1.castAction(1, new Vector2(850, 250))
|
||||||
}
|
}
|
||||||
|
|
||||||
app.listen(port, () => {
|
app.listen(port, () => {
|
||||||
|
|||||||
+14
-7
@@ -6,6 +6,7 @@ export default class Projectile {
|
|||||||
id = crypto.randomUUID()
|
id = crypto.randomUUID()
|
||||||
after = null
|
after = null
|
||||||
height = 50
|
height = 50
|
||||||
|
memory = {} // TODO: WARNING: currently only used for hit detection (code smell?)
|
||||||
onCollide = null
|
onCollide = null
|
||||||
owner = null
|
owner = null
|
||||||
position = new Vector2()
|
position = new Vector2()
|
||||||
@@ -29,18 +30,18 @@ export default class Projectile {
|
|||||||
Object.entries(options).forEach(([key, value]) => this[key] = value)
|
Object.entries(options).forEach(([key, value]) => this[key] = value)
|
||||||
}
|
}
|
||||||
|
|
||||||
checkCollisions() {
|
checkCollisions(collider) {
|
||||||
(this.game?.entities ?? []).filter((e) => e.id != this.id).forEach((e) => {
|
(this.game?.entities ?? []).filter((e) => e.id != this.id).forEach((e) => {
|
||||||
if (e.id == this.owner?.id) { return }
|
if (e.id == this.owner?.id) { return }
|
||||||
|
|
||||||
if (SATX.collideObject(this.collider(), e.collider())) {
|
if (SATX.collideObject(collider, e.collider())) {
|
||||||
this.onCollide(this, e)
|
if (this.onCollide != null) { this.onCollide(this, e) }
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
collider() {
|
collider() {
|
||||||
return new SAT.Circle(new SAT.Vector(this.x, this.y), this.radius)
|
return new SAT.Circle(new SAT.Vector(this.position.x, this.position.y), this.radius)
|
||||||
}
|
}
|
||||||
|
|
||||||
despawn() {
|
despawn() {
|
||||||
@@ -55,11 +56,12 @@ export default class Projectile {
|
|||||||
|
|
||||||
update() {
|
update() {
|
||||||
this.#move()
|
this.#move()
|
||||||
if (this.onCollide != null) { this.checkCollisions() }
|
if (this.onCollide != null) { this.checkCollisions(this.collider()) }
|
||||||
this.#checkIfArrived()
|
this.#checkIfArrived()
|
||||||
}
|
}
|
||||||
|
|
||||||
#checkIfArrived() {
|
#checkIfArrived() {
|
||||||
|
if (this.destination == null) { return }
|
||||||
if (!this.position.equals(this.destination)) { return }
|
if (!this.position.equals(this.destination)) { return }
|
||||||
|
|
||||||
if (this.after != null) {
|
if (this.after != null) {
|
||||||
@@ -71,11 +73,16 @@ export default class Projectile {
|
|||||||
|
|
||||||
#move() {
|
#move() {
|
||||||
const speed = (this.speed / (this.game?.tickBudget ?? 1000))
|
const speed = (this.speed / (this.game?.tickBudget ?? 1000))
|
||||||
|
const prevPos = this.position.clone()
|
||||||
if (this.position.distanceTo(this.destination) < speed) {
|
if (this.position.distanceTo(this.destination) < speed) {
|
||||||
this.position.copy(this.destination)
|
this.position.copy(this.destination)
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
const step = this.destination.clone().sub(this.position).normalize().multiplyScalar(speed)
|
||||||
|
this.position.add(step)
|
||||||
|
}
|
||||||
|
|
||||||
const step = this.destination.clone().sub(this.position).normalize().multiplyScalar(speed)
|
const tunnel = SATX.entityTunnel(prevPos.x, prevPos.y, this.position.x, this.position.y, this.radius)
|
||||||
this.position.add(step)
|
if (this.onCollide != null) { this.checkCollisions(tunnel) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user