improve grappling hook physics and rendering
This commit is contained in:
parent
4753f879e5
commit
663305bd23
11 changed files with 129 additions and 55 deletions
|
@ -36,6 +36,14 @@ class Body {
|
|||
this.b2body.ApplyTorque(f);
|
||||
}
|
||||
|
||||
setRotation(r) {
|
||||
this.b2body.SetAngleRadians(r);
|
||||
}
|
||||
|
||||
setVelocity(x, y) {
|
||||
this.b2body.SetLinearVelocity(new b2Vec2(x, y));
|
||||
}
|
||||
|
||||
contact() {
|
||||
}
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ class Grapple extends Projectile {
|
|||
this.xvel = pos.xvel;
|
||||
this.yvel = pos.yvel;
|
||||
this.r = pos.r;
|
||||
this.xvel += Math.cos(this.r) * 0.4;
|
||||
this.yvel += Math.sin(this.r) * 0.4;
|
||||
this.xvel += Math.cos(this.r) * 0.25;
|
||||
this.yvel += Math.sin(this.r) * 0.25;
|
||||
|
||||
this.welded = false;
|
||||
|
||||
|
@ -22,8 +22,8 @@ class Grapple extends Projectile {
|
|||
|
||||
this.type = 'grapple';
|
||||
this.frame = [
|
||||
[[0, -8], [5, -12], [4, 0], [0, 0]],
|
||||
[[0, 0], [4, 0], [5, 12], [0, 8]]
|
||||
[[0, -8], [5, -12], [2, 0], [0, 0]],
|
||||
[[0, 0], [2, 0], [5, 12], [0, 8]]
|
||||
];
|
||||
}
|
||||
|
||||
|
@ -39,24 +39,25 @@ class Grapple extends Projectile {
|
|||
|
||||
connect() {
|
||||
let p1 = { x: 0, y: 0.5 };
|
||||
let p2 = { x: 4, y: 0 };
|
||||
let p2 = { x: 0.0625, y: 0 };
|
||||
this.rope = new Rope(this.player.ship, this, p1, p2);
|
||||
this.rope.initLength = 6;
|
||||
this.world.addCopula(this.rope);
|
||||
this.rope.length = 5;
|
||||
}
|
||||
|
||||
contact(body, contact) {
|
||||
if (this.welded || body == this.source)
|
||||
return;
|
||||
this.welded = true;
|
||||
let normal = this.world.physics.contactData(contact).normal;
|
||||
let normal = this.world.physics.contactData(contact).worldNormal;
|
||||
let angle = Math.atan2(normal.y, normal.x);
|
||||
this.b2body.SetAngleRadians(angle);
|
||||
this.world.weld(this, body);
|
||||
this.setRotation(angle + Math.PI);
|
||||
this.b2body.SetAngularVelocity(0);
|
||||
this.setVelocity(0, 0);
|
||||
this.world.weld(this, body, { x: 0.15625, y: 0 });
|
||||
this.welded = true;
|
||||
}
|
||||
|
||||
tickType() {
|
||||
|
||||
}
|
||||
|
||||
packTypeDelta() {
|
||||
|
|
|
@ -89,7 +89,7 @@ class Ship extends Body {
|
|||
packTypeDelta() {
|
||||
let t = this.thrust;
|
||||
|
||||
return [t.forward, t.left, t.right];
|
||||
return [t.forward, t.left, t.right, this.debug || false];
|
||||
}
|
||||
|
||||
packFull() {
|
||||
|
|
|
@ -9,11 +9,23 @@ class Rope extends Copula {
|
|||
}
|
||||
|
||||
get length() {
|
||||
return this.b2joint.GetMaxLength();
|
||||
//return this.b2joint.GetMaxLength();
|
||||
return 8;
|
||||
}
|
||||
|
||||
set length(len) {
|
||||
this.b2joint.SetMaxLength(len);
|
||||
//this.b2joint.SetMaxLength(len);
|
||||
}
|
||||
|
||||
packFull() {
|
||||
return {
|
||||
type: 'rope',
|
||||
length: this.length,
|
||||
bodyA: this.bodyA.id,
|
||||
bodyB: this.bodyB.id,
|
||||
posA: this.pointA,
|
||||
posB: this.pointB
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ class World {
|
|||
addCopula(copula) {
|
||||
this.copulae.add(copula);
|
||||
this.physics.createCopula(copula);
|
||||
this.room.broadcast('create', copula.packFull());
|
||||
this.room.broadcast('effect', copula.packFull());
|
||||
}
|
||||
|
||||
applyDelta(body, data) {
|
||||
|
@ -138,8 +138,8 @@ class World {
|
|||
this.room.broadcast('destroy', copula.id);
|
||||
}
|
||||
|
||||
weld(bodyA, bodyB) {
|
||||
this.physics.weld(bodyA, bodyB);
|
||||
weld(bodyA, bodyB, point) {
|
||||
this.physics.weld(bodyA, bodyB, point);
|
||||
}
|
||||
|
||||
start() {
|
||||
|
|
|
@ -21,20 +21,14 @@ class Physics {
|
|||
this.world = new Box2D.b2World(new b2Vec2(0, 0), false);
|
||||
this.toRemove = [];
|
||||
this.toWeld = [];
|
||||
this.contacts = [];
|
||||
this.idk = false;
|
||||
|
||||
let onContact = contact => {
|
||||
let bodya = contact.GetFixtureA().GetBody().GetUserData();
|
||||
let bodyb = contact.GetFixtureB().GetBody().GetUserData();
|
||||
|
||||
if (bodya) {
|
||||
bodya.applyDelta();
|
||||
bodya.contact(bodyb. contact);
|
||||
}
|
||||
|
||||
if (bodyb) {
|
||||
bodyb.applyDelta();
|
||||
bodyb.contact(bodya, contact);
|
||||
}
|
||||
this.contacts.push([bodya, bodyb, contact]);
|
||||
}
|
||||
|
||||
let listener = new Box2D.b2ContactListener();
|
||||
|
@ -58,7 +52,7 @@ class Physics {
|
|||
bodyDef.angularVelocity = body.rvel || 0;
|
||||
bodyDef.bullet = body.type == 'missile';
|
||||
bodyDef.linearDamping = body.type == 'asteroid' ? 0.003 : 0.01;
|
||||
bodyDef.angularDamping = body.type == 'asteroid' ? 0.003 : 0.01;
|
||||
bodyDef.angularDamping = body.type == 'asteroid' ? 0.003 : 0.04;
|
||||
bodyDef.type = body.type == 'structure' ?
|
||||
Box2D.b2BodyType.b2_staticBody : Box2D.b2BodyType.b2_dynamicBody;
|
||||
if (body.player || true) bodyDef.allowSleep = false;
|
||||
|
@ -83,14 +77,18 @@ class Physics {
|
|||
|
||||
// TODO: Make this shorter somehow.
|
||||
createCopula(copula) {
|
||||
let s = SCALE;
|
||||
|
||||
if (copula.type == 'rope') {
|
||||
let b1 = copula.bodyA.b2body;
|
||||
let b2 = copula.bodyB.b2body;
|
||||
let p1 = copula.pointA;
|
||||
let p2 = copula.pointB;
|
||||
let p1 = new b2Vec2(copula.pointA.x, copula.pointA.y);
|
||||
let p2 = new b2Vec2(copula.pointB.x, copula.pointB.y);
|
||||
// See top of file.
|
||||
let start = b1.GetWorldPoint(new b2Vec2(p1.x, p1.y), {});
|
||||
let end = b2.GetWorldPoint(new b2Vec2(p2.x, p2.y), {});
|
||||
let start = b1.GetWorldPoint(p1, {});
|
||||
let end = b2.GetWorldPoint(p2, {});
|
||||
copula.bodyA.debug = p1;
|
||||
//copula.bodyB.debug = end;
|
||||
let dx = start.x - end.x
|
||||
let dy = start.y - end.y;
|
||||
let len = Math.sqrt(dx * dx + dy * dy);
|
||||
|
@ -98,10 +96,10 @@ class Physics {
|
|||
let ropeDef = new Box2D.b2RopeJointDef();
|
||||
ropeDef.bodyA = b1;
|
||||
ropeDef.bodyB = b2;
|
||||
ropeDef.maxLength = len;
|
||||
ropeDef.maxLength = copula.initLength || len;
|
||||
ropeDef.collideConnected = true;
|
||||
ropeDef.worldAnchorA = new b2Vec2(start);
|
||||
ropeDef.worldAnchorB = new b2Vec2(end);
|
||||
ropeDef.localAnchorA = p1;
|
||||
ropeDef.localAnchorB = p2;
|
||||
let b2joint = this.world.CreateJoint(ropeDef);
|
||||
|
||||
copula.b2joint = b2joint;
|
||||
|
@ -109,17 +107,28 @@ class Physics {
|
|||
|
||||
}
|
||||
|
||||
weld(bodyA, bodyB) {
|
||||
this.toWeld.push([bodyA, bodyB]);
|
||||
weld(bodyA, bodyB, point) {
|
||||
let b1 = bodyA.b2body;
|
||||
let b2 = bodyB.b2body;
|
||||
let jointDef = new Box2D.b2WeldJointDef();
|
||||
let anchor = b1.GetWorldPoint(new b2Vec2(point.x, point.y), {});
|
||||
jointDef.bodyA = b1;
|
||||
jointDef.bodyB = b2;
|
||||
jointDef.collideConnected = true;
|
||||
jointDef.localAnchorA = b1.GetLocalPoint(anchor, {});
|
||||
jointDef.localAnchorB = b2.GetLocalPoint(anchor, {});
|
||||
jointDef.localAnchorA = new b2Vec2(jointDef.localAnchorA.x, jointDef.localAnchorA.y);
|
||||
jointDef.localAnchorB = new b2Vec2(jointDef.localAnchorB.x, jointDef.localAnchorB.y);
|
||||
jointDef.referenceAngle = b2.GetAngleRadians() - b1.GetAngleRadians();
|
||||
this.world.CreateJoint(jointDef);
|
||||
}
|
||||
|
||||
contactData(contact) {
|
||||
let worldManifold = new Box2D.b2WorldManifold();
|
||||
contact.GetWorldManifold(worldManifold);
|
||||
let localManifold = new Box2D.b2WorldManifold();
|
||||
contact.GetManifold(localManifold);
|
||||
let localManifold = contact.GetManifold();
|
||||
let worldNormal = worldManifold.normal;
|
||||
let normal = localManifold.normal;
|
||||
let normal = localManifold.localNormal;
|
||||
|
||||
return {
|
||||
normal: normal,
|
||||
|
@ -167,18 +176,25 @@ class Physics {
|
|||
this.world.DestroyBody(this.toRemove[i].b2body);
|
||||
}
|
||||
|
||||
for (var i = 0; i < this.toWeld.length; i++) {
|
||||
let b1 = this.toWeld[i][0].b2body;
|
||||
let b2 = this.toWeld[i][1].b2body;
|
||||
let jointDef = new Box2D.b2WeldJointDef();
|
||||
jointDef.bodyA = b1;
|
||||
jointDef.bodyB = b2;
|
||||
//jointDef.referenceAngle = b1.GetAngleRadians() - b2.GetAngleRadians();
|
||||
this.world.CreateJoint(jointDef);
|
||||
this.toRemove = [];
|
||||
|
||||
for (var i = 0; i < this.contacts.length; i++) {
|
||||
let contact = this.contacts[i][2];
|
||||
let bodya = this.contacts[i][0];
|
||||
let bodyb = this.contacts[i][1];
|
||||
|
||||
if (bodya) {
|
||||
bodya.applyDelta();
|
||||
bodya.contact(bodyb, contact);
|
||||
}
|
||||
|
||||
if (bodyb) {
|
||||
bodyb.applyDelta();
|
||||
bodyb.contact(bodya, contact);
|
||||
}
|
||||
}
|
||||
|
||||
this.toRemove = [];
|
||||
this.toWeld = [];
|
||||
this.contacts = [];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
"power": {
|
||||
"forward": 0.015,
|
||||
"back": 0,
|
||||
"rotation": 0.001
|
||||
"rotation": 0.003
|
||||
},
|
||||
"hull": [
|
||||
[
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue