2011-12-19 24 views
2

我正在試圖通過應用部隊在C++/Objective C上的Box2D中製作螺旋渦。 我想要認識到的是一個旋轉,從一個點,或吸引他們推動身體。 我想我必須應用多個部隊。在這個問題在Box2D中製作一個漩渦

我的切入點是:

我想我需要去申請3種力: - 一種衝動,吸引或從中心擊退身體。 - 使它在螺旋上橫向移動的衝動,但是......怎麼樣? - 如果衝動對我沒有幫助,那麼扭轉身體本身。

+0

我在這裏發現了這個BOX2D漩渦教程:http://www.jungle-troll.com/2011/04/16/box2d-integration/ 。這裏有一個工作渦旋的例子:http://www.okujin.com/games/vortextest.html – 2011-12-19 18:45:21

+0

謝謝,這是一個很好的靈感(我正在考慮傳感器的方式)。但是問題的運動部分沒有解釋,對我來說似乎很棘手。 Flash例子工作得很好,但是......沒有源代碼!謝謝 ! – 2011-12-19 22:51:19

回答

3

我曾經做過一個旋轉平臺,通過製作一個圓形傳感器,該圓形傳感器對圓形矢量場給出的身體進行切向速度變化。我所用的圓形矢量場是這樣的:

V = (y, -x) 

這個矢量場的視覺表示可以在這裏找到: http://kasadkad.files.wordpress.com/2009/09/derham1.png?w=450&h=427

的y和x是身體對的中心的相對位置傳感器,所以你可以做這樣的事情:

Vector getTangentVector(Vector relativePosition, bool invert) 
{ 
    Vector vec; 
    if(invert) //if it's cw or ccw 
    { 
     vec.setY(relativePosition.x()); 
     vec.setX(-relativePosition.y()); 
    } 
    else 
    { 
     vec.setY(-relativePosition.x()); 
     vec.setX(relativePosition.y()); 
    } 
    return vec; 
} 

然後在我的程序的更新方法,我做這樣的事情:

for (b2ContactEdge* ce = platformBody->GetContactList(); ce; ce = ce->next) 
{ 

    b2Contact* c = ce->contact; 

    if(c->IsTouching()) 
    { 
     const b2Body* bodyA = c->GetFixtureA()->GetBody(); 
     const b2Body* bodyB = c->GetFixtureB()->GetBody(); 

     const b2Body* targetBody = (bodyA == platformBody)?bodyB:bodyA; 

     Vector speed = getTangentImpulse(
          getRelativePosition(platformBody, targetBody), 
          true); 


     speed *= CONSTANT; // CONSTANT = 1.8, 
          // this is to account for the targetBody attrition, 
          // so it doesn't slip on the platform 

     Vector currentSpeed; 
     currentSpeed.setX(targetBody->GetLinearVelocity().x); 
     currentSpeed.setY(targetBody->GetLinearVelocity().y); 



     Vector diff = speed - currentSpeed; 
     diff *= 0.01; //should depend on time, but this worked nicely. It makes the 
         //body change its linear velocity to be the same as "speed" at a 
         //0.01 change rate. 

     currentSpeed += diff; 
     targetBody->SetLinearVelocity(
           b2Vec2(currentSpeed.x(), 
           currentSpeed.y())); 

    } 

} 

在這個解決方案中有很多解決方法,例如,我不使用衝動和手動改變速度,它對我更好。另外,我用一個常數來解釋磨損。

它仍然產生了我需要的效果,所以我希望它適合你。對於漩渦,我想你只需要連接一個關節,如鼠標關節,連接到中心並抓住身體。如果只使用關節,就很難使其足夠堅固以抓住身體,但足夠弱以使其繞中心旋轉。與我的代碼一起,通過玩弄常量可能會更容易實現這一點。

我希望這會有所幫助。

編輯:我只記得,與平臺代碼,你也確保旋轉的方向,這是不可能的只有聯合。

+0

非常感謝!你的方法非常有啓發性。到目前爲止,我設法通過施加具有相對於它們與中心點的距離的公式的力來使物體沿着螺旋移動。我想找到的是讓他們以向心方式而不是離心機移動的方式。我將在計算機上發佈代碼(現在在iPhone上)。 – 2011-12-24 07:35:50

+0

我想你可以得到從中心到身體的矢量,對它進行標準化,乘以一些常數,然後將其添加到我的代碼中的速度矢量中,它應該產生你想要的效果。 – 2011-12-24 14:37:19

0

我創建了一系列圍繞中心點旋轉的小行星,方法是對每個小行星使用一個距離關節,然後應用切向力使它們圍繞中心「旋轉」。

您可以用指向渦旋中心的實際力來替換距離接頭。你也可以慢慢減少距離關節的距離,使物品「螺旋狀」進入。我將與此一起去,因爲它可以讓你更好地控制物品進入漩渦的速度。

我叫「myBodyA」是漩渦中心的身體。

從Box2D的手冊:

b2DistanceJointDef jointDef; 
jointDef.Initialize(myBodyA, myBodyB, worldAnchorOnBodyA, worldAnchorOnBodyB); jointDef.collideConnected = true; 
world->CreateJoint(&jointDef); 

你將需要用些力,你的身體(讓我們說這是myBodyB)得到它在朝着正確的方向,因此各地myBodyA旋轉。這將需要一些數學。

你想要做的是計算垂直於從myBodyB指向myBodyA的矢量的矢量。你可以通過從myBodyB到myBodyA的矢量找到它,對它進行標準化,取其斜度(通過PI/2旋轉),然後用它作爲力的方向。例如:

// Calculate Tangent Vector 
b2Vec2 radius = myBodyB.GetPosition()-myBodyA.GetPosition(); 
b2Vec2 tangent = radius.Skew(); 
tangent.Normalize(); 

// Apply some force along tangent 
myBodyB.ApplyForceToCenter(body->GetMass()*acceleration*vTangent); 

如果您正確閱讀此內容,您可以看到F = m * a * tangentVector;也就是說,你正在朝切線方向施加力。我相信它會順時針旋轉(如果我做了數學計算)。無論如何,對這支部隊的負面影響將會朝相反的方向發展。

要停止身體旋轉,可以使用SetLinearDamping(dampingValue)。所以只要你施加力量,它會繼續旋轉。如果你停止施加力量,它應該輕輕停下。您可以通過加速度值和dampingValue參數來控制加速/減速。

如果你真的想在速度控制好,我相信你能做到這一點鉗制速度:

b2Vec2 linVel = myBodyB.GetLinearVelocity(); 
linVel.Normalize(); 
linVel *= maxSpeed; 
myBodyB.SetLinearVelocity(linVel); 

對您有幫助?