I have been learning these 2 API’s and I am fairly new to Java as well. I have managed to create a Pong type game using just the box2d debug renderer.
I have created some simple graphics but for the hell of it, I have no idea how to attach a sprite to a body. I have tried to use a Box2DSprite thing on here that was created by dermetfan but I can’t get it to work. The wiki on libGDX is missing a huge chunk of Box2D and what is there about it, seems to be very vague.
Does anyone have a sample code of a sprite being applied to a single body?
I do it so that in my entity class (player for example) I have box2d’s body field which gets added to world at the begining. Then in entitiy’s render method you can draw anything at body.getPosition().
Box2d is actually one of the most doumented parts of libgdx because tutorials for jbox2d and standard box2d apply to it. Anyways, just set the sprite x/y to the position of the Body (getPosition())
I very much doubt there is a problem with the Box2DSprite you wrote! Most likely just my fail implementation to my program.
I am still trying to fire through your tutorials but life, things get in the way :D.
When I tried to use your Box2DSprite, it was throwing a null exception within the Box2DSprite.java, this was probably due to me not implementing it properly. I will get it, just a learning process I guess. hehe
I could help to find the mistake in the implementation if you posted it. However, I’m not trying to force the Box2DSprite on you Use what you think makes the most sense for you now.
In the first link I posted previously, basically this happens:
set the size of the Sprite to the size of the body (in meters, no conversion)
put the sprite in the bodies user data
get all bodies and their user data, if it’s a Sprite:
[list]
[li]set its position to the bottom left corner because it’ll be drawn from there (body position (is center) - sprite width / 2)
- set its rotation to the body rotation (body.getAngle() * MathUtils.radiansToDegrees), need to convert from radians to degrees here because the method takes degrees
- draw it
[/li]
[/list]
I know what the problem is, it is due to my poor OO design. I have a Ball class, WorldRenderer and GameSreen. I’ll fire it here and you can have a look, don’t giggle at the mess haha:
package com.gibbo.pong.view;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.physics.box2d.Box2DDebugRenderer;
import com.badlogic.gdx.physics.box2d.World;
import com.gibbo.pong.Scorer;
import com.gibbo.pong.graphics.Box2DSprite;
import com.gibbo.pong.model.Ball;
import com.gibbo.pong.model.Wall;
import com.gibbo.pong.screens.GameScreen;
public class WorldRenderer {
// Instance of the world
World world;
// Cam and debug instance
public OrthographicCamera cam;
Box2DDebugRenderer debug;
// The camera dimensions
private final float CAMERA_WIDTH = 30f;
private final float CAMERA_HEIGHT = 14f;
// Font and Sprite instance
SpriteBatch batch;
BitmapFont font;
// For setting size and converting to pixels
private int width;
private int height;
private float ppuX;
private float ppuY;
public WorldRenderer(World world) {
this.world = world;
this.cam = new OrthographicCamera(CAMERA_WIDTH, CAMERA_HEIGHT);
this.cam.position.set(CAMERA_WIDTH / 2, CAMERA_HEIGHT / 2, 0);
this.debug = new Box2DDebugRenderer();
this.cam.update();
this.batch = new SpriteBatch();
this.font = new BitmapFont();
}
public void setSize(int w, int h) {
this.width = w;
this.height = h;
ppuX = (float) width / CAMERA_WIDTH;
ppuY = (float) height / CAMERA_HEIGHT;
}
public void update(float delta) {
// Update the camera
cam.update();
// Draw the HUD
drawGraphics();
}
public void drawGraphics() {
// This starts the spritebatch and draws the playerscore to
// the screen, it then lets you know who is winning by drawing
// a message on the screen
batch.begin();
Box2DSprite.draw(batch, world);
font.draw(batch, "P1 Score: " + Scorer.p1Score, 25, 25);
font.draw(batch, "P2 Score: " + Scorer.p2Score, 1115, 25);
if (Scorer.p1Score > Scorer.p2Score) {
font.draw(batch, "Player 1 is winning!", 1280 / 2 - 140, 25);
} else if (Scorer.p2Score > Scorer.p1Score) {
font.draw(batch, "Player 2 is winning!", 1280 / 2 - 140, 25);
}
batch.end();
}
}
This class basically deals with any “drawing” on the screen, I will probably have a seperate Assets class to hold all the textures but since I was only using one at the moment, it seemed pointless.
This is my ball class:
package com.gibbo.pong.model;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;
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.CircleShape;
import com.badlogic.gdx.physics.box2d.Fixture;
import com.badlogic.gdx.physics.box2d.FixtureDef;
import com.badlogic.gdx.physics.box2d.World;
import com.gibbo.pong.graphics.Box2DSprite;
public class Ball {
public static Texture ball;
public static Sprite s;
public static Box2DSprite box2DSprite;
//Instance of the world
World world;
//Body for the ball
public Body ballBody;
//Fixture for the ball
Fixture ballFixture;
public Ball(World world){
this.world = world;
}
public Ball(World world, float posX, float posY){
//Define a body for the ball
BodyDef ballBodyDef = new BodyDef();
ballBodyDef.type = BodyType.DynamicBody;
ballBodyDef.position.set(posX, posY);
//Define a shape for the ball
CircleShape ballShape = new CircleShape();
ballShape.setRadius(0.30f);
//Define a fixture for the ball
FixtureDef ballFixtureDef = new FixtureDef();
ballFixtureDef.shape = ballShape;
ballFixtureDef.density = 1f;
//Create a ball
ballBody = world.createBody(ballBodyDef);
ballFixture = getBallBody().createFixture(ballFixtureDef);
ball = new Texture(Gdx.files.internal("images/ball.png"));
Sprite s = new Sprite(ball);
Box2DSprite box2DSprite = new Box2DSprite(s);
ballBody.setUserData(s);
// s.setOrigin(ballBodyPosX, ballBodyPosY);
// s.setPosition(ballBodyPosX, ballBodyPosY);
// Dispose of shape to keep the garbage collector happy
ballShape.dispose();
}
public void update(float delta){
}
public Body getBallBody() {
return ballBody;
}
public float getBallBodyPosX() {
return ballBody.getPosition().x;
}
public float getBallBodyPosY() {
return ballBody.getPosition().y;
}
}
You can probably imagine the GameScreen class, atm it draws the paddle, walls and goals. I was in the process of moving these to the WorldRenderer class but kept coming across problems and was going to actually re-write the whole thing. The GameScreen class also runs all the class.update() methods within it’s render loop, like my controller class.
Can you spot what I am failing at from my above code? It seems my main problem, well the most part I have difficult with is trying to do thing over several classes.