适用于iPhone的Box2d / Cocos2d应用漩涡/漩涡效果 [英] Applying a vortex / whirlpool effect in Box2d / Cocos2d for iPhone

查看:117
本文介绍了适用于iPhone的Box2d / Cocos2d应用漩涡/漩涡效果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用了 Nick Vellios教程使用Box2D对象创建径向重力。我知道 Make an Vortex 在这里,但我不知道如何在我的项目中实现它。

I've used Nick Vellios' tutorial to create radial gravity with a Box2D object. I am aware of Make a Vortex here on SO, but I couldn't figure out how to implement it in my project.

我制作了一个漩涡对象,它是一个以恒定角速度旋转的Box2D circleShape传感器。当其他Box2D对象接触这个涡流对象时,我想让它们以与涡流相同的角速度旋转,逐渐靠近涡流中心。在目前物体被吸引到涡流的中心,但它会直线为涡流的中心,而不是像我想要的慢慢旋转。

I have made a vortex object, which is a Box2D circleShape sensor that rotates with a consistent angular velocity. When other Box2D objects contact this vortex object I want them to rotate around at the same angular velocity as the vortex, gradually getting closer to the vortex's centre. At the moment the object is attracted to the vortex's centre but it will head straight for the centre of the vortex, rather than spinning around it slowly like I want it to. It will also travel in the opposite direction than the vortex as well as with the vortex's rotation.

给定一个漩涡和一个box2D体,我如何设置box2d体

Given a vortex and a box2D body, how can I set the box2d body to rotate with the vortex as it gets 'sucked in'.

我设置旋涡的旋转,当我创建它像这样:

I set the rotation of the vortex when I create it like this:

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

这里是如何应用径向重力,如 Nick Vellios的示例代码

Here is how I'm applying the radial gravity, as per 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给了我足够的信息,我的方式,现在只是调整。这是我现在正在做的,除了上面的代码。发生的是身体获得足够的速度以退出涡流的重力 - 在某个地方,我需要检查速度是否低于这个数字。我有点担心,我没有考虑到目前的物体的质量。

Update I think iForce2d has given me enough info to get on my way, now it's just tweaking. This is what I'm doing at the moment, in addition to the above code. What is happening is the body gains enough velocity to exit the vortex's gravity well - somewhere I'll need to check that the velocity stays below this figure. I'm a little concerned I'm not taking into account the object's mass at the moment.

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() );


推荐答案

听起来你只需要应用另一个力到在身体的当前点的涡流的方向。你可以使用b2Body :: GetLinearVelocityFromWorldPoint在世界上的任何点找到涡流的速度。从Box2D源:

It sounds like you just need to apply another force according to the direction of the vortex at the current point of the body. You can use b2Body::GetLinearVelocityFromWorldPoint to find the velocity of the vortex at any point in the world. From Box2D source:

/// 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

Once you know the velocity you're aiming for, you can calculate how much force is needed to go from the current velocity, to the desired velocity. This might be helpful: http://www.iforce2d.net/b2dtut/constant-speed

该链接中的主题仅讨论一维情况。对于你的情况,它也基本上是一维的,如果你将被吸入的身体的当前速度投影到vortexVelocity向量上:

The topic in that link only discusses a 1-dimensional situation. For your case it is also essentially 1-dimensional, if you project the current velocity of the sucked-in body onto the vortexVelocity vector:

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



现在bodyVelocity和vortexVelocity将在同一个方向,你可以计算应用多大的力。然而,如果你只是施加足够的力量来完全匹配涡流速度,吸入的身体可能会围绕涡旋轨道,而不会真正被吸入。我想你会想要使力比这稍微少一点,并且我将根据重力强度将其缩小,否则被吸入的主体一旦接触到涡流的外边缘将被侧向地甩开。

Now bodyVelocity and vortexVelocity will be in the same direction and you can calculate how much force to apply. However, if you simply apply enough force to match the vortex velocity exactly, the sucked in body will probably go into orbit around the vortex and never actually get sucked in. I think you would want to make the force quite a bit less than that, and I would scale it down according to the gravity strength as well, otherwise the sucked-in body will be flung away sideways as soon as it contacts the outer edge of the vortex. It could take a lot of tweaking to get the effect you want.

编辑:

您应用的力量应基于当前速度(bodyVelocity)和期望速度(vortexVelocity)之间的,即。如果身体已经随着漩涡移动,那么你不需要施加任何力。看看我在上面链接中的使用力子部分中的最后一个代码块。如果你用你的bodyVelocity和vortexVelocity向量的大小替换'vel'和'desiredVel',最后三行几乎可以满足你的需要:

The force you apply should be based on the difference between the current velocity (bodyVelocity) and the desired velocity (vortexVelocity), ie. if the body is already moving with the vortex then you don't need to apply any force. Take a look at the last code block in the sub-section titled 'Using forces' in the link I gave above. The last three lines there do pretty much what you need if you replace 'vel' and 'desiredVel' with the sizes of your bodyVelocity and vortexVelocity vectors:

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'一些百分比,减少'力'一些百分比等。如果你也可以缩小力量,使它在涡流的外缘为零,可能看起来更好。

But remember this would probably put the body into orbit, so somewhere along the way you would want to reduce the size of the force you apply, eg. reduce 'desiredVel' by some percentage, reduce 'force' by some percentage etc. It would probably look better if you could also scale the force down so that it was zero at the outer edge of the vortex.

这篇关于适用于iPhone的Box2d / Cocos2d应用漩涡/漩涡效果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆