2
\$\begingroup\$

As my prototype works perfectly fine I want to advance to more fun areas of the project and add a more complex player-character body.

So for Box2D I figured I'd need multiple fixtures, like one for the legs, one for the torso and one for the head.

Each of these fixtures will get a different sprite/texture that should be swappable dynamically if the player puts on some armour or changes cloths etc.

Until now the player-character consisted of a Box2D Body with just one single fixture. I added the sprite like this:

   body.setUserData(this.sprite);

I rendered it like this:

 // Draw-method
  if(body.getUserData() != null && body.getUserData() instanceof Sprite) {
      Sprite sprite = (Sprite) body.getUserData();
      sprite.setPosition(body.getPosition().x - sprite.getWidth() / 2, body.getPosition().y - sprite.getHeight() / 2);
      sprite.setRotation(body.getAngle() * MathUtils.radiansToDegrees);
      sprite.draw(spriteBatch);
  }

Now that I want to have multiple sprites for different "regions" of the body I figured it's better to add them to the fixture itself. For now I just wanted to reproduce what I already had, so just the one sprite I have to the one fixture I have right now instead of the body.

I do this like that:

Fixture fixture = body.createFixture(fixtureDef);

My problem arises when trying to render this.

for(Fixture fixture : body.getFixtureList())
{
    if(fixture.getUserData() != null && fixture.getUserData() instanceof Sprite)
    {
        Sprite sprite = (Sprite) fixture.getUserData();
        //sprite.setPosition(fixture.getShape().getPosition() ... // Not gonna work, because PolygonShape has no position! :(
        sprite.draw(spriteBatch);
    }
}

As you can read in the comment, the fixture for now has a rectangular shape which is made like:

shape = new PolygonShape();
shape.setAsBox(widthInMeters / 2, heightInMeters / 2);

The problem is, that a PolygonShape has not position :/ Now when I render this, the sprite is not being drawn at the fixtures position and currently I really have no idea how to fix that.

I'd highly appreciate any help you can give me! Thanks in advance and have a wonderful day! :)

\$\endgroup\$
1
\$\begingroup\$

A PolygonShape is just a collection of vertices. It's up to you how you want to define which position within that shape is "THE position" of the shape.

  • You could for instance use the position of the first vertex.

  • Or the centroid / average of all vertices.

  • Or the middle (or particular corner) of the bounding box formed from the leftmost, rightmost, topmost, and bottommost vertex positions.

    (This bounding box approach will likely be a good match for where your sprite's position is, but of course it depends on how you painted that sprite)

Like a lot of stuff in games, there's not one right answer that the code is supposed to already know. There are many valid choices you as a developer can make, and it's your responsibility to make those choices match consistently between different systems in your game.

\$\endgroup\$
0
\$\begingroup\$

This can actually be kind of complicated (perhaps there's a simple way that I've not found yet) so I would suggest letting someone else do it for you. Dermetfan has a really nice utilities library for Box2D and LibGDX which can do exactly what you're asking for.

Add this to your build.gradle under project(:core) inside dependencies

project(":core") {
    ...

    dependencies {
        ...
        compile "net.dermetfan.libgdx-utils:libgdx-utils-box2d:0.13.2" // <- This
    }
}

Then recompile your gradle project. With this you can replace all of your Sprite with Box2DSprite which allows you to automatically draw this sprite on a Body or Fixture.

Box2DSprite#draw(batch, fixture);

You can also add a Box2DSprite to your Body or Fixture's user data to automatically draw it.

// Set user data to the sprite.
fixture.setUserData(box2DSprite);
// Then we use the -static- function to automatically draw all attached sprites.
Box2DSprite.draw(batch, world);

Take a look at this wiki entry for more information.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.