add rope support
This commit is contained in:
parent
ccc77490ea
commit
ff0ac094cf
7 changed files with 91 additions and 19 deletions
|
@ -1,3 +1,5 @@
|
||||||
|
// TODO: Find more up-to-date Box2D library with Box2D 2.3 or higher.
|
||||||
|
|
||||||
class Physics {
|
class Physics {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
|
||||||
|
|
|
@ -26,6 +26,10 @@ class Connection {
|
||||||
this.player.updateInputs(data);
|
this.player.updateInputs(data);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
socket.on('test', data => {
|
||||||
|
this.player.room.world.test();
|
||||||
|
});
|
||||||
|
|
||||||
this.server.assignRoom(this.player);
|
this.server.assignRoom(this.player);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,13 @@ class Body {
|
||||||
packFull() {
|
packFull() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get com() {
|
||||||
|
return {
|
||||||
|
x: this.b2body.GetLocalCenter().x,
|
||||||
|
y: this.b2body.GetLocalCenter().y
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
get center() {
|
get center() {
|
||||||
return {
|
return {
|
||||||
x: this.b2body.GetWorldCenter().x,
|
x: this.b2body.GetWorldCenter().x,
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
class Copula {
|
class Copula {
|
||||||
constructor(b1, b2) {
|
constructor(b1, b2, p1, p2) {
|
||||||
this.b1 = b1;
|
this.bodyA = b1;
|
||||||
this.b2 = b2;
|
this.bodyB = b2;
|
||||||
|
this.pointA = p1 || b1.com;
|
||||||
|
this.pointB = p2 || b2.com;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,19 @@
|
||||||
const Copula = require('./copula.js');
|
const Copula = require('./copula.js');
|
||||||
|
|
||||||
class Rope extends Copula {
|
class Rope extends Copula {
|
||||||
constructor(p1, p2) {
|
constructor(b1, b2) {
|
||||||
super();
|
super(b1, b2);
|
||||||
|
this.type = 'rope';
|
||||||
|
this._length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
get length() {
|
||||||
|
return this._length;
|
||||||
|
}
|
||||||
|
|
||||||
|
set length(len) {
|
||||||
|
this.length = len;
|
||||||
|
this.b2joint.SetLength(len);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,6 +41,20 @@ class World {
|
||||||
let ship = new Ship(this, pos, player);
|
let ship = new Ship(this, pos, player);
|
||||||
player.ship = ship;
|
player.ship = ship;
|
||||||
this.addShip(ship);
|
this.addShip(ship);
|
||||||
|
|
||||||
|
//this.test();
|
||||||
|
}
|
||||||
|
|
||||||
|
test() {
|
||||||
|
if (this.players.size == 2) {
|
||||||
|
let b1 = Array.from(this.players)[0].ship;
|
||||||
|
let b2 = Array.from(this.players)[1].ship;
|
||||||
|
|
||||||
|
let copula = new (require('./copula/rope.js'))(b1, b2);
|
||||||
|
if (b1 != b2) {
|
||||||
|
this.physics.createCopula(copula);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
addShip(ship) {
|
addShip(ship) {
|
||||||
|
@ -100,14 +114,6 @@ class World {
|
||||||
};
|
};
|
||||||
this.spawner.spawnAsteroid(pos.x, pos.y,Math.random() * 50 + 10);
|
this.spawner.spawnAsteroid(pos.x, pos.y,Math.random() * 50 + 10);
|
||||||
}
|
}
|
||||||
|
|
||||||
let a1 = Array.from(this.asteroids)[Math.random() * this.asteroids.size];
|
|
||||||
let a2 = Array.from(this.asteroids)[Math.random() * this.asteroids.size];
|
|
||||||
|
|
||||||
let copula = new (require('./copula/copula.js'))(a1, a2);
|
|
||||||
if (a1 != a2) {
|
|
||||||
this.physics.createCopula(copula);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
removePlayer(player) {
|
removePlayer(player) {
|
||||||
|
|
|
@ -4,6 +4,12 @@
|
||||||
// so most changes done to it should be mirrored there to keep consistent
|
// so most changes done to it should be mirrored there to keep consistent
|
||||||
// physics between client and server.
|
// physics between client and server.
|
||||||
|
|
||||||
|
// Note:
|
||||||
|
// b2Body.GetWorldPoint is broken or something and to get it to work, you
|
||||||
|
// must pass an object as the second argument. I don't think it matters what
|
||||||
|
// object but numbers and strings don't work, so do something like
|
||||||
|
// b2body.GetWorldPoint(new b2Vec2(x, y), {});
|
||||||
|
|
||||||
const SCALE = 32;
|
const SCALE = 32;
|
||||||
|
|
||||||
const Box2D = require('box2d-html5');
|
const Box2D = require('box2d-html5');
|
||||||
|
@ -19,11 +25,15 @@ class Physics {
|
||||||
let bodya = contact.GetFixtureA().GetBody().GetUserData();
|
let bodya = contact.GetFixtureA().GetBody().GetUserData();
|
||||||
let bodyb = contact.GetFixtureB().GetBody().GetUserData();
|
let bodyb = contact.GetFixtureB().GetBody().GetUserData();
|
||||||
|
|
||||||
bodya.applyDelta();
|
if (bodya) {
|
||||||
bodyb.applyDelta();
|
bodya.applyDelta();
|
||||||
|
bodya.contact(bodyb);
|
||||||
|
}
|
||||||
|
|
||||||
bodya.contact(bodyb);
|
if (bodyb) {
|
||||||
bodyb.contact(bodya);
|
bodyb.applyDelta();
|
||||||
|
bodyb.contact(bodya);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let listener = new Box2D.b2ContactListener();
|
let listener = new Box2D.b2ContactListener();
|
||||||
|
@ -66,11 +76,37 @@ class Physics {
|
||||||
}
|
}
|
||||||
|
|
||||||
body.b2body = b2body;
|
body.b2body = b2body;
|
||||||
|
|
||||||
//if (body.type == 'ship') console.log(b2body.GetLocalCenter());
|
//if (body.type == 'ship') console.log(b2body.GetLocalCenter());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Make this shorter somehow.
|
||||||
createCopula(copula) {
|
createCopula(copula) {
|
||||||
|
if (copula.type == 'rope') {
|
||||||
|
let b1 = copula.bodyA.b2body;
|
||||||
|
let b2 = copula.bodyB.b2body;
|
||||||
|
let p1 = copula.pointA;
|
||||||
|
let p2 = copula.pointB;
|
||||||
|
// See top of file.
|
||||||
|
let start = b1.GetWorldPoint(b1.GetLocalCenter(), {});
|
||||||
|
let end = b2.GetWorldPoint(new b2Vec2(p2.x, p2.y), {});
|
||||||
|
console.log(start, end);
|
||||||
|
let dx = start.x - end.x
|
||||||
|
let dy = start.y - end.y;
|
||||||
|
let len = Math.sqrt(dx * dx + dy * dy);
|
||||||
|
|
||||||
|
let ropeDef = new Box2D.b2RopeJointDef();
|
||||||
|
ropeDef.bodyA = b1;
|
||||||
|
ropeDef.bodyB = b2;
|
||||||
|
ropeDef.maxLength = len;
|
||||||
|
ropeDef.collideConnected = true;
|
||||||
|
ropeDef.worldAnchorA = new b2Vec2(start);
|
||||||
|
ropeDef.worldAnchorB = new b2Vec2(end);
|
||||||
|
let b2joint = this.world.CreateJoint(ropeDef);
|
||||||
|
|
||||||
|
copula.b2joint = b2joint;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
raycast(start, end) {
|
raycast(start, end) {
|
||||||
|
@ -84,7 +120,7 @@ class Physics {
|
||||||
};
|
};
|
||||||
let i = 0;
|
let i = 0;
|
||||||
this.world.RayCast((fixture, point, normal, fraction) => {
|
this.world.RayCast((fixture, point, normal, fraction) => {
|
||||||
let body = fixture.GetBody().GetUserData();;
|
let body = fixture.GetBody().GetUserData();
|
||||||
if (fraction <= closest.fraction) {
|
if (fraction <= closest.fraction) {
|
||||||
closest = {
|
closest = {
|
||||||
body: body,
|
body: body,
|
||||||
|
@ -102,6 +138,10 @@ class Physics {
|
||||||
this.toRemove.push(body);
|
this.toRemove.push(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeCopula(copula) {
|
||||||
|
this.toRemove.push.apply(this.toRemove, copula.bodies);
|
||||||
|
}
|
||||||
|
|
||||||
step() {
|
step() {
|
||||||
this.world.Step(1, 5, 1 / 60);
|
this.world.Step(1, 5, 1 / 60);
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue