Hello Everyone,
Over the course of the next few weeks we would be covering the topic of using Box2d for physics in your libgdx app/game. In our recently released Android Game – Balloon Shooter we used Box2d for all the physics. Box2d is awesome in handling all the physics and gives realistic results. Integrating is not that difficult also. For more information regarding Box2d you can check their site Box2D where they also have a documentation which covers mostly everything you would require to make an awesome physics game.
There are many ways to use box2d in your game and the following method is one of the many methods you can use.
World:
In box2d all the objects exist in a world which has to be created before the objects.
The syntax for world requires to give two arguments -> Vector2 Gravity and Boolean allowSleep. Gravity as the name suggests is to give a gravitational force to all the objects in the world. You can also give a horizontal force (like a wind) if need arises. AllowSleep is usually set to true as it saves computations when objects in the game are stationary and not having any collisions, so usually we set it to true.
World world=new World(new Vector2(0,-20),true)
Here we used negative y value for gravity because in libgdx the y coordinate value decreases as we go down the screen.
Body & Fixture:
In box2d there are two parts of a physics objects -> a body and a fixture. Body is an invisible part which has information like position,velocity,angle etc. Fixture is the physical shape which is attached to the body to give it properties like mass, friction, restitution etc.
Body:
Firstly box was made with MKS (Metre, Kg, Second) units in mind, so it is not the best practice to have 1pixel equivalent to 1m in box2d. So we create constants to convert all the pixel units to physics one and vice versa.
static final float WORLD_TO_BOX=0.01f; static final float BOX_WORLD_TO=100f; float ConvertToBox(float x){ return x*WORLD_TO_BOX; }
For creating a body we need to have reference to the World object. Also for creating a body we first create a BodyDef object which store properties like position,angle and use it to create a body as shown below.
public void CreateBody(World world,Vector2 pos,float angle){ BodyDef bodyDef = new BodyDef(); bodyDef.type = bodyType; bodyDef.position.set(ConvertToBox(pos.x),ConvertToBox(pos.y)); bodyDef.angle=angle; body = world.createBody(bodyDef); }
Fixture/Shapes:
Now the body is made we have to attach a physical shape to it i.e. a Fixture. We first define a PolygonShape and give it dimenstions of width and height. As it takes half width and half height as arguments we divide both of them by 2. Then we create a FixtureDef object to hold information like density,restitution (the constant which defines collision is elastic or inelastic whose value ranges from 0.0 to 1.0. 1 being elastic and more than 1 will give really odd results),shape etc. Then we attach a fixture to the body by calling body.createFixture(FixtureDef fd).
private void MakeRectFixture(float width,float height,BodyDef.BodyType bodyType, float density,float restitution, Vector2 pos,float angle){ PolygonShape bodyShape = new PolygonShape(); float w=ConvertToBox(width/2f); float h=ConvertToBox(height/2f); bodyShape.setAsBox(w,h); FixtureDef fixtureDef=new FixtureDef(); fixtureDef.density=density; fixtureDef.restitution=restitution; fixtureDef.shape=bodyShape; body.createFixture(fixtureDef); bodyShape.dispose(); }
Adding a circle shape is similar to rectangle just that the shape type would be a CircleShape and not a PolygonShape and we would have to give a radius to it rather than width and height.
void MakeCircleFixture(float radius,BodyDef.BodyType bodyType, float density,float restitution, Vector2 pos,float angle){ FixtureDef fixtureDef=new FixtureDef(); fixtureDef.density=density; fixtureDef.restitution=restitution; fixtureDef.shape=new CircleShape(); fixtureDef.shape.setRadius(BoxObjectManager.ConvertToBox(radius)); body.createFixture(fixtureDef); fixtureDef.shape.dispose(); }
World Update Fixed TimeStep:
In this way a body can be created and fixtures can be attached to it. Finally to update the physics we have to call step function of world object to update it for the delta time passed. Shown below is a function to update the physics which should be called in the game’s main update function.
static final float BOX_STEP=1/120f; static final int BOX_VELOCITY_ITERATIONS=8; static final int BOX_POSITION_ITERATIONS=3; float accumulator; public void Update(float dt){ accumulator+=dt; while(accumulator>BOX_STEP){ world.step(BOX_STEP,BOX_VELOCITY_ITERATIONS,BOX_POSITION_ITERATIONS); accumulator-=BOX_STEP; } }
You can test with different values for the above three constants to see which works best for you. The above values were used in our game – Balloon Shooter. It is good to use a constant value for udpating physics because usually rendering is slower than physics and frames per second can be variable depending on what is being drawn on the screen. So what we do is have a constant udpate time for physics which is usually more than the render udpate time. So every frame we add the time in a variable called accumulator and the loop the phyics the number of times to update with the render timestep. This is not exactly the best method to do it but it worked for us so we kept it as shown above. There is a post which describes in a really detailed manner on how to have a fixed timestep to update physics.
Though bodies are created still you wont see anything on the screen as we haven’t attached any texture to the bodies.
This we will do in the next tutorial.
Thank you for the patience. Please leave any queries/suggestions/feedback in comments section. We look forward to hearing from you.
Oh!!! I really needed this, thank you!!! Can i translate your post to spanish, i have my blog about libgdx Development too
Sure go ahead, but don’t forget to link our blog 🙂
Of Course! Thanks!
hey u are not the this site’s admin! ¬¬
Me and abhishekbatra are the developers who work on this blog. So it is fine 🙂
Ok! thanks! 😉
Hello, I’m doing a Libgdx/Box2D simple game for my Final Year Computer Science project. I’m been fiddling with it for a while, but I’m having problems linking classes together when I write a larger code considering of multiple classes (the sprite doesn’t seem to move).
I was wondering you have some working source code examples?
Sure. Just give us sometime. We would put up a small example source code for libgdx/box2d in some days.
Hi,
I am newbie to android game development. Right now I am trying to develop a simple box game in android using libgdx and box2d. I have made a single .tmx file to load a level. This is for a size of 1024×768.
I have a simple question, if I have to load the game in devices with smaller resoution say 480×320, do I have to scale the image, but scaling, of course, will degrade the image quality. Or do I need to create .tmx files to support all four classes(xdpi, hdpi…) of devices?
If so, this will be quiet heavy, for I need to create a game with 25 levels, so will I have to create 100 .tmx files to launch the game.
May I know how you handle this issue in your game?
Thanks for taking the time to look at our game. Regarding your doubt well in our game we had one group of textures which we scaled for different resolutions.
Scaling degrades image quality so best way is to make the textures for highest resolution your game will support and then scale down for other resolutions because scaling down an image is much better than scaling up.
Hope this will help you.
Hi ,
Yes, I understand that. However my main concern is in loading the game from a .tmx file.
.tmx file will be refering only 1 category of images(say “hdpi”).
So if I need to support all four classes(xdpi , hdpi, …), do I need to create tmx for all of them?
Do the make fixture methods go in the libgdx create method and does the update method go in the libgdx render method? Then would I create an orthographic camera and use the Box2dDebugRenderer if I wanted to render this?
Hi.. the tutorial is wonderful but facing some errors as i am completely new to this game engine (libgdx).. It would be very helpful if you can pose an example source code.
ThankYou,
Adithya.
Hi,
You can try the source code in this post (http://rotatingcanvas.com/box2dlibgdx-example-code/)
Thanks
example app doesn’t launch
Exception in thread “LWJGL Application” com.badlogic.gdx.utils.GdxRuntimeException: File not found: Images/examplepack (Internal)
at com.badlogic.gdx.files.FileHandle.read(FileHandle.java:108)
at com.badlogic.gdx.graphics.g2d.TextureAtlas$TextureAtlasData.(TextureAtlas.java:99)
at com.badlogic.gdx.graphics.g2d.TextureAtlas.(TextureAtlas.java:215)
at com.badlogic.gdx.graphics.g2d.TextureAtlas.(TextureAtlas.java:210)
at com.Example.Assets.Load(Assets.java:18)
at com.Example.GameLoop.Init(GameLoop.java:40)
at com.Example.GameLoop.(GameLoop.java:35)
at com.Example.Game.create(Game.java:35)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:126)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:113)
oops. File not found. Okay.
Hi ,
Sorry for the late reply. You have to link the assets folder to the “BoxLibgdxExample-Desktop” Project. In the post (http://rotatingcanvas.com/box2dlibgdx-example-code/) where the example is available for download, screenshots are present to show how to the link the assets folder.
The steps are :-
Right click on BoxLibgdxExample-Desktop in Package Explorer-> Then go build Path -> then to Link Source.
In the screen which shows up click on browse and select the assets folder from the android project (BoxLibgdxExample-Android) and click Finish.
Thanks
No! I must say sorry, because it’s my stupidity 🙂