[Box2D, libGDX] Drawing a sprite in a body

First of all, I’m spanish and my English not is perfect, but i’m trying dot you understand me.

I’m trying to put a sprite in a body (or a texture, the theme is dot be a image), so, for do this, I have downloaded Box 2D editor and save my file. After, I find a tutorial for implement the body for my game, but when I run my game it look like this:

Body is moving independently the sprite, so it’s no cool…

How can I put my sprite in the body correctly?

My code:

Base.java


package com.unclain.serie2.a;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.physics.box2d.Body;
import com.badlogic.gdx.physics.box2d.BodyDef;
import com.badlogic.gdx.physics.box2d.BodyDef.BodyType;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.CircleShape;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.PolygonShape;
import com.badlogic.gdx.physics.box2d.World;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Label;

public class Base implements Screen{

	private static final float QUIBBY_WIDTH = 8;
	
	private World world;
	private OrthographicCamera camera;
	private Box2DDebugRenderer renderer;
	private Body bcirculo;
	
	private Texture texture;
	private SpriteBatch sb;
	private Sprite s;
	
	private static final float MUNDO_A_BOX = 0.01f;
	private static final float BOX_DEL_MUNDO = 100f;
	
	private Vector2 quibbyModelOrigin;
	
	private Body quibby;
	
	public void render(float delta) {
		Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
		Gdx.gl.glClearColor(0, 0.5f, 0, 1);
		
		float tw = Gdx.graphics.getWidth();
		float th = Gdx.graphics.getHeight();
		
		camera = new OrthographicCamera(tw / 2, th / 2);
		
		renderer = new Box2DDebugRenderer();
		
		renderer.render(world, camera.combined);
		
		world.step(1/40f, 6, 6);
		
		if(Gdx.input.isKeyPressed(Keys.D)){
			bcirculo.setLinearVelocity(new Vector2(50f, 0));
		}
		
		else if(Gdx.input.isKeyPressed(Keys.A)){
			bcirculo.setLinearVelocity(new Vector2(-50f, 0));
		}
		
		else if(Gdx.input.isKeyPressed(Keys.S)){
			bcirculo.setLinearVelocity(new Vector2(0, -50f));
		}
		
		else if(Gdx.input.isKeyPressed(Keys.W)){
			bcirculo.setLinearVelocity(new Vector2(0, 50f));		
		}
		
		else if(Gdx.input.isKeyPressed(Keys.R)){
			quibby.setLinearVelocity(new Vector2(0, 50f));
			s.setRotation(0);
		}
		
		else if(Gdx.input.isKeyPressed(Keys.UP)){
			quibby.setLinearVelocity(new Vector2(0, 50f));
		}
		
		else if(Gdx.input.isKeyPressed(Keys.DOWN)){
			quibby.setLinearVelocity(new Vector2(0, -50f));
		}
		
		else if(Gdx.input.isKeyPressed(Keys.RIGHT)){
			quibby.setLinearVelocity(new Vector2(50f, 0));
		}
		
		else if(Gdx.input.isKeyPressed(Keys.LEFT)){
			quibby.setLinearVelocity(new Vector2(-50f, 0));
		}
		
		sb = new SpriteBatch();
		sb.begin();
		s.draw(sb);
		sb.end();
		
		Vector2 bottlePos = quibby.getPosition().sub(quibbyModelOrigin);
		 
	    s.setPosition(bottlePos.x + s.getWidth() * 2, bottlePos.y + s.getHeight() * 2);
	    //s.setRegion(0, 0, 115, 135);
	    s.setOrigin(quibbyModelOrigin.x, quibbyModelOrigin.y);
	    s.setRotation(quibby.getAngle() * MathUtils.radiansToDegrees);
	    
	}

	public void resize(int width, int height) {
		
	}

	public void show() {
		world = new World(new Vector2(0, -60), true);
		camera = new OrthographicCamera(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2);
		
		BodyDef bdsuelo = new BodyDef();
		bdsuelo.position.set(new Vector2(0, -70));
		
		Body bsuelo = world.createBody(bdsuelo);
		
		PolygonShape ssuelo = new PolygonShape();
		ssuelo.setAsBox((camera.viewportWidth) * 2, 10.0f);
		
		bsuelo.createFixture(ssuelo, 0.0f);
		
		ssuelo.dispose();
		
		BodyDef bdcirculo = new BodyDef();
		bdcirculo.type = BodyType.DynamicBody;
		bdcirculo.position.set(new Vector2(0, 10));
		
		bcirculo = world.createBody(bdcirculo);
		
		CircleShape scircle = new CircleShape();
		scircle.setRadius(5.4f);
		
		FixtureDef fdcircle = new FixtureDef();
		fdcircle.density = 0.6f;
		fdcircle.friction = 0.5f;
		fdcircle.restitution = 0.5f;
		fdcircle.shape = scircle;
		
		Fixture fcircle = bcirculo.createFixture(fdcircle);
		
		texture = new Texture(Gdx.files.internal("MuñecoFeo256x256.png"));
		
		s = new Sprite(texture);
		
		scircle.dispose();
		
		crearQuibby();
		
	}
	
	public void crearQuibby(){
		BodyEditorLoaderFix loader = new BodyEditorLoaderFix(Gdx.files.internal("data/Serie2b.json"));
		
		BodyDef bd = new BodyDef();
		bd.type = BodyType.DynamicBody;
		
		FixtureDef fd = new FixtureDef();
		fd.density = 1;
		fd.friction = 0.5f;
		fd.restitution = 0.3f;
		
		quibby = world.createBody(bd);
		quibby.setUserData(s);
		
		loader.attachFixture(quibby, "MuñecoFeo.png", fd, QUIBBY_WIDTH);
		quibbyModelOrigin = loader.getOrigin("MuñecoFeo.png", QUIBBY_WIDTH).cpy();
	}


	public void hide() {
		
	}

	public void pause() {
		
	}

	public void resume() {
		
	}

	public void dispose() {
		
	}
	
	
	
}

The other class contain a setScreen(new Base()); method.

You need to look into box2d scaling: http://pimentoso.blogspot.com/2013/01/meter-and-pixel-units-in-box2d-game.html
Basically, box2d requires you to scale from pixels to meters. You can’t do 1:1 otherwise it will screw up, so choose something reasonable and read the article.

^ yup, this. I think you already have the conversion/scaling variables in your code, but you don’t use them in your code that you posted:

   private static final float MUNDO_A_BOX = 0.01f;
   private static final float BOX_DEL_MUNDO = 100f;

So basically, what you’d want to try is multiply the x and y coordinates of Sprite s by BOX_DEL_MUNDO when you’re setting its position.

Use camera that size is specified in meters.

It might not be the best way to understand how it works, but this might do the job for you.

I tryied to multiplicate the position of the sprite * BOX_DEL_MUNDO but now I can’t see it…

So, I have problems with Jymmt’s link, there are any tutorial for do this? I don’t understand the render part of it. ::slight_smile: