如何使用box2d构建和绘制一条漂亮的绳子

时间:2014-09-26 07:19:43

标签: java libgdx box2d

我在box2d中创建了一条带有RevoluteJointRopeJoint的绳子,但我遇到了一些问题:

  1. 有时,最后一段旋转,看起来它与绳索断开连接。
  2. 如何画这个东西?我创建一个每个链接大小的纹理。如果绳子没有移动,它看起来很好,但是一旦绳子移动并且不同的链节开始稍微旋转,你就会看到链节之间的间隙。
  3. 代码:

    private void createChain(World world, Body anchorBody) {
      Body previousBody = anchorBody;
    
      FixtureDef fixtureDef = new FixtureDef();
    
      PolygonShape robeLinkShape = new PolygonShape();
      robeLinkShape.setAsBox(4 / PPM, 8 / PPM);
      fixtureDef.shape = robeLinkShape;
      fixtureDef.density = 0.1f;
      //    fixtureDef.friction = 1.0f;
      fixtureDef.restitution = 0.1f;
      fixtureDef.filter.maskBits = Box2DConst.BIT_PLAYER;
      fixtureDef.filter.categoryBits = Box2DConst.BIT_GROUND;
    
      float mapX = anchorBody.getPosition().x * PPM;
      float mapY = anchorBody.getPosition().y * PPM;
    
      BodyDef bodyDef = new BodyDef();
      bodyDef.angularDamping = 1.0f;
      bodyDef.linearDamping = 1.0f;
    
      //create rope
      for (int i = 0; i < 10; i++) {
        Float robeX = mapX / PPM;
        Float robeY = (mapY - (i * 16)) / PPM;
        bodyDef.type = BodyDef.BodyType.DynamicBody;
        bodyDef.position.set(robeX, robeY);
    
        final Body link = world.createBody(bodyDef);
        link.createFixture(fixtureDef);
    
        RevoluteJointDef jointDef = new RevoluteJointDef();
        jointDef.initialize(previousBody, link, new Vector2(robeX, robeY));
    
        //don't need the rope to collide itself
        jointDef.collideConnected = false;
        jointDef.enableLimit = false;
    
        // because we don't collide with other bodies in the rope, limit rotation to keep the rope bodies from rotating too much.
        jointDef.lowerAngle = -5.0f * MathUtils.degreesToRadians;
        jointDef.upperAngle = 5.0f * MathUtils.degreesToRadians;
        world.createJoint(jointDef);
    
        links.add(link);
        previousBody = link;
      }
    
      RopeJointDef ropeJointDef = new RopeJointDef();
      ropeJointDef.localAnchorB.set(0, 0);
      ropeJointDef.maxLength = 90.0f;
      ropeJointDef.bodyB = previousBody;
      ropeJointDef.bodyA = links.get(0);
      ropeJointDef.collideConnected = false;
      world.createJoint(ropeJointDef);
    }
    
    public void draw(final SpriteBatch batch) {
      Texture texture = FipiGame.res.get("rope");
      batch.begin();
      for (Body link : links) {
        float x = (link.getPosition().x * PPM) - 4;
        float y = (link.getPosition().y * PPM) - 8;
    
        float angleDeg = MathUtils.radiansToDegrees * link.getAngle();
        batch.draw(texture, x, y, 0, 0, texture.getWidth(), texture.getHeight(), 1f, 1f, angleDeg, 0,   0,
                 texture.getWidth(), texture.getHeight(), false, false);
       }
    batch.end();
    }
    

1 个答案:

答案 0 :(得分:1)

而不是基于身体位置和旋转进行绘制:通过循环旋转关节位置(世界空间中的anchorA和anchorB的中点)创建一组点。然后绘制你的精灵,以便他们连接这些位置。这有点不准确,因为它不能完美地与刚体的位置对齐,但它应该看起来很好。