android - LibGDX Box2D 绳索疯狂地拉伸(stretch)

标签 android libgdx box2d revolute-joints

当我使用绳索时,我正在开发一个游戏,它是我在 Box2d 中使用圆和关节创建的。当我用较小的力拖动绳索时,它会按预期工作,而在其他情况下(当力更大时)它会像疯了似的拉伸(stretch),我不知道如何修复它并创造更稳定的绳索。我尝试了不同类型的关节(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);
    }
}

截图:

正常:

enter image description here

拉伸(stretch):

enter image description here

如果你知道如何解决这个问题,请帮助我。

谢谢,查理!

最佳答案

它的发生是因为链的每一部分只在本地解决它的位置约束,也就是说,它只看它的两个最近的邻居。它把那些邻居拉向自己,也把自己移向他们的中心。链条中间的一 block 不关心您将绳索末端连接到的固定点。

唯一可以保证完全固定的方法是将链条的每一段都用绳索接头连接到其他每一段。所以如果你有 n 个物体,你将需要 (n^2+n)/2 个关节。

下一个最好的办法是将链条的每一段都用绳索接头连接到固定端。那将是2n个关节。然而,如果你想拉动绳索,那么你还需要有一个绳索接头来连接玩家可以拾取和拖动的每一段链条。如果你想让玩家选择并拖动到他们喜欢的任何地方,你又回到了 (n^2+n)/2 的情况。

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

如果您的绳索不需要在整个长度上具有物理可碰撞性,那么我建议使用绳索接头连接两端,并使用 verlet 绳索点在两者之间渲染样条曲线或其他东西。

但是从屏幕截图来看,您似乎正试图将绳索卡在可碰撞点上并用张力将其拉到它们周围。我真的不认为您会喜欢尝试使用 Box2D 执行此操作的体验。您需要的是专门为绳索物理设计的定制行为。我不知道那里有任何好的现有源代码,但是您可以从这个视频中得到一些好的想法:https://www.youtube.com/watch?v=Krlf1XnzZGc

关于android - LibGDX Box2D 绳索疯狂地拉伸(stretch),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24814548/

相关文章:

java - 我收到 ArrayIndexOutOfBounds 异常,我不知道为什么。有人可以阐明一下吗?

java - 光线转换未报告碰撞

gradle - 具有惰性包含属性的Gradle zip任务包含其自身

iphone - Box2D 无限循环 (b2World::SolveTOI)

java - SQLite项目中的语法bug,找不到他

android - Git 推送失败 : fatal: unable to access Unknown SSL protocol error in connection to github. com:-9805

android - 如何删除android中不需要的重叠

android - 无法找到可选库

java - Box2D Libgdx黑屏

iphone - 为什么重力比例在 box2d 中不起作用