2012-05-20 94 views
1

我使用Nick Vellios' tutorial來創建具有Box2D對象的徑向引力。我知道這裏的Make a Vortex,但我無法弄清楚如何在我的項目中實現它。在iPhone2的Box2d/Cocos2d中應用旋渦/漩渦效果

我製作了一個渦旋物體,它是一個以一致的角速度旋轉的Box2D circleShape傳感器。當其他Box2D物體接觸到這個渦旋物體時,我希望它們以與渦旋相同的角速度旋轉,逐漸靠近渦旋的中心。此時物體被渦旋中心吸引,但它將直接前往渦流中心,而不是像我想要的那樣緩慢旋轉。它也會沿着與旋渦相反的方向以及旋渦的旋轉方向行進。

鑑於漩渦和box2D的身體,我怎樣才能設置box2d的身體隨渦流旋轉,因爲它被'吸入'。

我設置了旋渦的旋轉,當我創建這樣的:

b2BodyDef bodyDef; 
bodyDef.type = b2_dynamicBody; 
bodyDef.angle = 2.0f; 
bodyDef.angularVelocity = 2.0f; 

這裏是我如何應用徑向重力,按Nick Vellios' sample code

-(void)applyVortexForcesOnSprite:(CCSpriteSubclass*)sprite spriteBody:(b2Body*)spriteBody withVortex:(Vortex*)vortex VortexBody:(b2Body*)vortexBody vortexCircleShape:(b2CircleShape*)vortexCircleShape{ 

    //From RadialGravity.xcodeproj 
    b2Body* ground = vortexBody; 
    b2CircleShape* circle = vortexCircleShape; 
    // Get position of our "Planet" - Nick 
    b2Vec2 center = ground->GetWorldPoint(circle->m_p); 
    // Get position of our current body in the iteration - Nick 
    b2Vec2 position = spriteBody->GetPosition(); 
    // Get the distance between the two objects. - Nick 
    b2Vec2 d = center - position; 
    // The further away the objects are, the weaker the gravitational force is - Nick 
    float force = 1/d.LengthSquared(); // 150 can be changed to adjust the amount of force - Nick 
    d.Normalize(); 
    b2Vec2 F = force * d; 
    // Finally apply a force on the body in the direction of the "Planet" - Nick 
    spriteBody->ApplyForce(F, position); 
    //end radialGravity.xcodeproj 


} 

更新我覺得iForce2d給了我足夠的信息讓我的路,現在它只是調整。除了上面的代碼之外,這是我目前正在做的事情。正在發生的事情是身體獲得足夠的速度以便很好地離開漩渦的重力 - 在某處我需要檢查速度是否低於這個數字。我有點擔心,我目前沒有考慮到物體的質量。

b2Vec2 vortexVelocity = vortexBody->GetLinearVelocityFromWorldPoint(spriteBody->GetPosition()); 

b2Vec2 vortexVelNormal = vortexVelocity; 
vortexVelNormal.Normalize(); 
b2Vec2 bodyVelocity = b2Dot(vortexVelNormal, spriteBody->GetLinearVelocity()) * vortexVelNormal; 

//Using a force 
b2Vec2 vel = bodyVelocity; 
float forceCircleX = .6 * bodyVelocity.x; 
float forceCircleY = .6 * bodyVelocity.y; 

spriteBody->ApplyForce(b2Vec2(forceCircleX,forceCircleY), spriteBody->GetWorldCenter()); 

回答

2

這聽起來像你只是需要施加另一個力量根據漩渦的方向在身體的當前點。您可以使用b2Body :: GetLinearVelocityFromWorldPoint來查找世界上任何點的漩渦速度。從Box2D的來源:

/// Get the world linear velocity of a world point attached to this body. 
/// @param a point in world coordinates. 
/// @return the world velocity of a point. 
b2Vec2 GetLinearVelocityFromWorldPoint(const b2Vec2& worldPoint) const; 

因此,這將是:

b2Vec2 vortexVelocity = vortexBody->GetLinearVelocityFromWorldPoint(suckedInBody->GetPosition()); 

一旦你知道你的目標的速度,你可以計算出多少力,需要從目前的速度走,所需的速度。這可能會有幫助:http://www.iforce2d.net/b2dtut/constant-speed

該鏈接中的主題僅討論一維情況。對於你的情況下,它也基本上是一維的,如果你的項目的當前速度被吸入的身體到vortexVelocity向量:

b2Vec2 vortexVelNormal = vortexVelocity; 
vortexVelNormal.Normalize(); 
b2Vec2 bodyVelocity = b2Dot(vortexVelNormal, suckedInBody->GetLinearVelocity()) * vortexVelNormal; 

現在bodyVelocity和vortexVelocity將在同一個方向,你可以計算出適用的力量很大。然而,如果你只是施加足夠的力量來精確匹配渦旋速度,那麼被吸入的體內可能會進入渦旋軌道,並且從來沒有真正被吸入。我想你會想讓這個力量比這少一點,並且我會根據重力強度將其縮小,否則吸入的物體一接觸渦流的外邊緣就會被側向拋出。它可能需要很多調整來獲得你想要的效果。

編輯:

應用的力,應根據當前速度(bodyVelocity)和所需的速度(vortexVelocity)之間,即在差異。如果身體已經與漩渦一起移動,那麼你不需要施加任何力量。看看上面給出的鏈接中標題爲「使用力量」的小節中的最後一個代碼塊。最後三行有做很多,如果你更換「韋爾」和「desiredVel」你bodyVelocity的大小和vortexVelocity向量你需要什麼:

float desiredVel = vortexVelocity.Length(); 
float currentVel = bodyVelocity.Length(); 
float velChange = desiredVel - currentVel; 
float force = body->GetMass() * velChange/(1/60.0); //for a 1/60 sec timestep 
body->ApplyForce(b2Vec2(force,0), body->GetWorldCenter()); 

但請記住,這將可能把身體送入軌道,所以在某個程度上你會想要減小你施加的力量的大小,例如。將'desiredVel'降低一定的百分比,將'force'降低一定的百分比等等。如果你也可以縮小這個力,使其在渦旋的外緣爲零,那麼它可能會更好看。

+0

這看起來像一個很好的答案,今晚我會告訴你一個好消息,讓你知道我如何繼續。謝謝! – glenstorey

+0

只是爲了澄清 - 我應該這樣做,而不是我已經在做什麼,而不是除了它之外? – glenstorey

+0

另外。你有什麼好看的。 – iforce2d

0

我有一個項目,我有一個小行星圍繞中心點旋轉(有東西在它們之間跳躍......這是一個不同點)。

  • 它們通過b2DistanceJoints連接到「中心」主體。
  • 您可以控制關​​節長度,使其慢慢向內(或向外)旋轉。這可以讓你找到糧食控制,而不是平衡力量控制,這可能是困難的。
  • 你也可以使用切向力使它們繞着中心。
  • 通過應用不同的(或隨機變化)的切向力,可以使 撞上對方,等

我發佈一個更完整的回答了這個問題here