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