在运行时创建关节时,对象会传送 [英] When creating a joint during runtime, object teleports

查看:79
本文介绍了在运行时创建关节时,对象会传送的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有两个对象,当它们之间的距离小于10时,我创建了一个关节:

I have two objects and when the distance between them is less than 10, I create a joint:

var joint_def = new box2d.b2RevoluteJointDef();
joint_def.bodyA = body1;
joint_def.bodyB = body2;
joint_def.localAnchorA = new box2d.b2Vec2(0, 0);
joint_def.localAnchorB = new box2d.b2Vec2(0, 0);
world.CreateJoint(joint_def);

但是,问题是,一个物体在另一个物体上传送/跳跃.预期的行为是一个物体在另一个物体上缓慢移动.

The problem is, however, that one object teleports/jumps on top of the other. The intended behavior would be that one object slowly moves on top of the other.

有什么主意吗?谢谢.

推荐答案

我相信您有两个问题:

问题1: localAnchorA和localAnchorB是您希望关节位于的点.这将是世界空间中映射到各个实体的局部坐标系中的点.您可以手动执行此操作,也可以使用joint_def上的函数执行此操作(至少这是它在c ++中的工作方式):

Problem #1: The localAnchorA and localAnchorB are the point that you want the joint to be at. This would be the point in world space mapped into the local coordinate system of the respective bodies. You can do this manually, or you can do this with a function on the joint_def (at least that is the way it works in c++):

自动:

b2RevoluteJointDef jointDef;
b2Vec2 anchor = _body->GetWorldCenter();
jointDef.Initialize(_body, otherBody, anchor);
jointDef.collideConnected = true;
_world->CreateJoint(&jointDef);

手动:

   b2RevoluteJointDef jointDef;
   b2Vec2 anchor = _body->GetWorldCenter();
   jointDef.bodyA = _body;
   jointDef.bodyB = otherBody;
   jointDef.localAnchorA = _body->GetLocalPoint(anchor);
   jointDef.localAnchorB = otherBody->GetLocalPoint(anchor);
   jointDef.referenceAngle = otherBody->GetAngle() - _body->GetAngle();
   _world->CreateJoint(&jointDef);

您正在使用b2Vec2(0,0)初始化锚点(两个锚点). 我将使用此代码库来演示不同之处:

You are initializing the anchor points (both of them) with b2Vec2(0,0). I'm going to use this code base to demonstrate what the difference looks like:

当您在每个实体的局部空间中定义了两个锚点时:

When you have both anchor points defined in the local space of each body:

请注意,"T"正在旋转,但另一个物体未移动.但是关节使它们彼此之间保持旋转距离.

Note that the "T" is rotating but the other body is not moving. But the joint is keeping them at a rotated distance from each other.

如果两个本地锚点都设置为(0,0):

If you have both the local anchor points set to (0,0):

通常,如果您具有Initialize(...)方法,请使用它来创建关节.

In general, if you have the Initialize(...) method, use it to create the joint.

问题2: 如果从相距10m的物体开始,然后在此处创建旋转关节,则它们将停留在该位置.如果您希望他们开始互相帮助...我认为最简单的方法(而且我已经做到了... 参见此处)是在两者之间连接一个绳索接头,然后,每次物理循环的更新",都要做类似的事情(知道绳索接头是第一个和仅与身体相连的关节):

Problem #2: If you start out with the bodies 10m apart and that is where you create your revolute joint, that is where they will stay. If you want them to start moving towards each other...I think the easiest way to do this (and I have done it...see here) is to attach a rope joint between the two and then, every "update" of the physics loop, do something like this (knowing that the rope joint is the first and only joint connected to the body):

  b2JointEdge* jointEdge = GetBody()->GetJointList();
  b2RopeJoint* rope = (b2RopeJoint*)jointEdge->joint;
  rope->SetMaxLength(rope->GetMaxLength()-_ropeClimbDistPerUpdate);

当绳索长度小于某个公差时,请连接旋转接头.使蜘蛛从小行星中摇摆很有效...

When the rope length gets less than some tolerance, connect your revolute joint. It works pretty good to make spiders swing from asteroids...

注意,您也可以使用b2DistanceJoint代替b2RopeJoint.绳索关节约束最大距离,而距离关节约束固定距离.对于这种情况,应该大致相同.绳索接头可能不在其他box2d端口中.

NOTE You can also use a b2DistanceJoint instead of a b2RopeJoint. The rope joint constrains the maximum distance while the distance joint constrains the fixed distance. For this situation, it should work out about the same. The rope joint may not be present in other box2d ports.

这是您需要的吗?

这篇关于在运行时创建关节时,对象会传送的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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