add client side physics

by god did this take a lot of debugging to get working
This commit is contained in:
Asraelite 2016-03-24 00:13:10 +00:00
parent 65f78ec3ac
commit 1412cabbb4
19 changed files with 697 additions and 71 deletions

View file

@ -16,12 +16,11 @@ function Net() {
this.socket.on('update', function(data) {
game.world.update(data);
window.q = data;
//console.log('.');
});
this.socket.on('world', function(data) {
game.world.clear();
console.log(data);
game.world.playerShipId = data.playerShipId;
for (var i in data.bodies) {
game.world.add(data.bodies[i]);
@ -31,6 +30,10 @@ function Net() {
this.socket.on('create', function(data) {
game.world.add(data);
});
this.socket.on('destroy', function(data) {
game.world.remove(data);
});
};
this.update = function(move) {

View file

@ -5,7 +5,7 @@ function renderAsteroid(pallet, body) {
var vx = -game.world.getCenter().x;
var vy = -game.world.getCenter().y;
pallet.view(x + vx, y + vy, false, body.r);
pallet.view(x + vx, y + vy, false, pos.r);
var context = pallet.context;
var points = body.frame[0];

View file

@ -54,7 +54,7 @@ function Renderer() {
} else if (body.bodyType == 'asteroid') {
renderAsteroid(pallet, body);
} else {
pallet.rect('#338', body.x, body.y, 10, 10);
// Render structures, projectiles etc..
}
}

View file

@ -8,12 +8,12 @@ function renderShip(pallet, ship) {
var turr = game.assets.images.turrets['01'].small;
//pallet.view(ship.x, ship.y, false, ship.r);
var pos = ship.getPos();
var x = pos.x;
var y = pos.y;
var x = pos.x * SCALE;
var y = pos.y * SCALE;
var vx = -game.world.getCenter().x;
var vy = -game.world.getCenter().y;
pallet.view(x + vx, y + vy, false, ship.r);
pallet.view(x + vx, y + vy, false, pos.r);
var ts = ship.size / 2;
for (var i = 0; i < ship.mounts.length; i++) {
@ -27,4 +27,6 @@ function renderShip(pallet, ship) {
pallet.image(ship.move[0] ? thr8 : thr0, 0, 0, 0);
pallet.restore();
//pallet.text(ship.name, x + vx | 0, y + vy | 0, '#fff', 'FreePixel', 16, 'center', 'bottom');
}

View file

@ -1,32 +1,36 @@
function Asteroid(data) {
this.id = data.id;
this.x = data[0];
this.y = data[1];
this.r = data[2];
this.x = data.delta[0];
this.y = data.delta[1];
this.r = data.delta[2];
this.bodyType = 'asteroid';
this.frame = data.frame;
this.updated = false;
var b2Vec2 = Box2D.Common.Math.b2Vec2;
var s = SCALE;
this.getPos = function() {
var pos = this.b2body.GetPosition();
var angle = this.b2body.GetAngle();
return {
x: this.x,
y: this.y
x: pos.x,
y: pos.y,
r: angle
};
}
};
this.update = function(data) {
this.x = data[0];
this.y = data[1];
this.xvel = data[2];
this.xvel = data[2]
this.yvel = data[3];
this.r = data[4];
this.rvel = data[5];
}
this.updated = true;
};
this.tick = function() {
this.x += this.xvel * 10;
this.y += this.yvel * 10;
this.r += this.rvel * 10;
this.xvel *= 0.98;
this.yvel *= 0.98;
}
};
}

View file

@ -0,0 +1,89 @@
function Physics() {
var b2Vec2 = Box2D.Common.Math.b2Vec2;
var b2World = Box2D.Dynamics.b2World;
var b2Body = Box2D.Dynamics.b2Body;
var b2BodyDef = Box2D.Dynamics.b2BodyDef;
var b2Fixture = Box2D.Dynamics.b2Fixture;
var b2FixtureDef = Box2D.Dynamics.b2FixtureDef;
var b2PolygonShape = Box2D.Collision.Shapes.b2PolygonShape;
this.world = new b2World(new b2Vec2(0, 0));
this.toRemove = [];
var b2DebugDraw = Box2D.Dynamics.b2DebugDraw;
var debugDraw = new b2DebugDraw();
debugDraw.SetSprite(document.getElementById("starbugs_canvas").getContext("2d"));
debugDraw.SetDrawScale(SCALE);
debugDraw.SetFillAlpha(0.3);
debugDraw.SetLineThickness(1.0);
debugDraw.SetFlags(b2DebugDraw.e_shapeBit | b2DebugDraw.e_jointBit);
this.world.SetDebugDraw(debugDraw);
this.createBody = function(body) {
var s = SCALE;
var bodyDef = new b2BodyDef();
bodyDef.userData = body;
bodyDef.position = new b2Vec2(body.x || 0, body.y || 0);
bodyDef.fixedRotation = false;
bodyDef.active = true;
bodyDef.linearVelocity = new b2Vec2(0, 0);
bodyDef.angularVelocity = 0;
bodyDef.linearDamping = body.bodyType == 'ship' ? 0.01 : 0.003;
bodyDef.angularDamping = body.bodyType == 'ship' ? 0.01 : 0.003;
bodyDef.type = body.bodyType == 'structure' ?
b2Body.b2_staticBody : b2Body.b2_dynamicBody;
bodyDef.allowSleep = false;
var b2body = this.world.CreateBody(bodyDef);
var fixtureDef = new b2FixtureDef();
fixtureDef.density = 10;
fixtureDef.friction = 1;
fixtureDef.restitution = 1;
for (var i in body.frame) {
var poly = body.frame[i].map(function(vertex) {
return new b2Vec2(vertex[0] / s, vertex[1] / s);
});
fixtureDef.shape = new b2PolygonShape();
fixtureDef.shape.SetAsArray(poly, poly.length);
//console.log(fixtureDef);
b2body.CreateFixture(fixtureDef);
}
body.b2body = b2body;
body.com = b2body.GetLocalCenter();
if (body.bodyType == 'ship') {
console.log(body.getPos());
//console.log(b2body.GetLocalCenter());
//console.log(body);
//console.log(b2body.GetMass());
//console.log(b2body.GetFixtureList().GetShape());
}
}
this.removeBody = function(body) {
this.toRemove.push(body.b2body);
}
this.step = function() {
this.world.Step(1, 5, 1 / 60);
this.world.ClearForces();
//this.world.DrawDebugData();
for (var i in game.world.bodies) {
var s = SCALE;
var body = game.world.bodies[i];
if (!body.updated) continue;
body.b2body.SetPositionAndAngle(new b2Vec2(body.x, body.y), body.r);
body.b2body.SetLinearVelocity(new b2Vec2(body.xvel, body.yvel));
body.b2body.SetAngularVelocity(body.rvel);
body.updated = false;
}
for (var i = 0; i < this.toRemove.length; i++) {
this.world.DestroyBody(this.toRemove[i]);
}
this.toRemove = [];
}
}

View file

@ -1,14 +1,14 @@
function Ship(data) {
this.id = data.id;
this.team = data.team;
this.x = data.delta[0];
this.y = data.delta[1];
this.r = data.delta[4];
this.xvel = data.delta[2];
this.yvel = data.delta[3];
this.rvel = data.delta[5];
this.r = data.delta[2];
this.team = data.team;
this.name = data.name;
this.hull = '01';
this.move = [];
this.thrust = {};
this.power = data.power;
this.mounts = data.mounts;
this.turrets = data.turrets;
this.frame = data.frame;
@ -18,46 +18,71 @@ function Ship(data) {
'large': 24
}[data.size];
this.lastMove = [];
this.b2body = false;
this.bodyType = 'ship';
this.com = {
x: 16,
y: 17.6
x: 0,
y: 0
};
var b2Vec2 = Box2D.Common.Math.b2Vec2;
var s = SCALE;
this.getPos = function() {
var pos = this.b2body.GetPosition();
var angle = this.b2body.GetAngle();
return {
x: this.x * s,
y: this.y * s
x: pos.x,
y: pos.y,
r: angle
}
}
};
this.update = function (data) {
this.x = data[0];
this.y = data[1];
this.xvel = data[2];
this.xvel = data[2]
this.yvel = data[3];
this.r = data[4];
this.rvel = data[5];
if(this != game.world.playerShip) this.move[0] = data[6];
}
this.updated = true;
this.thrust = {
forward: data[6],
left: data[7],
right: data[8]
}
};
this.updateMove = function() {
if (JSON.stringify(this.move) != JSON.stringify(this.lastMove) || true) {
game.net.update(this.move);
this.lastMove = Array.apply(0, this.move); // Bloody Javascript.
}
}
};
this.applyForce = function(x, y) {
var b = this.b2body;
b.ApplyForce(new b2Vec2(x, y), b.GetWorldCenter());
};
this.applyTorque = function(f) {
this.b2body.ApplyTorque(f);
};
this.tick = function() {
this.x += this.xvel * 10;
this.y += this.yvel * 10;
//this.r += this.rvel * 10;
this.xvel *= 0.98;
this.yvel *= 0.98;
if (this.move[0]) {
var power = this.power.forward;
var x = Math.cos(this.getPos().r) * power;
var y = Math.sin(this.getPos().r) * power;
this.applyForce(x, y);
}
if (this.move[1]) this.rvel -= 0.01;
if (this.move[2]) this.rvel += 0.01;
}
if (this.move[1]) {
this.applyTorque(-this.power.rotation);
}
if (this.move[2]) {
this.applyTorque(this.power.rotation);
}
};
}

View file

@ -4,15 +4,20 @@ function World() {
this.bodies = {};
this.playerShip = false;
this.playerShipId = false;
this.physics = new Physics();
var fr = false;
this.getCenter = function() {
if (!this.playerShip) return { x: 0, y: 0 };
var x = this.playerShip.getPos().x;
var y = this.playerShip.getPos().y;
var comx = this.playerShip.com.x;
var comy = this.playerShip.com.y;
var r = this.playerShip.r;
var x = this.playerShip.getPos().x * SCALE;
var y = this.playerShip.getPos().y * SCALE;
var comx = this.playerShip.com.x * SCALE;
var comy = this.playerShip.com.y * SCALE;
comx = 0;
comy = 0;
var r = this.playerShip.getPos().r;
var d = Math.sqrt(comx * comx + comy * comy);
var a = Math.atan2(comy, comx);
@ -28,15 +33,23 @@ function World() {
if (data.type == 'ship') body = new Ship(data);
if (data.type == 'structure') body = new Structure(data);
if(data.type == 'ship') console.log(body);
this.bodies[body.id] = body;
if(data.type == 'ship') console.log(this.bodies);
this.physics.createBody(body);
};
this.remove = function(id) {
console.log(id);
this.physics.removeBody(this.bodies[id]);
delete this.bodies[id];
};
this.clear = function() {
this.bodies = {};
for (var i in this.bodies) {
this.remove(i);
}
this.playerShip = false;
};
@ -57,6 +70,8 @@ function World() {
};
this.tick = function() {
this.physics.step();
for (var i in this.bodies) {
this.bodies[i].tick();
}