当我使用绳索时,我正在开发一个游戏,该游戏是我在Box2d中使用圆和关节创建的。绳索在我用低力拖动时会按预期工作,而在其他情况下(当力更大时),绳索会像疯了似的伸展,我不知道如何解决它并制造出更稳定的绳索。我尝试了不同类型的关节(RopeJoint,RevoluteJoint,DistanceJoint等),但是它没有用。
这是我的代码:

public class RopeItem {

public Body body;
private com.badlogic.gdx.graphics.g2d.Sprite bodySprite;
float width, length;
public CircleShape shape;
public RopeItem(World world, float width, float height, BodyType bodyType, Vector2 position) {
    super();

    //init body
    BodyDef bodyDef = new BodyDef();
    bodyDef.type = bodyType;
    bodyDef.position.set(position);
    this.body = world.createBody(bodyDef);
    //init shape
    FixtureDef fixtureDef = new FixtureDef();
    fixtureDef.density = 0.1f;
    fixtureDef.friction = 0.4f;
    fixtureDef.restitution  = 0.2f;
    shape = new CircleShape();
    shape.setRadius(width / 2);
    fixtureDef.shape = shape;
    fixtureDef.filter.categoryBits = 0x0001;
    fixtureDef.filter.maskBits = 0x0002;

    this.body.createFixture(fixtureDef);
    shape.dispose();

    //create a body sprite
    bodySprite = new com.badlogic.gdx.graphics.g2d.Sprite(new TextureRegion(new Texture("data/rope_circle.png")));
    bodySprite.setSize(width, height);
    bodySprite.setOrigin(width/2, height/2);
    body.setUserData(bodySprite);

}


}

public void createRope(int length) {
    RevoluteJoint[] joints = new RevoluteJoint[length - 1];
    RopeJoint[] ropeJoints = new RopeJoint[length - 1];
    float width = 0.23f, height = 0.23f;
    for(int i=0; i<length; i++) {
        ropeSegmenets.add(new RopeItem(world, width, height, BodyType.DynamicBody, new Vector2(0.3f, 0)));
    }

    RevoluteJointDef jointDef = new RevoluteJointDef();
    jointDef.localAnchorA.x = -height / 2;
    jointDef.localAnchorB.x = height / 2;

    RopeJointDef ropeJointDef = new RopeJointDef();
    ropeJointDef.localAnchorA.set(0, -height / 2);
    ropeJointDef.localAnchorB.set(0, height / 2);
    ropeJointDef.maxLength = length;

    for(int i = 0; i < length-1; i++) {
        jointDef.bodyA = ropeSegmenets.get(i).body;
        jointDef.bodyB = ropeSegmenets.get(i + 1).body;
        joints[i] = (RevoluteJoint) world.createJoint(jointDef);

        ropeJointDef.bodyA = ropeSegmenets.get(i).body;
        ropeJointDef.bodyB = ropeSegmenets.get(i+1).body;
        ropeJoints[i] = (RopeJoint) world.createJoint(ropeJointDef);
    }
}


屏幕截图:

正常:



拉伸:



如果您知道如何解决此问题,请帮助我。

谢谢,查理!

最佳答案

之所以会发生这种情况,是因为链的每个部分都只能在本地解决其位置约束,也就是说,它仅查看其两个最近的邻居。它把那些邻居拉向自己,也向自己的中心移动。链条中间的一块与您将绳索的末端固定到的固定点无关。

完全固定的唯一保证方法是用绳索接头将链条的每一部分相互连接。因此,如果您有n个身体,则需要(n ^ 2 + n)/ 2个关节。

第二个最好的办法是使每个链条都通过一个绳索接头连接到固定端。那将是2n个关节。但是,如果您要拉动绳索,那么还需要有一个绳索接头来连接玩家可以拾取和拖动的链条的每一块。如果您想让播放器在他们喜欢的任何地方进行拾取和拖动,您将再次回到(n ^ 2 + n)/ 2的情况。

您也许可以部分地做到这一点,例如。沿线均匀分布一些额外的绳节,以仅将某些点连接到链的末端。

如果您的绳索在整个长度上不需要物理上可碰撞的存在,那么我建议您使用绳索接头连接两端,并使用垂直的绳索点在两者之间绘制花键或类似的东西。

但是,从屏幕截图中,您似乎正在尝试将绳索悬挂在可碰撞的点上,并用力将其拉动。我真的不认为您会喜欢尝试使用Box2D进行操作的经验。为此,您需要的是专门为绳索物理设计的自定义行为。我不知道有什么不错的现有源代码,但是您可以从此视频中获得一些好主意:https://www.youtube.com/watch?v=Krlf1XnzZGc

10-07 20:40