From 1027d980c1a5a2f560033ab1647b67e5272c3273 Mon Sep 17 00:00:00 2001 From: Asraelite Date: Mon, 21 Mar 2016 23:45:27 +0000 Subject: [PATCH] add basic updating to client on physics --- package.json | 3 ++- public/js/starbugs/main.js | 1 + public/js/starbugs/net.js | 4 ++++ public/js/starbugs/render/render.js | 20 +++++++++++++++++++ public/js/starbugs/world/ship.js | 5 +++++ public/js/starbugs/world/world.js | 20 +++++++++++++++++++ server/game/index.js | 7 +++++-- server/game/net/connection.js | 8 ++++++++ server/game/net/index.js | 1 + server/game/player.js | 13 ++++++++++++- server/game/room/index.js | 25 ++++++++++++++++++++++++ server/game/room/world/body.js | 20 ++++++++++++++++++- server/game/room/world/index.js | 30 +++++++++++++++++++++++++---- server/game/room/world/physics.js | 12 ++++++++++-- server/game/room/world/ship.js | 4 ++-- 15 files changed, 160 insertions(+), 13 deletions(-) create mode 100644 public/js/starbugs/world/world.js diff --git a/package.json b/package.json index a285cea..479a02a 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "express": "^4.13.4", "recursive-readdir": "^1.3.0", "socket.io": "^1.4.5", - "uglify-js": "^2.6.2" + "uglify-js": "^2.6.2", + "uuid": "^2.0.1" } } diff --git a/public/js/starbugs/main.js b/public/js/starbugs/main.js index 61d245e..2b7be24 100644 --- a/public/js/starbugs/main.js +++ b/public/js/starbugs/main.js @@ -19,6 +19,7 @@ function Game() { this.state = 'connecting'; this.net = new Net(); + this.world = new World(); this.renderer = new Renderer(); this.tick = function() { diff --git a/public/js/starbugs/net.js b/public/js/starbugs/net.js index dd8e078..d93eb16 100644 --- a/public/js/starbugs/net.js +++ b/public/js/starbugs/net.js @@ -13,5 +13,9 @@ function Net() { game.connected = false; game.state = 'disconnected'; }); + + this.socket.on('update', function(data) { + game.world.update(data); + }); }; } diff --git a/public/js/starbugs/render/render.js b/public/js/starbugs/render/render.js index 39f3812..3c12449 100644 --- a/public/js/starbugs/render/render.js +++ b/public/js/starbugs/render/render.js @@ -17,6 +17,26 @@ function Renderer() { pallet.clear(); pallet.fill('#000'); + + this.renderGrid(); + + for (var id in game.world.bodies) { + var body = game.world.bodies[id]; + + pallet.rect('#338', body.x, body.y, 10, 10); + } + } + + this.renderGrid = function() { + var ox = (game.world.playerShip.x || 0) % 50; + var oy = (game.world.playerShip.y || 0) % 50; + + + for (var x = -50 + ox; x < canvas.width + 50; x += 50) { + for (var y = -50 + oy; y < canvas.height + 50; y += 50) { + pallet.outline('#0a0a0a', x, y, 51, 51, 1); + } + } } pallet.fillScreen(); diff --git a/public/js/starbugs/world/ship.js b/public/js/starbugs/world/ship.js index e69de29..ec56ff5 100644 --- a/public/js/starbugs/world/ship.js +++ b/public/js/starbugs/world/ship.js @@ -0,0 +1,5 @@ +function Ship(id) { + this.id = id; + this.x = 0; + this.y = 0; +} diff --git a/public/js/starbugs/world/world.js b/public/js/starbugs/world/world.js new file mode 100644 index 0000000..ce840ef --- /dev/null +++ b/public/js/starbugs/world/world.js @@ -0,0 +1,20 @@ +function World() { + this.bodies = {}; + this.playerShip = false; + + this.update = function(data) { + for (var id in data) { + if (!this.bodies[id]) { + this.bodies[id] = new Ship(id); + this.playerShip = this.bodies[id]; + } + + var body = this.bodies[id]; + body.x = data[id][0]; + body.y = data[id][1]; + body.r = data[id][2]; + + + } + } +} diff --git a/server/game/index.js b/server/game/index.js index 1e10aab..9fbc065 100644 --- a/server/game/index.js +++ b/server/game/index.js @@ -12,10 +12,13 @@ class GameServer { assignRoom(player) { let room = Array.from(this.rooms.values()).sort((a, b) => { - return a.players - b.players; + return a.playerCount - b.playerCount; })[0]; - if (!room || room.full) room = new Room(); + if (!room || room.full) { + room = new Room(); + this.rooms.set(room.name, room); + } room.add(player); } diff --git a/server/game/net/connection.js b/server/game/net/connection.js index 7e7af72..4fd9ba6 100644 --- a/server/game/net/connection.js +++ b/server/game/net/connection.js @@ -36,6 +36,14 @@ class Connection { }); } + disconnect() { + this.player.disconnect(); + } + + send(msg, data) { + this.io.to(this.socket.id).emit(msg, data); + } + tick() { this.chatCooldown -= 1; } diff --git a/server/game/net/index.js b/server/game/net/index.js index 9cd0235..b5fab9d 100644 --- a/server/game/net/index.js +++ b/server/game/net/index.js @@ -21,6 +21,7 @@ class GameNet { cons.set(id, new Connection(this, socket)); socket.on('disconnect', _ => { + cons.get(id).disconnect(); cons.delete(id); }); }); diff --git a/server/game/player.js b/server/game/player.js index 85db952..61cb936 100644 --- a/server/game/player.js +++ b/server/game/player.js @@ -9,7 +9,18 @@ class Player { this.team = false; this.kickCount = 0; this.connection = connection; - this.name = `Stupid $(fruit[Math.random() * fruit.length | 0])`; + this.name = `Stupid ${fruit[Math.random() * fruit.length | 0]}`; + this.delta = {}; + } + + disconnect() { + this.room.remove(this); + } + + sendUpdate() { + if (Object.keys(this.delta).length == 0) return; + this.connection.send('update', this.delta); + this.delta = {}; } } diff --git a/server/game/room/index.js b/server/game/room/index.js index 8b2d95a..e539dc4 100644 --- a/server/game/room/index.js +++ b/server/game/room/index.js @@ -9,9 +9,12 @@ class Room { this.teamB = new Set(); this.world = new World(); this.name = (Math.random() * 100000 | 0).toString(36); + + this.start(); } add(player) { + console.log(`${player.name} joined ${this.name}.`); player.room = this; player.connection.room = this.name; this.players.add(player); @@ -19,6 +22,14 @@ class Room { this.world.addPlayer(player); } + remove(player) { + console.log(`${player.name} left ${this.name}.`); + this.players.delete(player); + this.teamA.delete(player); + this.teamB.delete(player); + this.world.removePlayer(player); + } + setTeam(player, team) { this.teamA.delete(player); this.teamB.delete(player); @@ -26,6 +37,20 @@ class Room { player.team = team; } + update(self) { + self.players.forEach(player => player.sendUpdate()); + } + + start() { + this.world.start(); + this.interval = setInterval(_ => this.update(this), 1 / 60); + } + + stop() { + this.world.stop(); + clearInterval(this.interval); + } + get playerCount() { return this.players.size; } diff --git a/server/game/room/world/body.js b/server/game/room/world/body.js index a237b9c..b3c193f 100644 --- a/server/game/room/world/body.js +++ b/server/game/room/world/body.js @@ -1,10 +1,28 @@ 'use strict'; +const uuid = require('uuid'); + class Body { - constructor() { + constructor(world) { + this.x = 0; + this.y = 0; + this.r = 0; this.b2body = false; this.type = 'dynamic'; this.health = 1; + this.world = world; + this.id = uuid.v4().slice(0, 8); + } + + applyDelta() { + this.world.applyDelta(this.id, this.pack()); + } + + pack() { + let pos = this.b2body.GetPosition(); + let rot = this.b2body.GetAngleRadians(); + + return [pos.x, pos.y, rot]; } } diff --git a/server/game/room/world/index.js b/server/game/room/world/index.js index d6bf7d6..fde244d 100644 --- a/server/game/room/world/index.js +++ b/server/game/room/world/index.js @@ -15,23 +15,45 @@ class World { addPlayer(player) { this.players.add(player); - let ship = new Ship(player); + let ship = new Ship(this, player); + player.ship = ship; this.ships.set(player, ship); + this.bodies.add(ship); this.physics.createBody(ship); } + applyDelta(body, data) { + this.players.forEach(player => player.delta[body] = data); + } + removePlayer(player) { - removeBody(player.ship); + this.removeBody(player.ship); this.ships.delete(player); this.players.delete(player); } removeBody(body) { - // Remove from Box2d. + this.physics.toRemove.push(body); + this.bodies.delete(body); + this.ships.delete(body); + this.structures.delete(body); + this.asteroids.delete(body); } - tick() { + start() { + this.interval = setInterval(_ => this.tick(this), 1 / 60); + } + stop() { + clearInterval(this.interval); + } + + tick(self) { + self.physics.step(); + + if (Math.random() < 0.001) { + self.bodies.forEach(body => body.applyDelta()); + } } } diff --git a/server/game/room/world/physics.js b/server/game/room/world/physics.js index 7bcf64d..3f1287c 100644 --- a/server/game/room/world/physics.js +++ b/server/game/room/world/physics.js @@ -11,6 +11,7 @@ const b2Vec2 = Box2D.b2Vec2; class Physics { constructor() { this.world = new Box2D.b2World(new b2Vec2(0, 0), false); + this.toRemove = []; } createBody(body) { @@ -19,7 +20,7 @@ class Physics { bodyDef.position = new b2Vec2(body.x || 0, body.y || 0); bodyDef.fixedRotation = false; bodyDef.active = true; - bodyDef.linearVelocity = new b2Vec2(body.xvel || 0, body.yvel || 0); + bodyDef.linearVelocity = new b2Vec2(body.xvel || 0.05, body.yvel || 0); bodyDef.angularVelocity = body.rvel || 0; bodyDef.type = body.type == 'static' ? Box2D.b2Body.b2_staticBody : Box2D.b2Body.b2_dynamicBody; @@ -31,7 +32,7 @@ class Physics { fixtureDef.restitution = 0; for (var poly of body.structure) { - poly.map(vertex => new b2Vec2(vertex[0], vertex[1])); + poly = poly.map(vertex => new b2Vec2(vertex[0], vertex[1])); fixtureDef.shape = new Box2D.b2PolygonShape(); fixtureDef.shape.SetAsArray(poly, poly.length); b2body.CreateFixture(fixtureDef); @@ -42,6 +43,13 @@ class Physics { step() { this.world.Step(1, 5, 1 / 60); + + for (var i = 0; i < this.toRemove.length; i++) { + this.world.DestroyBody(this.toRemove[i].b2body); + console.log(this.world.GetBodyList()); + } + + this.toRemove = []; } } diff --git a/server/game/room/world/ship.js b/server/game/room/world/ship.js index 9ea679c..ce0a2a5 100644 --- a/server/game/room/world/ship.js +++ b/server/game/room/world/ship.js @@ -6,8 +6,8 @@ const hulls = require('./traits/hulls.json'); const Body = require('./body.js'); class Ship extends Body { - constructor(player, build) { - super(); + constructor(world, player, build) { + super(world); this.build = build || defaults.spawnShip.build; this.player = player;