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\$

2 Answers 2

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\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .