Lets see in this tutorial we will learn how to develop an android game with Box2d. There are following steps :
Step :1. Create a project using motodev.

Step :2. Create a lib folder inside the project and put jbox2d-2.0.1-full.jar file there.

Step :3. Open the project properties and add the jar file in the library.

Step :4. Rename the MainActivity.java into Box2dGame.java put the same in AndroidManifest.xml. Now open the class and put following code
package com.physicssample;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
public class Box2dGame extends Activity
{
private GLSurfaceView _surfaceView;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
_surfaceView = new ClearGLSurfaceView(this);
setContentView(_surfaceView);
}
@Override
protected void onPause() {
super.onPause();
_surfaceView.onPause();
}
@Override
protected void onResume() {
super.onResume();
_surfaceView.onResume();
}
}
Step :5. Now create a ClearGLSurfaceView.java class and put following code inside the class
package com.physicssample;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.view.MotionEvent;
public class ClearGLSurfaceView extends GLSurfaceView
{
ClearRenderer _refRenderer;
public ClearGLSurfaceView(Context context) {
super(context);
_refRenderer = new ClearRenderer(context);
setRenderer(_refRenderer);
}
public boolean onTouchEvent(final MotionEvent event) {
_refRenderer.setSize(this.getWidth(),this.getHeight());
queueEvent(new Runnable(){
public void run() {
_refRenderer.touchEvent(event.getX(), event.getY(), event.getAction());
}});
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
return true;
}
}
Step :5. Now create a ClearRenderer.java class and put following code inside the class
package com.physicssample;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import org.jbox2d.collision.PolygonShape;
import org.jbox2d.collision.Shape;
import org.jbox2d.collision.ShapeType;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.opengl.GLU;
import android.view.MotionEvent;
public class ClearRenderer implements GLSurfaceView.Renderer
{
private PhysicsWorld _physicsWorld;
private ObjectCreater _refBox;
private Context _context;
private int _width;
private int _height;
public ClearRenderer(Context newContext)
{
_context = newContext;
_refBox = new ObjectCreater(new float[]{-1,-1,0,1,-1,0,1,1,0,-1,1,0}, new float[]{ 0f,1f, 1f,1f, 1f,0f,0f,0f},new short[]{0,1,2,3,0},5);
_physicsWorld = new PhysicsWorld();
_physicsWorld.createWorld();
_physicsWorld.addBox(0f, -25f, 50f, 10f, 0f, false);
}
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
GLU.gluOrtho2D(gl, -12f, 12f, -20f, 20f);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
GL10.GL_REPEAT);
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
GL10.GL_REPEAT);
_refBox.loadTexture(gl, _context, R.drawable.box);
}
public void onSurfaceChanged(GL10 gl, int w, int h)
{
gl.glViewport(0, 0, w, h);
}
public void onDrawFrame(GL10 gl)
{
gl.glClearColor(0f, 0, 0.5f, 1.0f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
GL10.GL_REPLACE);
gl.glColor4f(1f, 1f, 1f, 1f);
Vec2 vec;
Body _body = _physicsWorld.getBodyList();
do
{
Shape _shape = _body.getShapeList();
if (_shape != null)
{
vec = _body.getPosition();
float rot = _body.getAngle() * 57f;
if (ShapeType.POLYGON_SHAPE == _shape.getType())
{
Vec2[] _vertexes = ((PolygonShape)_shape).getVertices();
_refBox.draw(gl, vec.x, vec.y, 0f, rot, _vertexes[2].x, _vertexes[2].y);
}
}
_body = _body.getNext();
}
while (_body != null);
_physicsWorld.update();
}
public void touchEvent(float x, float y, int eventCode)
{
float _worldX = ((x-(this._width/2))*12f)/(this._width/2);
float _worldY = ((y-(this._height/2))*-20f)/(this._height/2);
if (eventCode == MotionEvent.ACTION_UP)
{
_physicsWorld.addBox(_worldX, _worldY, .98f, .98f, 0f, true);
}
}
public void setSize(int x, int y)
{
this._width = x;
this._height = y;
}
}
Step :6. Now create a PhysicsWorld.java class and put following code inside the class
package com.physicssample;
import org.jbox2d.collision.AABB;
import org.jbox2d.collision.PolygonDef;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.World;
public class PhysicsWorld
{
final private int MAXBOX = 20;
final private float FRAMERATE = 30f;
private float _timeStep = (1f / FRAMERATE);
private int _iterations = 5;
private int _count = 0;
private AABB _box2dWorld;
private World _myWorld;
public void createWorld()
{
_box2dWorld = new AABB();
_box2dWorld.lowerBound.set(new Vec2(-100f, -100f));
_box2dWorld.upperBound.set(new Vec2(100f, 100f));
Vec2 gravity = new Vec2(0f, -10f);
boolean doSleep = false;
_myWorld = new World(_box2dWorld, gravity, doSleep);
}
public void setGrav(float x, float y)
{
_myWorld.setGravity(new Vec2(x,y));
}
public void addBox(float x, float y, float xr, float yr, float angle, boolean dynamic)
{
if (_count < (MAXBOX-1))
{
BodyDef _groundBody;
_groundBody = new BodyDef();
_groundBody.position.set(new Vec2(x, y));
_groundBody.angle = angle;
Body groundBody = _myWorld.createBody(_groundBody);
PolygonDef _groundShape;
_groundShape = new PolygonDef();
_groundShape.setAsBox(xr, yr);
_groundShape.density = 1.0f;
groundBody.createShape(_groundShape);
if (dynamic)
{
groundBody.setMassFromShapes();
}
if (dynamic)
{
_count++;
}
}
}
public void update()
{
_myWorld.step(_timeStep, _iterations);
}
public int getCount()
{
return _count;
}
public Body getBodyList()
{
return _myWorld.getBodyList();
}
}
Step :6. Now create a ObjectCreater.java class and put following code inside the class
package com.physicssample;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import javax.microedition.khronos.opengles.GL10;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLUtils;
public class ObjectCreater
{
private FloatBuffer _vertexBuffer;
private ShortBuffer _indexBuffer;
private FloatBuffer _texBuffer;
private int _vertexCount = 0;
private boolean _hasTexture = false;
private int[] _texture = new int[1];
public ObjectCreater(float[] coords, float[] tcoords, short[] icoords, int vertexes)
{
this(coords, icoords, vertexes);
_texBuffer = makeFloatBuffer(tcoords);
}
public ObjectCreater(float[] coords, short[] icoords, int vertexes)
{
_vertexCount = vertexes;
_vertexBuffer = makeFloatBuffer(coords);
_indexBuffer = makeShortBuffer(icoords);
}
protected static FloatBuffer makeFloatBuffer(float[] arr) {
ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4);
bb.order(ByteOrder.nativeOrder());
FloatBuffer fb = bb.asFloatBuffer();
fb.put(arr);
fb.position(0);
return fb;
}
protected static ShortBuffer makeShortBuffer(short[] arr) {
ByteBuffer bb = ByteBuffer.allocateDirect(arr.length*4);
bb.order(ByteOrder.nativeOrder());
ShortBuffer ib = bb.asShortBuffer();
ib.put(arr);
ib.position(0);
return ib;
}
public void loadTexture(GL10 gl, Context mContext, int mTex) {
_hasTexture = true;
gl.glGenTextures(1, _texture, 0);
gl.glBindTexture(GL10.GL_TEXTURE_2D, _texture[0]);
Bitmap bitmap;
bitmap = BitmapFactory.decodeResource(mContext.getResources(), mTex);
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
bitmap.recycle();
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR );
gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR );
}
public void draw(GL10 gl) {
if (_hasTexture) {
gl.glEnable(GL10.GL_TEXTURE_2D);
gl.glBindTexture(GL10.GL_TEXTURE_2D, _texture[0]);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, _texBuffer);
} else {
gl.glDisable(GL10.GL_TEXTURE_2D);
}
gl.glFrontFace(GL10.GL_CCW);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, _vertexBuffer);
gl.glDrawElements(GL10.GL_TRIANGLE_FAN, _vertexCount, GL10.GL_UNSIGNED_SHORT, _indexBuffer);
gl.glDisable(GL10.GL_TEXTURE_2D);
}
public void draw(GL10 gl, float x, float y, float z, float rot, float scale) {
this.draw(gl, x, y, z, rot, scale, scale);
}
public void draw(GL10 gl, float x, float y, float z, float rot, float scaleX, float scaleY) {
gl.glPushMatrix();
gl.glTranslatef(x, y, z);
gl.glRotatef(rot, 0f, 0f, 1f);
gl.glScalef(scaleX, scaleY, 1f);
this.draw(gl);
gl.glPopMatrix();
}
}
Step :6. Run your app it will look like this . If you have any question or need more clarification please write on forum.dremsus.com.

Tags: alpha effect, An Android application, AndEngine, AndEngineGame, Android components, Android Game, animation in Android, Apple, Blinking effect, Box2d, Box2D and Android, Box2D Game demo in Android, Game Programming, Key Event, Key Event handler, Movement, Splash screen, Timer, Touch, TouchEvent, Transition
Follow us on Twitter