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 {
|
||||
constructor() {
|
||||
|
||||
|
|
|
@ -26,6 +26,10 @@ class Connection {
|
|||
this.player.updateInputs(data);
|
||||
});
|
||||
|
||||
socket.on('test', data => {
|
||||
this.player.room.world.test();
|
||||
});
|
||||
|
||||
this.server.assignRoom(this.player);
|
||||
}
|
||||
|
||||
|
|
|
@ -70,6 +70,13 @@ class Body {
|
|||
packFull() {
|
||||
}
|
||||
|
||||
get com() {
|
||||
return {
|
||||
x: this.b2body.GetLocalCenter().x,
|
||||
y: this.b2body.GetLocalCenter().y
|
||||
}
|
||||
}
|
||||
|
||||
get center() {
|
||||
return {
|
||||
x: this.b2body.GetWorldCenter().x,
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
'use strict';
|
||||
|
||||
class Copula {
|
||||
constructor(b1, b2) {
|
||||
this.b1 = b1;
|
||||
this.b2 = b2;
|
||||
constructor(b1, b2, p1, p2) {
|
||||
this.bodyA = b1;
|
||||
this.bodyB = b2;
|
||||
this.pointA = p1 || b1.com;
|
||||
this.pointB = p2 || b2.com;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,8 +3,19 @@
|
|||
const Copula = require('./copula.js');
|
||||
|
||||
class Rope extends Copula {
|
||||
constructor(p1, p2) {
|
||||
super();
|
||||
constructor(b1, b2) {
|
||||
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);
|
||||
player.ship = 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) {
|
||||
|
@ -100,14 +114,6 @@ class World {
|
|||
};
|
||||
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) {
|
||||
|
|
|
@ -4,6 +4,12 @@
|
|||
// so most changes done to it should be mirrored there to keep consistent
|
||||
// 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 Box2D = require('box2d-html5');
|
||||
|
@ -19,12 +25,16 @@ class Physics {
|
|||
let bodya = contact.GetFixtureA().GetBody().GetUserData();
|
||||
let bodyb = contact.GetFixtureB().GetBody().GetUserData();
|
||||
|
||||
if (bodya) {
|
||||
bodya.applyDelta();
|
||||
bodyb.applyDelta();
|
||||
|
||||
bodya.contact(bodyb);
|
||||
}
|
||||
|
||||
if (bodyb) {
|
||||
bodyb.applyDelta();
|
||||
bodyb.contact(bodya);
|
||||
}
|
||||
}
|
||||
|
||||
let listener = new Box2D.b2ContactListener();
|
||||
listener.BeginContact = onContact;
|
||||
|
@ -66,10 +76,36 @@ class Physics {
|
|||
}
|
||||
|
||||
body.b2body = b2body;
|
||||
|
||||
//if (body.type == 'ship') console.log(b2body.GetLocalCenter());
|
||||
}
|
||||
|
||||
// TODO: Make this shorter somehow.
|
||||
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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -84,7 +120,7 @@ class Physics {
|
|||
};
|
||||
let i = 0;
|
||||
this.world.RayCast((fixture, point, normal, fraction) => {
|
||||
let body = fixture.GetBody().GetUserData();;
|
||||
let body = fixture.GetBody().GetUserData();
|
||||
if (fraction <= closest.fraction) {
|
||||
closest = {
|
||||
body: body,
|
||||
|
@ -102,6 +138,10 @@ class Physics {
|
|||
this.toRemove.push(body);
|
||||
}
|
||||
|
||||
removeCopula(copula) {
|
||||
this.toRemove.push.apply(this.toRemove, copula.bodies);
|
||||
}
|
||||
|
||||
step() {
|
||||
this.world.Step(1, 5, 1 / 60);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue