diff --git a/public/static/js/wingbase/net.js b/public/static/js/wingbase/net.js index 7d6b01c..4dd803a 100644 --- a/public/static/js/wingbase/net.js +++ b/public/static/js/wingbase/net.js @@ -18,7 +18,6 @@ class Net { this.socket.on('update', data => { game.world.update(data); - //console.log('.'); }); this.socket.on('world', data => { diff --git a/public/static/js/wingbase/render/render.js b/public/static/js/wingbase/render/render.js index 802590c..69b3996 100644 --- a/public/static/js/wingbase/render/render.js +++ b/public/static/js/wingbase/render/render.js @@ -31,8 +31,7 @@ class Renderer { if (state == 'connecting' || state == 'disconnected') { pallet.clear(); pallet.fill('#111'); - var str = state == 'connecting' ? 'Connecting' : 'Shit\'s ' + - 'diconnected, yo!'; + var str = state == 'connecting' ? 'Connecting' : 'Disconnected'; pallet.text(str, canvas.width / 2, canvas.height / 2, '#fff', 'FreePixel', 16, 'center', 'middle'); return; diff --git a/public/static/js/wingbase/render/ships.js b/public/static/js/wingbase/render/ships.js index 8b9bb61..104d633 100644 --- a/public/static/js/wingbase/render/ships.js +++ b/public/static/js/wingbase/render/ships.js @@ -16,9 +16,9 @@ Renderer.prototype.renderShip = (pallet, ship) => { pallet.view(x + vx, y + vy, false, pos.r); let ts = ship.size / 2; - for (let i = 0; i < ship.mounts.length; i++) { - if (ship.turrets[i]) { - pallet.image(turr, ship.mounts[i][0] - ts, ship.mounts[i][1] - ts, 0); + for (let i = 0; i < ship.fixtures.length; i++) { + if (ship.fixtures[i]) { + pallet.image(turr, ship.fixtures[i][0] - ts, ship.fixtures[i][1] - ts, 0); } } pallet.image(ship.team == 'a' ? teama : teamb, 0, 0, 0); diff --git a/public/static/js/wingbase/world/asteroid.js b/public/static/js/wingbase/world/asteroid.js index 7f49185..f8a47fa 100644 --- a/public/static/js/wingbase/world/asteroid.js +++ b/public/static/js/wingbase/world/asteroid.js @@ -6,7 +6,7 @@ class Asteroid extends Body { } updateType(data) { - this.debug = data[6]; + this.debug = data.debug; } tick() { diff --git a/public/static/js/wingbase/world/body.js b/public/static/js/wingbase/world/body.js index 7185965..bf2d501 100644 --- a/public/static/js/wingbase/world/body.js +++ b/public/static/js/wingbase/world/body.js @@ -2,17 +2,17 @@ class Body { constructor(data) { - this.x = data.delta[0]; - this.y = data.delta[1]; - this.xvel = data.delta[2]; - this.yvel = data.delta[3]; - this.r = data.delta[4]; - this.rvel = data.delta[5]; - + console.log(data); + this.interface = data.interface; + let s = this.interface.order.length + this.interface.fixtures; + this.interface.size = s; this.id = data.id this.frame = data.frame; + this.fixtures = data.fixtures; this.b2body = false; this.updated = 0; + + game.world.update(data.delta); this.com = { x: 0, @@ -40,15 +40,19 @@ class Body { } update(data) { - this.x = data[0]; - this.y = data[1]; - this.xvel = data[2] - this.yvel = data[3]; - this.r = data[4]; - this.rvel = data[5]; + let values = {}; + Array.from(data).map((v, i) => { + values[this.interface.order[i]] = v + }); + this.x = values.x; + this.y = values.y; + this.xvel = values.xvel; + this.yvel = values.yvel; + this.r = values.r; + this.rvel = values.rvel; this.updated = 10; - this.updateType(data); + this.updateType(values); } updateType() { @@ -56,6 +60,6 @@ class Body { } tick() { - + } } diff --git a/public/static/js/wingbase/world/ship.js b/public/static/js/wingbase/world/ship.js index a3bc7e2..c63dea8 100644 --- a/public/static/js/wingbase/world/ship.js +++ b/public/static/js/wingbase/world/ship.js @@ -1,6 +1,5 @@ class Ship extends Body { constructor(data) { - console.log(data); super(data); this.player = new Player(data.name, data.team, this); this.team = data.team; @@ -8,8 +7,6 @@ class Ship extends Body { this.hull = '01'; this.thrust = {}; this.power = data.power; - this.mounts = data.mounts; - this.turrets = data.turrets; this.size = { 'small': 8, 'medium': 16, @@ -21,10 +18,10 @@ class Ship extends Body { updateType(data) { this.thrust = { - forward: data[6] + forward: data.thrustForward } - this.debug = data[9]; + this.debug = data.debug; } tick() { diff --git a/public/static/js/wingbase/world/turret.js b/public/static/js/wingbase/world/turret.js new file mode 100644 index 0000000..28c0924 --- /dev/null +++ b/public/static/js/wingbase/world/turret.js @@ -0,0 +1,8 @@ +class Turret { + constructor(ship, type, pos) { + this.ship = ship; + this.type = type; + this.pos = pos; + this.traversal = 0; + } +} diff --git a/public/static/js/wingbase/world/world.js b/public/static/js/wingbase/world/world.js index bec6465..fc5dfa4 100644 --- a/public/static/js/wingbase/world/world.js +++ b/public/static/js/wingbase/world/world.js @@ -1,4 +1,4 @@ -var SCALE = 32; +const SCALE = 32; class World { constructor() { @@ -44,16 +44,19 @@ class World { }; update(data) { - for (var id in data) { - if (!this.bodies[id]) { + let array = new Float32Array(data); + let i = 0; + while (i < array.length) { + let id = array[i++]; + let body = this.bodies[id]; + + if (!body) { game.net.send('requestBodyData', id); - continue; + return; } - var body = this.bodies[id]; - body.update(data[id]); - - if (data[id].destroy) delete this.bodies[id]; + body.update(array.slice(i, i + body.interface.size)); + i += body.interface.size; } }; diff --git a/server/game/names.json b/server/game/names.json index c7b1b0c..922c195 100644 --- a/server/game/names.json +++ b/server/game/names.json @@ -76,11 +76,14 @@ "Salal Berry", "Salak", "Satsuma", + "Soursop", "Star Fruit", "Strawberry", "Tamarillo", "Tamarind", - "Ugli Fruit" + "Ugli Fruit", + "Yuzu", + "Ziziphus" ], "adjectives": { "a": [ @@ -159,7 +162,8 @@ "Perfect", "Pitiful", "Paranoid", - "Pink" + "Pink", + "Porous" ], "q": [ "Quivering", @@ -172,7 +176,8 @@ "s": [ "Stupid", "Silly", - "Smart" + "Smart", + "Slimy" ], "t": [ "Terrific", @@ -195,10 +200,12 @@ "Xenophobic" ], "y": [ - "Yellow" + "Yellow", + "Useful" ], "z": [ - "Zany" + "Zany", + "Zealous" ] } } diff --git a/server/game/player.js b/server/game/player.js index e9e54dc..1de71d9 100644 --- a/server/game/player.js +++ b/server/game/player.js @@ -11,7 +11,7 @@ class Player { this.lastAction = Date.now(); this.connection = connection; this.name = this.randomName(); - this.delta = {}; + this.delta = []; this.chatCooldown = 0; } @@ -20,6 +20,10 @@ class Player { this.room.remove(this); } + applyDelta(data) { + this.delta = this.delta.concat(data); + } + updateInputs(data) { this.ship.updateInputs(data); this.lastAction = Date.now(); @@ -49,9 +53,9 @@ class Player { } sendUpdate() { - if (Object.keys(this.delta).length == 0) return; + if (this.delta.length == 0) return; this.connection.send('update', this.delta); - this.delta = {}; + this.delta = []; } tick() { diff --git a/server/game/room/index.js b/server/game/room/index.js index 02cd113..5f160ec 100644 --- a/server/game/room/index.js +++ b/server/game/room/index.js @@ -13,6 +13,14 @@ class Room { this.teamB = new Set(); this.world = new World(this); this.name = (Math.random() * 100000 | 0).toString(36); + this.tps = 60; + + this.idGenerator = (function*() { + let i = 0; + + while (true) + yield i++; + })(); this.gameServer = gameServer; this.io = this.gameServer.net.io; @@ -46,6 +54,10 @@ class Room { this.message('roomLeave', player.name, 'team' + player.team); } + generateId() { + return this.idGenerator.next().value; + } + setTeam(player, team) { this.teamA.delete(player); this.teamB.delete(player); @@ -58,9 +70,9 @@ class Room { player.connection.drop(); } - update(self) { - //if (this.world.tickCount % 100 == 0) - self.players.forEach(player => { + update() { + this.world.tick(); + this.players.forEach(player => { player.sendUpdate(); if (Date.now() - player.lastAction > 10000) { //this.kick(player); @@ -75,7 +87,7 @@ class Room { chat(player, message) { wingbase.log(`${this.name}/${player.name}: ${message}`); - + this.chatCooldown++; this.io.to(this.name).emit('chat', { type: 'player', @@ -104,6 +116,7 @@ class Room { let data = { playerShipId: player.ship.id, bounds: this.world.bounds, + tps: this.tps, bodies: Array.from(this.world.bodies).map(b => b.packFull()) }; @@ -113,7 +126,8 @@ class Room { start() { this.world.populate(); this.world.start(); - this.interval = setInterval(_ => this.update(this), 1 / 60); + let wait = 1 / this.tps * 1000; + this.interval = setInterval(this.update.bind(this), wait); } stop() { diff --git a/server/game/room/world/body/asteroid.js b/server/game/room/world/body/asteroid.js index 01a7cf3..2447199 100644 --- a/server/game/room/world/body/asteroid.js +++ b/server/game/room/world/body/asteroid.js @@ -4,17 +4,19 @@ const Body = require('./body.js'); class Asteroid extends Body { constructor(world, pos, size) { - super(world); - - this.x = pos.x; - this.y = pos.y; + super(world, pos); this.debug = 0; - this.size = size; - this.type = 'asteroid'; + this.size = size; this.frame = this.randomFrame(); + + + this.interface.order.push.apply(this.interface.order, [ + 'debug' + ]); + this.interface.type = 'asteroid'; } randomFrame() { @@ -34,13 +36,8 @@ class Asteroid extends Body { return [this.debug]; } - packFull() { - return { - type: 'asteroid', - id: this.id, - frame: this.frame, - delta: this.packDelta() - } + packTypeFull() { + return {}; } } diff --git a/server/game/room/world/body/body.js b/server/game/room/world/body/body.js index 8467737..264fae4 100644 --- a/server/game/room/world/body/body.js +++ b/server/game/room/world/body/body.js @@ -2,19 +2,37 @@ const uuid = require('uuid'); +const Mount = require('./turret/mount.js'); + const b2Vec2 = require('box2d-html5').b2Vec2; class Body { - constructor(world) { - this.x = 0; - this.y = 0; - this.r = 0; - this.b2body = false; - this.type = 'asteroid'; - this.mounts = []; - this.health = 1; + constructor(world, data) { + data = data || {}; this.world = world; - this.id = uuid.v4().slice(0, 8); + this.id = this.world.room.generateId(); + this.type = 'body'; + this.b2body = false; + + this.mounts = data.mounts || []; + this.health = data.health || 1; + this.mounts = this.mounts.map(m => new Mount(this, m)); + + let fixtures = data.fixtures || []; + this.fixtures = this.mounts.map((m, i) => fixtures[i] || 0); + + this.interface = { + order: [ + 'x', + 'y', + 'xvel', + 'yvel', + 'r', + 'rvel' + ], + type: 'body', + fixtures: this.fixtures.length + }; } destruct() { @@ -23,7 +41,7 @@ class Body { } applyDelta() { - this.world.applyDelta(this.id, this.packDelta()); + this.world.applyDelta(this.packDelta()); } applyForce(x, y, center) { @@ -74,8 +92,13 @@ class Body { let rot = this.b2body.GetAngleRadians(); let rvel = this.b2body.GetAngularVelocity(); - // Simple array to save bandwidth. - return [pos.x, pos.y, vel.x, vel.y, rot, rvel].concat(this.packTypeDelta()); + let values = [this.id, pos.x, pos.y, vel.x, vel.y, rot, rvel]; + values = values.concat(this.packTypeDelta()); + this.mounts.forEach(m => { + values = values.concat(m.packDelta()); + }); + + return values; } packTypeDelta() { @@ -83,11 +106,24 @@ class Body { } packFull() { - return { - type: 'body', + let packet = { + type: this.type, id: this.id, - delta: this.packDelta() + frame: this.frame, + fixtures: this.mounts.map(m => m.packFull()), + delta: this.packDelta(), + interface: this.interface } + + let typePacket = this.packTypeFull(); + for (let i in typePacket) + packet[i] = typePacket[i]; + + return packet; + } + + packTypeFull() { + return {}; } get com() { diff --git a/server/game/room/world/body/projectile/grapple.js b/server/game/room/world/body/projectile/grapple.js index e05ee88..a91d222 100644 --- a/server/game/room/world/body/projectile/grapple.js +++ b/server/game/room/world/body/projectile/grapple.js @@ -5,13 +5,9 @@ const Rope = require('../../copula/rope.js'); class Grapple extends Projectile { constructor(world, pos, source) { - super(world); + // pos.x *= 32, pos.y *= 32, idk why + super(world, pos); - this.x = pos.x * 32; - this.y = pos.y * 32; - this.xvel = pos.xvel; - this.yvel = pos.yvel; - this.r = pos.r; this.xvel += Math.cos(this.r) * 0.25; this.yvel += Math.sin(this.r) * 0.25; @@ -64,14 +60,8 @@ class Grapple extends Projectile { return []; } - packFull() { - return { - type: 'grapple', - id: this.id, - source: this.source.id, - frame: this.frame, - delta: this.packDelta() - }; + packProjectileFull() { + return {}; } } diff --git a/server/game/room/world/body/projectile/missile.js b/server/game/room/world/body/projectile/missile.js index b03ac89..09d7dfa 100644 --- a/server/game/room/world/body/projectile/missile.js +++ b/server/game/room/world/body/projectile/missile.js @@ -51,14 +51,8 @@ class Missile extends Projectile { return []; } - packFull() { - return { - type: 'missile', - id: this.id, - source: this.source.id, - frame: this.frame, - delta: this.packDelta() - }; + packProjectileFull() { + return {}; } } diff --git a/server/game/room/world/body/projectile/projectile.js b/server/game/room/world/body/projectile/projectile.js index 2d6d5ad..12b0500 100644 --- a/server/game/room/world/body/projectile/projectile.js +++ b/server/game/room/world/body/projectile/projectile.js @@ -8,7 +8,21 @@ class Projectile extends Body { } connect() { - + + } + + packTypeDelta() { + return []; + } + + packProjectileFull() { + return {}; + } + + packTypeFull() { + let packet = this.packProjectileFull(); + packet.source = this.source.id; + return packet; } } diff --git a/server/game/room/world/body/ship.js b/server/game/room/world/body/ship.js index 2688dab..b10745f 100644 --- a/server/game/room/world/body/ship.js +++ b/server/game/room/world/body/ship.js @@ -4,13 +4,12 @@ const defaults = require('../traits/defaults.json'); const shipTraits = require('../traits/ships.json'); const Body = require('./body.js'); -const Mount = require('./turret/mount.js'); class Ship extends Body { constructor(world, pos, player, build) { - super(world); - build = build || defaults.spawnShip; + let traits = shipTraits[build.ship]; + super(world, traits, build); // Body data. this.x = pos.x || 0; @@ -23,19 +22,18 @@ class Ship extends Body { this.grapple = false; // Traits. - let traits = shipTraits[this.class]; this.traits = traits; this.frame = traits.frame; this.power = traits.power; this.size = traits.size; - // Mounts - traits.mounts.forEach((data, i) => { - let mount = new Mount(this, data); - this.mounts.push(mount); - }); - - this.turrets = build.turrets || []; + // Delta interface. + this.interface.order.push.apply(this.interface.order, [ + 'thrustForward', + 'thrustLeft', + 'thrustRight' + ]); + this.interface.type = 'ship'; this.thrust = { forward: 0, @@ -56,9 +54,9 @@ class Ship extends Body { release: data[7] }; - this.thrust.forward = this.inputs.forward; - this.thrust.left = this.inputs.left; - this.thrust.right = this.inputs.right; + this.thrust.forward = +this.inputs.forward; + this.thrust.left = +this.inputs.left; + this.thrust.right = +this.inputs.right; if (this.inputs.missile) this.launchMissile(); if (this.inputs.grapple) { @@ -100,22 +98,23 @@ class Ship extends Body { packTypeDelta() { let t = this.thrust; - - return [t.forward, t.left, t.right, this.debug || false]; + return [t.forward, t.left, t.right]; } - packFull() { + getTypeDeltaInterface() { + return [ + 'thrustForward', + 'thrustLeft', + 'thrustRight' + ]; + } + + packTypeFull() { return { - type: 'ship', - id: this.id, team: this.player.team, name: this.player.name, - frame: this.frame, power: this.power, - mounts: this.mounts.map(m => m.packFull()), - turrets: this.turrets.map(t => t.packFull()), - size: this.size, - delta: this.packDelta() + size: this.size }; } } diff --git a/server/game/room/world/body/turret/mount.js b/server/game/room/world/body/turret/mount.js index 27ebf53..b4647e5 100644 --- a/server/game/room/world/body/turret/mount.js +++ b/server/game/room/world/body/turret/mount.js @@ -17,7 +17,9 @@ class Mount { this.traversal = data.traversal ? { cw: data.bounds[0], ccw: data.bounds[1] - } : false; + } : 0; + + this.updateDeltaInterface(); } destruct() { @@ -25,11 +27,20 @@ class Mount { this.fixture.destruct(); } + packDelta() { + return [this.traversal || 0]; + } + + updateDeltaInterface() { + this.deltaInterface = this.fixture ? ['traversal'] : []; + } + packFull() { return { x: this.position.x, - y: this.position.y - } + y: this.position.y, + turret: this.turret ? this.turret.type : 0 + }; } } diff --git a/server/game/room/world/index.js b/server/game/room/world/index.js index cc5c5c0..641764e 100644 --- a/server/game/room/world/index.js +++ b/server/game/room/world/index.js @@ -11,12 +11,12 @@ class World { this.physics = new Physics(); this.spawner = new Spawner(this); this.bodies = new Set(); - this.copulae = new Set(); - this.structures = new Set(); this.asteroids = new Set(); + this.copulae = new Set(); + this.players = new Set(); this.projectiles = new Set(); this.ships = new Map(); - this.players = new Set(); + this.structures = new Set(); this.room = room; this.tps = 0; this.tpsCount = 0; @@ -63,18 +63,18 @@ class World { } addAsteroid(asteroid) { - this.asteroids.add(asteroid); this.addBody(asteroid); } addProjectile(projectile) { - this.projectiles.add(projectile); this.addBody(projectile); projectile.connect(); } addBody(body) { this.bodies.add(body); + if (body.type == 'asteroid') this.asteroids.add(body); + if (body.type == 'structure') this.structures.add(body); this.physics.createBody(body); this.room.broadcast('create', body.packFull()); } @@ -85,8 +85,9 @@ class World { this.room.broadcast('effect', copula.packFull()); } - applyDelta(body, data) { - this.players.forEach(player => player.delta[body] = data); + applyDelta(data) { + data = data.map(v => +(v.toFixed(3))); + this.players.forEach(player => player.applyDelta(data)); } explosion(pos, power) { @@ -126,9 +127,9 @@ class World { removeBody(body) { body.destruct(); this.bodies.delete(body); - this.ships.delete(body); - this.structures.delete(body); this.asteroids.delete(body); + this.structures.delete(body); + this.ships.delete(body); this.projectiles.delete(body); this.room.broadcast('destroy', body.id); } @@ -143,15 +144,15 @@ class World { } start() { - this.interval = setInterval(_ => this.tick(this), 1000 / 60); + } stop() { - clearInterval(this.interval); + } - tick(self) { - self.physics.step(); + tick() { + this.physics.step(); let tickBodies = (set, interval) => { set.forEach(body => { @@ -161,9 +162,9 @@ class World { }); }; - tickBodies(self.ships, 1); - tickBodies(self.asteroids, 4); - tickBodies(self.projectiles, 1); + tickBodies(this.ships, 1); + tickBodies(this.asteroids, 4); + tickBodies(this.projectiles, 1); if (Date.now() - this.tpsStart > 5000) { this.tps = this.tpsCount / 5 | 0; diff --git a/server/game/room/world/spawner.js b/server/game/room/world/spawner.js index 731db72..712143b 100644 --- a/server/game/room/world/spawner.js +++ b/server/game/room/world/spawner.js @@ -30,7 +30,6 @@ class Spawner { yvel: ship.vel.y }; let missile = new Missile(this.world, pos, ship); - this.world.addProjectile(missile); return missile; }