2014-07-17 5 views
1

로프를 사용할 때 원과 조인트를 사용하여 Box2d에서 만든 게임을 개발 중입니다. 밧줄은 낮은 힘으로 드래그 할 때 예상대로 작동하고, 다른 경우에는 (힘이 더 클 때) 미친 듯이 늘어납니다. 나는 그것을 고정하고보다 안정된 로프를 만드는 방법을 모릅니다. 나는 여러 종류의 관절 (RopeJoint, RevoluteJoint, DistanceJoint 등)을 시도했지만 쓸모가 없습니다.미친 듯이 늘어나는 LibGDX Box2D 로프

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

:

다음은 내 코드입니다3210

enter image description here

이 문제를 해결하는 방법을 알고 있다면 도와주세요.

감사합니다. Charlie!

답변

1

체인의 각 부분은 로컬에서 위치 제약 조건 만 해결하기 때문에 발생합니다. 즉, 가장 인접한 두 개의 이웃을 찾습니다. 이웃을 그쪽으로 끌어 당기고 또한 그 중심으로 움직입니다. 체인의 중간에있는 조각은 로프 끝 부분에 부착 한 고정 점을 신경 쓰지 않습니다.

완벽하게 해결하는 유일한 방법은 체인의 모든 부분을 로프 조인트로 다른 모든 부분에 연결하는 것입니다. 따라서 몸이 n 개인 경우 (n^2 + n)/2 개의 관절이 필요합니다.

다음으로 가장 좋은 것은 로프 조인트로 고정 끝단에 체인의 모든 부분을 연결하는 것입니다. 그것은 2n 개의 관절이 될 것입니다. 그러나 밧줄을 당기고 싶다면 플레이어가 선택할 수있는 모든 밧줄을 연결하는 로프 조인트가 필요합니다. 플레이어가 원하는 위치로 드래그하도록하려면 다시 (n^2 + n)/2로 돌아갑니다.

부분적으로 할 수 있습니다. 라인의 일부 끝 부분을 체인의 끝에 연결하기 위해 라인을 따라 고르게 밧줄 조인트를 고르게 펼칩니다.

로프가 전체 길이에 걸쳐 물리적으로 충돌 가능한 존재를 가질 필요가없는 경우, 로프 연결부를 사용하여 두 끝을 연결하고 베벨 로프 점을 사용하여 중간에 스플라인 또는 다른 것을 렌더링하는 것이 좋습니다. 당신이 collidable 점에 밧줄을 걸고 긴장로 주위를 당겨하려고하는 것처럼

그러나 스크린 샷에서, 그것은 보인다. I 정말 당신이 Box2D와 함께 이것을 시도하는 경험을 즐길 것이라고 생각하지 않습니다. 당신이 필요로하는 것은 로프 물리학을 위해 특별히 고안된 맞춤 제작 된 행동입니다. 나는 거기에 어떤 좋은 기존의 소스 코드의 모르겠지만,이 비디오에서 좋은 아이디어를 얻을 수 : https://www.youtube.com/watch?v=Krlf1XnzZGc

+0

감사합니다 많이! 내 로프가 지금은 더 안정적입니다. – user1929598