2012-02-08 6 views
2

Box2dを使用して、Parachute Ninja (ZeptoLab)のようなゴム糸(ゴムバンド/伸縮性ロープ)の作成方法は?Box2Dでラバースレッドを作成するには?

enter image description here

-(void) CreateElasticRope { 
//=======Params 
// Position and size 
b2Vec2 lastPos = b2Vec2(4,4); //set position first body 
float widthBody = 0.35; 
float heightBody = 0.1; 
// Body params 
float density = 0.05; 
float restitution = 0.5; 
float friction = 0.5; 
// Distance joint 
float dampingRatio = 0.85; 
float frequencyHz = 10; 
// Rope joint 
float kMaxWidth = 1.1; 
// Bodies 
int countBodyInChain = 10; 
b2Body* prevBody; 
//========Create bodies and joints 
for (int k = 0; k < countBodyInChain; k++) { 
    b2BodyDef bodyDef; 
    if(k==0 || k==countBodyInChain-1) bodyDef.type = b2_staticBody; //first and last bodies are static 
    else bodyDef.type = b2_dynamicBody; 
    bodyDef.position = lastPos; 
    lastPos += b2Vec2(2*widthBody, 0); //modify b2Vect for next body 
    bodyDef.fixedRotation = YES; 
    b2Body* body = world->CreateBody(&bodyDef); 

    b2PolygonShape distBodyBox; 
    distBodyBox.SetAsBox(widthBody, heightBody); 
    b2FixtureDef fixDef; 
    fixDef.density = density; 
    fixDef.restitution = restitution; 
    fixDef.friction = friction; 
    fixDef.shape = &distBodyBox; 
    body->CreateFixture(&fixDef); 

    if(k>0) { 
     //Create distance joint 
     b2DistanceJointDef distJDef; 
     b2Vec2 anchor1 = prevBody->GetWorldCenter(); 
     b2Vec2 anchor2 = body->GetWorldCenter(); 
     distJDef.Initialize(prevBody, body, anchor1, anchor2); 
     distJDef.collideConnected = false; 
     distJDef.dampingRatio = dampingRatio; 
     distJDef.frequencyHz = frequencyHz; 
     world->CreateJoint(&distJDef); 

     //Create rope joint 
     b2RopeJointDef rDef; 
     rDef.maxLength = (body->GetPosition() - prevBody->GetPosition()).Length() * kMaxWidth; 
     rDef.localAnchorA = rDef.localAnchorB = b2Vec2_zero; 
     rDef.bodyA = prevBody; 
     rDef.bodyB = body; 
     world->CreateJoint(&rDef); 

    } //if k>0 

    prevBody = body; 
} //for -loop 
} 

IパラメータdampingRatioとfrequencyHzの異なる値を設定し、距離及びロープジョイントを使用し、その効果ははるかに(長い時間のための私のスレッドは元の状態に来る例であるからです、それほど弾力的ではない)。

+3

いくつかのコードを含めて、コードがどのように間違っているかを説明する必要があります。それ以外の人は、あなたがすでに持っているものの欠陥を指摘するのではなく、完全なチュートリアルを書く必要があります。 – Dennis

答えて

-4

私が見たゲームに加えられた最高の物理的実装は、工学の学位を持つ男によって行われました。彼は、物理学/工学で行う計算をC++に翻訳しました。単純な重力、反動、推力から、偶発的な爆発によって引き起こされる回転速度までのすべて。すべての数学は、アニメーションとは異なるモジュールに分かれていました。

弾性バンドの3つの状況があると考えています。 1)形状の力をかけて伸ばした後 2)バンドの弾性特性 3)形状はバンドにもはや触れておらず、バンドは自重と慣性で緩やかに振動しています

真の物理計算を使うほど、より現実的です現れる。私はあなた自身でそれを簡単にするためにそれをすくい取ることができると確信していますが、人間は本質的に偽物を見て良いです。

+0

「真の物理学」は、評価されたドメインには適用できないことが多いため、ゲームで理解しよう! – CapelliC

+0

もちろん。しかし、Box2dは実際の公式を使用し、このエンジンの助けを借りて物理学を実装することができます。 – Sinba

1

私は非常に彼らがそこに任意の関節を使用している疑いがあります。彼らはたぶん、忍者の現在の位置と2つの柱の真ん中との距離をとって、方向を計算し、衝動を開始するだけです...そして、柱と忍者の間に2本の線を引くだけです。

+0

面白い考え。しかし、ジャンプ忍者のガムは弾力的に振る舞います。 – Sinba

+0

缶詰のアニメーションにすることができます。 – iforce2d

3

力を加えることで、ばねをシミュレートできます。各タイムステップでは、接続されているボディの力を更新します(必要に応じてボディを起動させます)。身体の1つが地面(または静止した身体)である場合、身体だけを地面に動かす必要はありません。

通常のスプリングは、たわみに応じて張力と圧縮力(プルとプッシュ)の両方を適用します。あなたのケースではバンジーを持っているので、圧縮力だけが張力(プル)になることはありません。

これはあなたが必要とする数式さ:

F = K Fは力である* X

、Kはバネ剛性(力/たわみ)であり、xは、偏向です。たわみは、最初の長さと現在の長さ(接続点間の距離)の差として計算されます。 Fの記号は、引っ張っているのか押しているのかを決定します。 Fを計算したら、2つのスプリング接続点を結ぶ線に沿ってそれを適用する必要があります。力のバランスを満足させるには、この力を反対方向に加える必要があります(一方の体が正になり、他方の体が負の力を得ます)。これはニュートン卿がそう言っているからです。ここで

は、あなたは、いくつかのプロパティを持つスプリングオブジェクトを必要とする例(pyBox2Dで動作しますが、あなたは簡単にC++にこれを変換することができます)

です。あなたの春のオブジェクトは、最初の長さ、剛性、body1、body2、接続座標(b1x、b1y、b2x、b2y(ローカル座標))を知る必要があります

あなたの場合は、長さ< spr.initialLength、これがTrueの場合、あなたは何の力も加えません。

  body1 = spr.box2DBody1 
      body2 = spr.box2DBody2 

      pA = body1.GetWorldPoint(b2Vec2(spr.box2Db1x, spr.box2Db1y)) 
      pB = body2.GetWorldPoint(b2Vec2(spr.box2Db2x, spr.box2Db2y)) 
      lenVector = pB - pA 
      length = lenVector.Length() 
      deltaL = length - spr.initialLength 
      force = spr.K * deltaL 
      #normalize the lenVector 
      if length == 0: 
       lenVector = b2Vec2(0.70710678118654757, 0.70710678118654757) 
      else: 
       lenVector = b2Vec2(lenVector.x/length, lenVector.y/length) 
      sprForce = b2Vec2(lenVector.x * force, lenVector.y * force) 
      body1.ApplyForce(sprForce, pA) 
      body2.ApplyForce(-sprForce, pB) 
関連する問題