[LibGDX] Linking a Sprite (Or another image) to a Box2D Body

I have a body and a sprite which I want to link to that body.
My first idea was to set Sprite position to body position like this:

//(Inside my sprite's update method)
Vector2 bodyPos = new Vector2(body.getPosition().x - ship.getDimensions().x / 2, body.getPosition().y - ship.getDimensions().y / 2);
		ship.setPosition(bodyPos);
		ship.setRotation((float) Math.toRadians(body.getAngle()));

Because I am just drawing one or two bodies and sprites to see how things work, so far there are no problems with that method.

But then I accidentally found out about body.setUserData(Object) method. Wondering if this has any advantages or deals with something I have not encountered or thought about, I went to libgdx documentation and found this (at https://code.google.com/p/libgdx/wiki/PhysicsBox2D):

Iterator<Body> bi = world.getBodies();
                   
while (bi.hasNext()){
    Body b = bi.next();

    // Get the bodies user data - in this example, our user 
    // data is an instance of the Entity class
    Entity e = (Entity) b.getUserData();

    if (e != null) {
        // Update the entities/sprites position and angle
        e.setPosition(b.getPosition().x, b.getPosition().y);
        // We need to convert our angle from radians to degrees
        e.setRotation(MathUtils.radiansToDegrees * b.getAngle());
    }
}

So if I have only one body and not an array of bodies and sprites, it will be like this:

body.setUserData(mySprite);

(when rendering)
(Sprite)body.getUserData().setPosition(values);

Right? Because I don’t have many bodies and certainly I don’t need an iterator.

So, is this method only useful with many bodies? Or is it my method wrong or inefficient?

The other question is, I have my sprite in one class and body in another class (Actually I have a static method which creates a body wherever I want etc). These two do not know about each other. That is to say, no references, no parameters about each other.
Should I write them like this:

//Sprite constructor
public MySprite(parameters, no body parameters){
}

//Body constructor
public MyBody(other parameters, Object userData){
//other code
body.setUserData(userData);
}

I hope you can enlighten me with your ideas and knowledge :slight_smile:

EDIT: Dammit, I just realized there is a MathUtils class :smiley:

I think the proper way should be this:

You have an Entity class, which holds reference to a Body and a reference to Sprite

your game loop should go in this order


box2d.update(whatever)

for(Entity ent :entities) {
   ent.update(); // entity logic like AI, inputs, etc. At the end it updates Sprite position to match a Body position
}

//render sprites

Sprites should be held in different structure, optimal for rendering.

Body’s UserData should hold reference to its Entity - not to loop through bodies. It’s useful for collision detection. Box2D lets you add listeners and filters to your world… so you can detect when your bullet collides with a player, etc. your listeners would receive to Bodies. you can identify them by their UserData

I am sorry, I can’t understand. What should the entity class look like?
You say Entity class should hold reference to body and sprite. And you say Body’s userdata should hold reference to its entity. That sounded confusing to me. It might be because English is not my native language, but I just didn’t understand.

Correct me if I’m wrong, but I thought the userData was mostly for collision info with contactlisteners. I think your original method was fine.

User data is just pointer to any data that you want. Also its only sane way to do mapping from body to entity.

[quote=“Jimmt,post:4,topic:42057”]
+1

The original method on the OP is the same way I do it and I think it’s fine as well.

[quote=“pitbuller,post:5,topic:42057”]
What do you mean by “do mapping from body to entity”? What are you referring to with “entity”? I’m asking because I’m interested in how to utilize userData…

Usually it’s used for storing the java side object representing the Entity. When a collision happens, the Entity should be notified. But upon collision, you only get the Box2D Body, so you have to save user data (the entity to call the #collide(Entity) method) :slight_smile:

Hm… I don’t quite understand.

Sorry if I’m sounding a bit slow, but… why should the Entity be notified? (I’m still not sure I also understand what is being referred to as the Entity… is it synonymous to Object?)

Usually in games the Entity class represents anything in the game world, be it a weapon or enemy. The Entity should be connected to the box2D body because otherwise it’s hard to process what body hit what other body.

But what I do is that the body is a part of the Entity class…

…am I doing it wrong?

???

Yes, but when you use contactlistener it can only give you the fixtures/bodies that collide.

Sorry, I’m probably not explaining myself right… I’m coming from the perspective of “But wait… I’m handling collisions without the use of userData… does that mean I’m doing it wrong?”

How I do it is for example I have a class called MyCoin that represents a coin in the game, and it contains a Box2D Body. Now, during gameplay, I want the coin to disappear when the player comes into contact/collides with it (meaning the player has picked it up). What I do now is that I have all the coins stored in a Vector called coins; and upon collision, I loop through that Vector to check:

(1) Is one of the fixtures the player body?
AND
(2) Is the other fixture a coin?

At which point, if both are true, I do all the stuff that should happen (e.g. money increases) and then queue the coin for destruction after the world step. So, like this:

for (int i = 0; i < coins.size(); i++) {
    if ((fixtureA.getBody().equals(coins.elementAt(i).getBody()) && fixtureB.getBody().equals(myPlayer.getBody())) 
     || (fixtureB.getBody().equals(coins.elementAt(i).getBody()) && fixtureA.getBody().equals(myPlayer.getBody()))) {
        // do everything related to the coin getting picked up
    }
}

It occurred to me as I was implementing this that having to loop through collections of certain objects repeatedly upon collision is probably not the best way to do things from a performance standpoint. Also, I wanted specific objects of the same class to have significantly different behavior, it would probably be a pain to handle.

But I couldn’t think of another way to do it. Now, if userData will help me achieve this, I’m all ears :slight_smile: Please help. TIA!

Great conversation took place here while my connection was broken :slight_smile: Thanks guys.

So, let me wrap things up and see if there is something wrong in what I understood;

  • I should do the logic part with box2d (obviously, it is the physics part), and rendering part with an entity class (So, MyShip class is an entity class?) assuming that I want to separate logic and render (which is the efficient thing to do).
  • UserData is there to make collision detection easier? If I link my entity to a body using user data, I can determine which entity hit which one easier (like if(body.getUserData == myEntity) {//do stuff}

[quote=matheus23]Usually it’s used for storing the java side object representing the Entity. When a collision happens, the Entity should be notified. But upon collision, you only get the Box2D Body, so you have to save user data (the entity to call the #collide(Entity) method)
[/quote]

  • A Body userdata could (or should?) be an entity.

  • What we call entity is nothing more than our objects in the game. Like, the character, the enemy, the bullets, and weapons?

  • Basicly, there is nothing wrong with my method, but I still can (or should?) link the body and entity using UserData, and updating the entities using my method or the method in the libgdx page is up to me. And if I use UserData, I also have an advantage like this:

if(body1.getUserData() == ship){
// do not explode the ship, check health first
}
if(body2.getUserData()  == bullet){
//just make the bullet disappear
}

Adding to this… if I do the following inside the MyCoin class:

body.setUserData(this); // to store this MyCoin instance inside the body

How can I use getUserData() inside the collision listener to determine that the body is linked to a MyCoin instance? Meaning… how do I complete this if-statement?

if ((fixtureA.getBody().getUserData.equals(/*what can I put here to determine that this is MyCoin?*/) && fixtureB.getBody().equals(/*what can I put here to determine that this is MyPlayer?*/)) 
 || (fixtureB.getBody().getUserData.equals(/*what can I put here to determine that this is MyCoin?*/) && fixtureA.getBody().equals(/*what can I put here to determine that this is MyPlayer?*/))) {
    // do everything related to the coin getting picked up
}

Looking out for certain collisions and handling them with user data. Pushing user data into type specific working variables.
This approach works for all entities of a certain class.


// disable droid-bullet collisions if between shooter and own bullet because bullets are fired from the center of the body
world.setContactFilter(new ContactFilter() {

			@Override
			public boolean shouldCollide(Fixture fixtureA, Fixture fixtureB) {
				Object userDataA = fixtureA.getBody().getUserData();
				Object userDataB = fixtureB.getBody().getUserData();

				Droid droid = cast(userDataA, userDataB, Droid.class);
				Bullet bullet = cast(userDataA, userDataB, Bullet.class);
				if (droid != null && bullet != null) {
					if (bullet.getShooter().equals(droid)) {
						return false;
					}
				}

				return true;
			}
		});
private <O> O cast(Object object1, Object object2, Class<O> expectedClass) {
		if (expectedClass.isAssignableFrom(object1.getClass())) {
			return (O)object1;
		}
		if (expectedClass.isAssignableFrom(object2.getClass())) {
			return (O)object2;
		}
		return null;
	}

^ whoa…

http://static.rateyourmusic.com/lk/l/w/24d7c3b152d41ec52698dcbe9a10c9fc/3957980.jpg

I like it.

I may implement something similar in my code if I could also get around everything else that my current implementation requires :slight_smile: Thanks!