1

円とジョイントを使用して 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);
    }
}

スクリーンショット:

普通:

ここに画像の説明を入力

伸ばした:

ここに画像の説明を入力

この問題を解決する方法を知っている場合は、助けてください。

ありがとう、チャーリー!

4

1 に答える 1

1

これは、チェーンの各部分がその位置の制約をローカルで解決するだけであるために発生します。それはそれらの隣人をそれ自体に引き寄せ、またそれらの中心に向かって移動します。チェーンの真ん中のピースは、ロープの端を取り付けた固定点を気にしません。

それを完全に修正する唯一の保証された方法は、チェーンのすべての部分をロープジョイントで他のすべての部分に接続することです. したがって、n 個のボディがある場合、(n^2+n)/2 個のジョイントが必要になります。

次善の策は、チェーンのすべての部分を固定端にロープ ジョイントで接続することです。それは2nジョイントになります。ただし、ロープを引っ張る場合は、プレイヤーが選択してドラッグできるチェーンのすべての部分を接続するためのロープ ジョイントも必要です。プレーヤーが好きな場所にピック アンド ドラッグできるようにしたい場合は、(n^2+n)/2 のケースに戻ります。

たとえば、部分的にそれを行うことができる場合があります。いくつかの余分なロープ ジョイントを線に沿って均等に広げて、チェーンの端にいくつかの点だけを接続します。

ロープが全長にわたって物理的に衝突する必要がない場合は、ロープ ジョイントを使用して 2 つの端を接続し、ベルレット ロープ ポイントを使用してその間にスプラインまたは何かをレンダリングすることをお勧めします。

しかし、スクリーンショットからは、衝突する可能性のあるポイントにロープを掛けて、張力をかけて引っ張ろうとしているように見えます。Box2D でこれを実行しようとする経験を楽しめるとは思えませんそのために必要なのは、ロープの物理学のために特別に設計されたカスタムメイドの動作です。既存の優れたソース コードは知りませんが、次のビデオから良いアイデアを得ることができます: https://www.youtube.com/watch?v=Krlf1XnzZGc

于 2014-07-18T10:54:06.257 に答える