【问题标题】:Applying a vortex / whirlpool effect in Box2d / Cocos2d for iPhone在 Box2d / Cocos2d for iPhone 中应用涡流/漩涡效果
【发布时间】:2012-05-20 05:21:26
【问题描述】:

我使用Nick Vellios' tutorial 使用 Box2D 对象创建径向重力。我在 SO 上知道Make a Vortex,但我不知道如何在我的项目中实现它。

我制作了一个涡流对象,它是一个 Box2D 圆形传感器,它以一致的角速度旋转。当其他 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() );

【问题讨论】:

    标签: objective-c math cocos2d-iphone box2d


    【解决方案1】:

    听起来你只需要根据身体当前点的漩涡方向施加另一个力。您可以使用 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) 之间的差异,即。如果身体已经随着漩涡移动,那么你不需要施加任何力量。看看我上面给出的链接中标题为“使用力量”的小节中的最后一个代码块。如果将 'vel' 和 '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' 降低某个百分比等。如果您还可以按比例缩小力,使其在涡流的外边缘为零,它可能看起来会更好。

    【讨论】:

    • 这看起来是一个很好的答案,今晚我会试一试,让你知道我的进展如何。谢谢!
    • 只是澄清一下 - 我应该这样做而不是我已经在做的事情,而不是除此之外?
    • 谢谢,我想我现在正在路上 - 我想我只需要根据你给我的链接设置一个最大可能的速度,这样物体就不能像它们一样很好地退出重力此刻。如果你看到我做了一些明显愚蠢的事情,请告诉我,否则我会继续玩,并在我弄清楚时将其标记为正确。再次感谢您的帮助。
    【解决方案2】:

    我有一个项目,我有小行星围绕一个中心点旋转(它们之间有东西跳跃......这是一个不同的点)。

    • 它们通过 b2DistanceJoints 连接到“中心”主体。
    • 您可以控制关​​节长度,使它们缓慢地向内(或向外)螺旋。这使您可以找到颗粒控制而不是平衡力控制,这可能很困难。
    • 您还可以应用切向力使它们围绕中心旋转。
    • 通过施加不同的(或随机变化的)切向力,您可以使 相互碰撞等。

    我对这个问题here发布了更完整的答案。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-08
      • 2018-09-01
      • 2012-12-10
      • 1970-01-01
      • 2019-02-03
      相关资源
      最近更新 更多