So I am working on programming a java 2D platformer for fun on the side and I have a rendered TMX level and a box2d body (just a circle shape) that I am currently using as my player. All the controls work good, but the camera is off center but follows player perfectly. What I am trying to do is to get the sprite to be attached to the body. I am aware they don't work perfectly and that the sprite basically just has to follow the body but can't get it to work.
Right now my sprite displays off the map because it goes to the bottom left corner by default and my map is messed up. I have tried drawing the sprite animation to the x and y from the body position but that isn't working. Here is my code
This is my class and create **I cut out some stuff that wasn't relevant so don't mind the random declarations*
public class MyGdxGame extends ApplicationAdapter implements InputProcessor {
Texture img;
TiledMap tiledMap;
OrthographicCamera camera;
TiledMapRenderer tiledMapRenderer;
SpriteBatch sb;
Texture texture;
Player player;
Sprite sprite;
static float w,h;
//Box2D Variables
World world;
Box2DDebugRenderer b2dr;
Animator mario;
private Hud hud;
public static final int V_WIDTH = 485;
public static final int V_HEIGHT = 515;
private static final int FRAME_COLS = 8;
private static final int FRAME_ROWS = 1;
public static final float PPM = 100f;
public SpriteBatch batch;
Animation runAnimation;
Texture runSheet;
TextureRegion[] runFrames;
TextureRegion currentFrame;
float stateTime;
float sbX = 80;
float sbY = 12;
final float timeStamp = 1.0f / 30.0f;
@Override
public void create (){
GdxNativesLoader.load();
w = Gdx.graphics.getWidth();
h = Gdx.graphics.getHeight();
tiledMap = new TmxMapLoader().load("Level1-1.tmx");
tiledMapRenderer = new OrthogonalTiledMapRenderer(tiledMap, 1f / PPM);
Gdx.input.setInputProcessor(this);
world = new World(new Vector2(0, -10f), true); //Vector is for gravity
b2dr = new Box2DDebugRenderer();
player = new Player(world);
BodyDef bdef = new BodyDef();
PolygonShape shape = new PolygonShape();
FixtureDef fdef = new FixtureDef();
Body body;
//Create ground bodies/fixtures
for(MapObject object : tiledMap.getLayers().get(2).getObjects().getByType(RectangleMapObject.class)){
Rectangle rect = ((RectangleMapObject) object).getRectangle();
bdef.type = BodyDef.BodyType.StaticBody;
bdef.position.set(((rect.getX() + rect.getWidth() / 2) / PPM), ((rect.getY() + rect.getHeight() /2) / PPM));
body = world.createBody(bdef);
shape.setAsBox((rect.getWidth() / 2) / PPM, (rect.getHeight() / 2 / PPM));
fdef.shape = shape;
body.createFixture(fdef);
}
//Create pipe bodies/fixtures
for(MapObject object : tiledMap.getLayers().get(3).getObjects().getByType(RectangleMapObject.class)){
Rectangle rect = ((RectangleMapObject) object).getRectangle();
bdef.type = BodyDef.BodyType.StaticBody;
bdef.position.set(((rect.getX() + rect.getWidth() / 2) / PPM), ((rect.getY() + rect.getHeight() /2) / PPM));
body = world.createBody(bdef);
shape.setAsBox((rect.getWidth() / 2) / PPM, (rect.getHeight() / 2) / PPM);
fdef.shape = shape;
body.createFixture(fdef);
}
//Create brick bodies/fixtures
for(MapObject object : tiledMap.getLayers().get(4).getObjects().getByType(RectangleMapObject.class)){
Rectangle rect = ((RectangleMapObject) object).getRectangle();
bdef.type = BodyDef.BodyType.StaticBody;
bdef.position.set(((rect.getX() + rect.getWidth() / 2) / PPM), ((rect.getY() + rect.getHeight() /2) / PPM));
body = world.createBody(bdef);
shape.setAsBox((rect.getWidth() /2 / PPM), (rect.getHeight() /2 / PPM));
fdef.shape = shape;
body.createFixture(fdef);
}
camera = new OrthographicCamera();
camera.setToOrtho(false, w / PPM, h / PPM);
camera.update();
runSheet = new Texture("Squirrel-Run.png");
TextureRegion[][] tmp = TextureRegion.split(runSheet, runSheet.getWidth()/FRAME_COLS, runSheet.getHeight()/FRAME_ROWS);
runFrames = new TextureRegion[FRAME_COLS * FRAME_ROWS];
int index = 0;
for(int i = 0; i < FRAME_ROWS; i++){
for(int j = 0; j < FRAME_COLS; j++){
runFrames[index++] = tmp[i][j];
}
}
runAnimation = new Animation(0.025f, runFrames);
sb = new SpriteBatch();
stateTime = 0f;
hud = new Hud(sb);
world.step(timeStamp, 6, 2);
}
this is my render, update and input methods
public void update(){
camera.update();
}
public void handleInput(){
if(Gdx.input.isKeyJustPressed(Input.Keys.SPACE))
player.b2body.applyLinearImpulse(new Vector2(0, 4f), player.b2body.getWorldCenter(), true);
if(Gdx.input.isKeyPressed(Input.Keys.RIGHT) && player.b2body.getLinearVelocity().x <= 2)
player.b2body.applyLinearImpulse(new Vector2(0.1f, 0), player.b2body.getWorldCenter(), true);
if(Gdx.input.isKeyPressed(Input.Keys.LEFT) && player.b2body.getLinearVelocity().x >= -2)
player.b2body.applyLinearImpulse(new Vector2(-0.1f, 0), player.b2body.getWorldCenter(), true);
}
@Override
public void render (){
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
tiledMapRenderer.render();
tiledMapRenderer.setView(camera);
handleInput();
//Render our box2dDebugLines
b2dr.render(world, camera.combined);
world.step(timeStamp, 6, 2);
camera.position.set(player.b2body.getWorldCenter().x, player.b2body.getWorldCenter().y, 0);
camera.update();
stateTime += Gdx.graphics.getDeltaTime();
currentFrame = runAnimation.getKeyFrame(stateTime, true);
sb.begin();
sb.draw(currentFrame, player.b2body.getPosition().x / PPM, player.b2body.getPosition().y / PPM);
sb.end();
sb.setProjectionMatrix(hud.stage.getCamera().combined);
hud.stage.draw();
And this is my player class
public final class Player {
public int x,y;
public Vector3 position;
public World world;
public com.badlogic.gdx.physics.box2d.Body b2body;
public Player(World world) {
this.world = world;
defineSprite();
}
public void defineSprite(){
BodyDef bdef = new BodyDef();
bdef.position.set(32 / MyGdxGame.PPM, 32 / MyGdxGame.PPM);
bdef.type = BodyDef.BodyType.DynamicBody;
b2body = world.createBody(bdef);
FixtureDef fdef = new FixtureDef();
CircleShape shape = new CircleShape();
shape.setRadius(5 / MyGdxGame.PPM);
fdef.shape = shape;
b2body.createFixture(fdef);
}
public float getX() {
return position.x;
}
public float getY() {
return position.y;
}
public Vector3 getPosition() {
return position;
}
public float getWidth() {
return 32 / MyGdxGame.PPM;
}
public float getHeight() {
return 32 / MyGdxGame.PPM;
}
}
I know my code is jumbled I am new to programming, I will clean up with separate classes once I get this working. I was looking into .setUserData but I don't know what else i need to put for this. Can anyone point me in the right direction of my camera/attaching the sprite to the body? Thanks