add a basic terrain layout

This commit is contained in:
2025-01-19 00:59:17 +09:00
parent 0b949683a6
commit 0a4853aff9
6 changed files with 2291 additions and 41 deletions
+1
View File
@@ -333,6 +333,7 @@ export default class Entity {
if (!this.#moving || this.#dest == null) { return false }
// TODO: bounding boxes to early discard a lot of collidables
const collidables = this.collidables()
const fixedDest = SATX.clamp(SATX.fixCollisions(this.#dest, collidables, this.radius), this.game?.width, this.game?.height, this.radius)
+2 -2
View File
@@ -11,12 +11,12 @@ export default class Game {
averageTick = 0
currentTick = 0
entities = []
height = 5000
height = 10000 * 1.6
projectiles = []
secondToSlowestTick = 0
terrains = []
tickRate = 30
width = 5000
width = 10000 * 1.6
#currentTiming = 0
#eventEmitter = new EventEmitter()
+62 -38
View File
@@ -6,6 +6,7 @@ import Game from './game.js'
import Team from './team.js'
import Template from './template.js'
import Terrain from './terrain.js'
import Level from './level.js'
const app = new WebSocketExpress()
const port = 1280
@@ -15,6 +16,7 @@ app.use('/', express.static('public'))
app.use('/three/', express.static('node_modules/three'))
app.use('/@tweenjs/', express.static('node_modules/@tweenjs'))
app.use('/stats.js/', express.static('node_modules/stats.js'))
app.use('/tools/', express.static('tools'))
app.use(express.urlencoded({ extended: true }))
app.ws('/ws', async (req, res) => {
@@ -74,52 +76,73 @@ function laneScenario() {
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(-450, 450)
const midNorthWallPoints = midWallPoints.map((p) => p.clone().add(midNorthWallOffset))
const midNorthWall = new Terrain(midNorthWallPoints)
midNorthWall.id = 'midNorthWall'
game.addTerrain(midNorthWall)
const midSouthWallOffset = new Vector2(50, -50)
const midSouthWallPoints = midWallPoints.map((p) => p.clone().add(midSouthWallOffset))
const midSouthWall = new Terrain(midSouthWallPoints)
midSouthWall.id = 'midSouthWall'
game.addTerrain(midSouthWall)
// 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 blueRoute = [new Vector2(600, 1350), new Vector2(1900, 1900)]
const redRoute = [new Vector2(600, 1350), new Vector2(100, 100)]
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 ([(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 })))
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: blueRoute })))
game.spawnEntity(new Entity(Template.minion(Team.red, { ranged: true, route: redRoute })))
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
@@ -128,6 +151,7 @@ function laneScenario() {
app.listen(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))
laneScenario()
game.start()
+2133
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -9,7 +9,7 @@ export default class Template {
height: options.ranged ? 40 : 38,
logic: this.#minionLogic(options.route),
maxHealth: options.ranged ? 300 : 450,
position: team == Team.blue ? new Vector2(200, 200) : new Vector2(1800, 1800),
position: options.route?.at(0) ?? new Vector2(0, 0),
radius: 48,
speed: 325,
team,