use auto-incremented IDs instead of UUIDs

This commit is contained in:
2025-01-19 21:43:27 +09:00
parent e4f1fe19f4
commit 634dde2a3b
9 changed files with 127 additions and 110 deletions
+11 -4
View File
@@ -47,7 +47,12 @@ const entities = {}
const projectiles = {} const projectiles = {}
const positionTweens = {} const positionTweens = {}
const terrains = {} const terrains = {}
let state = { abilities: [], entities: [], terrains: [], projectiles: [] } var state = { abilities: [], entities: [], terrains: [], projectiles: [] }
global.entities = entities
global.projectiles = projectiles
global.terrains = terrains
global.state = state
const geometry = new THREE.PlaneGeometry(0, 0) const geometry = new THREE.PlaneGeometry(0, 0)
const material = new THREE.MeshToonMaterial({ color: 0x115011 }) const material = new THREE.MeshToonMaterial({ color: 0x115011 })
@@ -67,7 +72,7 @@ global.renderer = renderer
global.camera = camera global.camera = camera
global.scene = scene global.scene = scene
const tweenDuration = 33 var tweenDuration = 1
const keysDown = {} const keysDown = {}
const mouse = {} const mouse = {}
@@ -179,6 +184,10 @@ function connectWebSocket() {
state.byteSize = new Blob([event.data]).size state.byteSize = new Blob([event.data]).size
const stateUpdates = JSON.parse(event.data) const stateUpdates = JSON.parse(event.data)
if (stateUpdates.tickRate != null) {
tweenDuration = 1000 / stateUpdates.tickRate
}
if (stateUpdates.width != null && stateUpdates.height != null) { if (stateUpdates.width != null && stateUpdates.height != null) {
state.width = stateUpdates.width state.width = stateUpdates.width
state.height = stateUpdates.height state.height = stateUpdates.height
@@ -253,8 +262,6 @@ function connectWebSocket() {
} }
} }
// console.log(state)
if (state.width != null && state.height != null && (ground.geometry.attributes.width != state.width || ground.geometry.attributes.height != state.height)) { if (state.width != null && state.height != null && (ground.geometry.attributes.width != state.width || ground.geometry.attributes.height != state.height)) {
ground.geometry = new THREE.PlaneGeometry(state.width / 100, state.height / 100) ground.geometry = new THREE.PlaneGeometry(state.width / 100, state.height / 100)
ground.position.set(state.width / 200, state.height / 200, 0) ground.position.set(state.width / 200, state.height / 200, 0)
+4 -1
View File
@@ -4,7 +4,10 @@ import Projectile from './projectile.js'
// Three classes: Blade, Armor, Charm // Three classes: Blade, Armor, Charm
export default class Ability { export default class Ability {
id = crypto.randomUUID() id = `ability-${Ability.nextId()}`
static nextId() { return this.#nextUniqueId++ }
static #nextUniqueId = 0
name = 'Ability' name = 'Ability'
castTime = 0 castTime = 0
+5 -1
View File
@@ -1,6 +1,10 @@
export default class Buff { export default class Buff {
id = crypto.randomUUID() id = `ability-${Buff.nextId()}`
static nextId() { return this.#nextUniqueId++ }
static #nextUniqueId = 0
name = 'Buff' name = 'Buff'
duration = 0 duration = 0
#effect = () => {} #effect = () => {}
+5 -1
View File
@@ -6,7 +6,10 @@ import Team from './team.js'
import Buff from './buff.js' import Buff from './buff.js'
export default class Entity { export default class Entity {
id = crypto.randomUUID() id = `entity-${Entity.nextId()}`
static nextId() { return this.#nextUniqueId++ }
static #nextUniqueId = 0
abilities = {} abilities = {}
bbox = new Float32Array(4) bbox = new Float32Array(4)
buffs = [] buffs = []
@@ -36,6 +39,7 @@ export default class Entity {
#noPathfindingUntil = 0 #noPathfindingUntil = 0
#spawnPosition = new Vector2() #spawnPosition = new Vector2()
static collider(x, y, radius) { static collider(x, y, radius) {
return new SAT.Circle(new SAT.Vector(x, y), radius) return new SAT.Circle(new SAT.Vector(x, y), radius)
} }
+2 -2
View File
@@ -11,12 +11,12 @@ export default class Game {
averageTick = 0 averageTick = 0
currentTick = 0 currentTick = 0
entities = [] entities = []
height = 10000 * 1.6 height = 1000
projectiles = [] projectiles = []
secondToSlowestTick = 0 secondToSlowestTick = 0
terrains = [] terrains = []
tickRate = 30 tickRate = 30
width = 10000 * 1.6 width = 1000
#behindMs = 0 #behindMs = 0
#currentTiming = 0 #currentTiming = 0
+8 -98
View File
@@ -1,23 +1,21 @@
import { Vector2 } from 'three' import { Vector2 } from 'three'
import { WebSocketExpress } from 'websocket-express' import { WebSocketExpress } from 'websocket-express'
import Entity from './entity.js'
import express from 'express' import express from 'express'
import Game from './game.js' import Game from './game.js'
import Team from './team.js' import { Dungeon, Ravine } from './level.js'
import Template from './template.js'
import Terrain from './terrain.js'
import Level from './level.js'
const app = new WebSocketExpress() const app = new WebSocketExpress()
const port = 1280 const port = 1280
const game = new Game() const game = new Game()
app.use('/', express.static('public')) app.use(express.urlencoded({ extended: true }))
app.use('/three/', express.static('node_modules/three')) app.use('/three/', express.static('node_modules/three'))
app.use('/@tweenjs/', express.static('node_modules/@tweenjs')) app.use('/@tweenjs/', express.static('node_modules/@tweenjs'))
app.use('/stats.js/', express.static('node_modules/stats.js')) app.use('/stats.js/', express.static('node_modules/stats.js'))
app.use('/', express.static('public'))
app.use('/tools/', express.static('tools')) app.use('/tools/', express.static('tools'))
app.use(express.urlencoded({ extended: true }))
app.ws('/ws', async (req, res) => { app.ws('/ws', async (req, res) => {
const websocket = await res.accept() const websocket = await res.accept()
@@ -30,6 +28,7 @@ app.ws('/ws', async (req, res) => {
}) })
websocket.on('message', (rawData) => { websocket.on('message', (rawData) => {
let delay = 0
const message = JSON.parse(rawData) const message = JSON.parse(rawData)
const entity = message.id != null ? game.entities.find((e) => e.id == message.id) : null const entity = message.id != null ? game.entities.find((e) => e.id == message.id) : null
if (entity == null) { if (entity == null) {
@@ -40,11 +39,6 @@ app.ws('/ws', async (req, res) => {
console.log(message) console.log(message)
} }
let delay = 0
// if(message.id == '1') {
// delay = 45
// }
if (message.action == 'attack') { if (message.action == 'attack') {
setTimeout(() => entity.attackAction(new Vector2(message.x, message.y)), delay) setTimeout(() => entity.attackAction(new Vector2(message.x, message.y)), delay)
} }
@@ -67,95 +61,11 @@ app.ws('/ws', async (req, res) => {
}) })
}) })
function laneScenario() {
const player1 = new Entity(Template.player({
id: '1',
spawnPosition: new Vector2(500, 150),
team: Team.blue,
}))
game.spawnEntity(player1)
player1.attackAction(new Vector2(500, 150))
// const player2 = new Entity(Template.player({
// id: '2',
// spawnPosition: new Vector2(1600, 1800),
// team: Team.red,
// }))
// game.spawnEntity(player2)
// player2.attackAction(new Vector2(1600, 1800))
const gameLogic = function gameLogic() {
const game = this
const midRoute = [
new Vector2(1544, 1572),
new Vector2(2748, 2792),
new Vector2(3628, 3688),
new Vector2(4992, 5000),
new Vector2(6272, 6188),
new Vector2(7252, 7200),
new Vector2(8436, 8408),
].map((p) => p.multiplyScalar(1.6))
const topRoute = [
new Vector2(868, 1740),
new Vector2(856, 3480),
new Vector2(808, 5944),
new Vector2(816, 7256),
new Vector2(976, 7772),
new Vector2(1388, 8384),
new Vector2(1948, 8940),
new Vector2(2392, 9152),
new Vector2(4168, 9196),
new Vector2(6548, 9168),
new Vector2(8288, 9176),
].map((p) => p.multiplyScalar(1.6))
const botRoute = [
new Vector2(1704, 812),
new Vector2(3460, 828),
new Vector2(5804, 768),
new Vector2(7332, 844),
new Vector2(8052, 1100),
new Vector2(8528, 1516),
new Vector2(9080, 2208),
new Vector2(9224, 2620),
new Vector2(9172, 4344),
new Vector2(9136, 6752),
new Vector2(9136, 8248),
].map((p) => p.multiplyScalar(1.6))
if (game.entities.length < 100) {
if ([(0 * game.tickRate), (1 * game.tickRate), (2 * game.tickRate)].includes(game.currentTick % (30 * game.tickRate))) {
game.spawnEntity(new Entity(Template.minion(Team.blue, { ranged: false, route: topRoute })))
game.spawnEntity(new Entity(Template.minion(Team.blue, { ranged: false, route: midRoute })))
game.spawnEntity(new Entity(Template.minion(Team.blue, { ranged: false, route: botRoute })))
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: false, route: topRoute.toReversed() })))
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: false, route: midRoute.toReversed() })))
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: false, route: botRoute.toReversed() })))
}
if ([(3 * game.tickRate), (4 * game.tickRate), (5 * game.tickRate)].includes(game.currentTick % (30 * game.tickRate))) {
game.spawnEntity(new Entity(Template.minion(Team.blue, { ranged: true, route: topRoute })))
game.spawnEntity(new Entity(Template.minion(Team.blue, { ranged: true, route: midRoute })))
game.spawnEntity(new Entity(Template.minion(Team.blue, { ranged: true, route: botRoute })))
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: true, route: topRoute.toReversed() })))
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: true, route: midRoute.toReversed() })))
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: true, route: botRoute.toReversed() })))
}
}
}
game.logic = gameLogic
}
app.listen(port, () => { app.listen(port, () => {
console.log(`Server started! Visit http://localhost:${port}`) console.log(`Server started! Visit http://localhost:${port}`)
Level.terrains.map((points) => new Terrain(points.map((p) => p.multiplyScalar(1.6)))).forEach((terrain) => game.addTerrain(terrain)) // Dungeon.scenario(game)
laneScenario() Ravine.scenario(game)
game.start() game.start()
}) })
+86 -1
View File
@@ -1,6 +1,91 @@
import { Vector2 } from 'three' import { Vector2 } from 'three'
import Team from './team.js'
import Template from './template.js'
import Terrain from './terrain.js'
import Entity from './entity.js'
export class Dungeon {
}
export class Ravine {
static scenario(game) {
game.width = 10000 * 1.6
game.height = 10000 * 1.6
this.terrains.map((points) => new Terrain(points.map((p) => p.multiplyScalar(1.6)))).forEach((terrain) => game.addTerrain(terrain))
game.logic = this.logic.bind(game)
const player1 = new Entity(Template.player({
id: '1',
spawnPosition: new Vector2(500, 150),
team: Team.blue,
}))
game.spawnEntity(player1)
}
static logic() {
const game = this
const midRoute = [
new Vector2(1544, 1572),
new Vector2(2748, 2792),
new Vector2(3628, 3688),
new Vector2(4992, 5000),
new Vector2(6272, 6188),
new Vector2(7252, 7200),
new Vector2(8436, 8408),
].map((p) => p.multiplyScalar(1.6))
const topRoute = [
new Vector2(868, 1740),
new Vector2(856, 3480),
new Vector2(808, 5944),
new Vector2(816, 7256),
new Vector2(976, 7772),
new Vector2(1388, 8384),
new Vector2(1948, 8940),
new Vector2(2392, 9152),
new Vector2(4168, 9196),
new Vector2(6548, 9168),
new Vector2(8288, 9176),
].map((p) => p.multiplyScalar(1.6))
const botRoute = [
new Vector2(1704, 812),
new Vector2(3460, 828),
new Vector2(5804, 768),
new Vector2(7332, 844),
new Vector2(8052, 1100),
new Vector2(8528, 1516),
new Vector2(9080, 2208),
new Vector2(9224, 2620),
new Vector2(9172, 4344),
new Vector2(9136, 6752),
new Vector2(9136, 8248),
].map((p) => p.multiplyScalar(1.6))
if (game.entities.length < 100) {
if ([(0 * game.tickRate), (1 * game.tickRate), (2 * game.tickRate)].includes(game.currentTick % (30 * game.tickRate))) {
game.spawnEntity(new Entity(Template.minion(Team.blue, { ranged: false, route: topRoute })))
game.spawnEntity(new Entity(Template.minion(Team.blue, { ranged: false, route: midRoute })))
game.spawnEntity(new Entity(Template.minion(Team.blue, { ranged: false, route: botRoute })))
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: false, route: topRoute.toReversed() })))
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: false, route: midRoute.toReversed() })))
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: false, route: botRoute.toReversed() })))
}
if ([(3 * game.tickRate), (4 * game.tickRate), (5 * game.tickRate)].includes(game.currentTick % (30 * game.tickRate))) {
game.spawnEntity(new Entity(Template.minion(Team.blue, { ranged: true, route: topRoute })))
game.spawnEntity(new Entity(Template.minion(Team.blue, { ranged: true, route: midRoute })))
game.spawnEntity(new Entity(Template.minion(Team.blue, { ranged: true, route: botRoute })))
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: true, route: topRoute.toReversed() })))
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: true, route: midRoute.toReversed() })))
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: true, route: botRoute.toReversed() })))
}
}
}
export default class Map {
static terrains = [ static terrains = [
// // top base gate west wall // // top base gate west wall
// [ // [
+3 -1
View File
@@ -4,7 +4,9 @@ import SATX from './satx.js'
import Entity from './entity.js' import Entity from './entity.js'
export default class Projectile { export default class Projectile {
id = crypto.randomUUID() id = `projectile-${Projectile.nextId()}`
static nextId() { return this.#nextUniqueId++ }
static #nextUniqueId = 0
bbox = new Float32Array(4) bbox = new Float32Array(4)
height = 50 height = 50
+3 -1
View File
@@ -2,7 +2,9 @@ import { Shape, ShapeUtils, Vector2 } from 'three'
import SAT from 'sat' import SAT from 'sat'
export default class Terrain { export default class Terrain {
id = crypto.randomUUID() id = `terrain-${Terrain.nextId()}`
static nextId() { return this.#nextUniqueId++ }
static #nextUniqueId = 0
bbox = new Float32Array(4) bbox = new Float32Array(4)
position = new Vector2() position = new Vector2()