add vision

This commit is contained in:
2025-01-20 00:05:48 +09:00
parent 634dde2a3b
commit bf38f69071
8 changed files with 241 additions and 84 deletions
+65 -5
View File
@@ -1,4 +1,5 @@
import { EventEmitter } from 'node:events'
import { Vector2 } from 'three'
import Ability from './ability.js'
import Buff from './buff.js'
import Entity from './entity.js'
@@ -11,12 +12,13 @@ export default class Game {
averageTick = 0
currentTick = 0
entities = []
height = 1000
gameLoopIntervalId = null
height = 0
projectiles = []
secondToSlowestTick = 0
terrains = []
tickRate = 30
width = 1000
width = 0
#behindMs = 0
#currentTiming = 0
@@ -35,6 +37,20 @@ export default class Game {
return this.terrains.map((t) => t.unadjustedWaypoints).concat(this.entities.map((e) => e.unadjustedWaypoints)).flat()
}
action(id, options) {
const entity = this.entities.find((it) => it.id == id)
if (entity == null) {
console.error({ error: 'Invalid ID' })
return
}
if (options.action == 'attack') { entity.attackAction(new Vector2(options.x, options.y)) }
if (options.action == 'cast') { entity.castAction(options.slot, new Vector2(options.x, options.y)) }
if (options.action == 'halt') { entity.haltAction(), delay }
if (options.action == 'stop') { entity.stopAction() }
if (options.action == 'move') { entity.moveAction(new Vector2(options.x, options.y)) }
}
addTerrain(terrain) {
this.terrains.push(terrain)
}
@@ -82,7 +98,28 @@ export default class Game {
}
start() {
setInterval(this.#gameLoopCall.bind(this), 1)
if (this.gameLoopIntervalId != null) { return }
this.gameLoopIntervalId = setInterval(this.#gameLoopCall.bind(this), 1)
}
stop() {
if (this.gameLoopIntervalId == null) { return }
clearInterval(this.gameLoopIntervalId)
this.gameLoopIntervalId = null
}
subscription(websocket, id) {
return function builtSubscription() {
const game = this
const entity = game.entities.find((it) => it.id == id)
if (entity == null) { return }
const team = entity.team
const message = game.visionByTeam(team)
websocket.send(JSON.stringify(message))
}
}
update() {
@@ -98,8 +135,31 @@ export default class Game {
this.currentTick++
}
visionByTeam() {
return null // TODO: vision
visibleEntities(team) {
const visionSources = this.visionSources(team)
return Array.from(new Set(visionSources.map((it) => it.entitiesInVision()).flat()))
}
visibleProjectiles(team) {
const visionSources = this.visionSources(team)
return Array.from(new Set(visionSources.map((it) => it.projectilesInVision()).flat()))
}
visionSources(team) {
const entityVisionSources = this.entities.filter((it) => it.team == team)
const projectileVisionSources = this.projectiles.filter((it) => it.visionRange > 0 && (it.team == null || it.team == team))
return entityVisionSources.concat(projectileVisionSources)
}
visionByTeam(team) {
const visionSources = this.visionSources(team)
const visibleEntities = new Set(visionSources.map((it) => it.entitiesInVision()).flat())
const visibleProjectiles = new Set(visionSources.map((it) => it.projectilesInVision()).flat())
return {
...this,
entities: this.entities.filter((it) => visibleEntities.has(it.id)),
projectiles: this.projectiles.filter((it) => visibleProjectiles.has(it.id)),
}
}
#calculateTickMetrics() {