import { Vector2 } from 'three' import { WebSocketExpress } from 'websocket-express' import Ability from './ability.js' import Entity from './entity.js' import express from 'express' import Game from './game.js' import Team from './team.js' import Template from './template.js' import Terrain from './terrain.js' const app = new WebSocketExpress() const port = 1280 const game = new Game() app.use('/', express.static('public')) app.use('/three/', express.static('node_modules/three')) app.use('/@tweenjs/', express.static('node_modules/@tweenjs')) app.use(express.urlencoded({ extended: true })) app.ws('/ws', async (req, res) => { const websocket = await res.accept() const subscription = () => websocket.send(JSON.stringify(game.state())) game.eventEmitter.on('tick', subscription) websocket.on('close', () => { game.eventEmitter.removeListener('tick', subscription) }) websocket.on('message', (rawData) => { const message = JSON.parse(rawData) const entity = message.id != null ? game.entities.find((e) => e.id == message.id) : null if (entity == null) { console.error({ error: { reason: 'Invalid ID', message } }) return } else { console.log(message) } if (message.action == 'attack') { entity.attackAction(new Vector2(message.x, message.y)) } if (message.action == 'cast') { entity.castAction(message.slot, new Vector2(message.x, message.y)) } if (message.action == 'halt') { entity.haltAction() } if (message.action == 'stop') { entity.stopAction() } if (message.action == 'move') { entity.moveAction(new Vector2(message.x, message.y)) } }) }) 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 midWallStart = new Vector2(600, 600) const midWallEnd = new Vector2(1400, 1400) const midWallMiddle = new Vector2(800, 1200) const midWallThickness = midWallEnd.clone().sub(midWallStart).rotateAround(new Vector2(), -Math.PI / 2).normalize().multiplyScalar(50) const midWallPoints = [ midWallStart, midWallMiddle, midWallEnd, midWallEnd.clone().add(midWallThickness), midWallMiddle.clone().add(midWallThickness), midWallStart.clone().add(midWallThickness), ] const midNorthWallOffset = new Vector2(-400, 400) const midNorthWallPoints = midWallPoints.map((p) => p.clone().add(midNorthWallOffset)) const midNorthWall = new Terrain(midNorthWallPoints) midNorthWall.id = 'midNorthWall' game.addTerrain(midNorthWall) const midSouthWallOffset = new Vector2(0, 0) const midSouthWallPoints = midWallPoints.map((p) => p.clone().add(midSouthWallOffset)) const midSouthWall = new Terrain(midSouthWallPoints) midSouthWall.id = 'midSouthWall' game.addTerrain(midSouthWall) const gameLogic = function gameLogic() { const game = this const blueRoute = [new Vector2(600, 1350), new Vector2(1900, 1900)] const redRoute = [new Vector2(600, 1350), new Vector2(100, 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: blueRoute }))) game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: false, route: redRoute }))) } 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: blueRoute }))) game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: true, route: redRoute }))) } } game.logic = gameLogic // const uBottomPoints = [ // midSouthWallPoints.at(0).clone().sub(midWallThickness), // midSouthWallPoints.at(1).clone().sub(midWallThickness), // midNorthWallPoints.at(-2).clone().add(midWallThickness), // midNorthWallPoints.at(-1).clone().add(midWallThickness), // ] // const uBottom = new Terrain(uBottomPoints) // uBottom.id = 'uBottom' // game.addTerrain(uBottom) } app.listen(port, () => { console.log(`Server started! Visit http://localhost:${port}`) laneScenario() game.start() })