Bull in a china shop – Behind the scenes in Android

DSC00032Here are the details about how I constructed the “Bull in a china shop” demo. For this demo I used Box2D physics engine and AndEngine to make the demo. I decided to use sprites for the china shop and picked up images of glasses, wine glasses, bottles etc from www.openclipart.org.

Be extremely careful when creating the TextureRegion using BitmapTextureAtlas. If you don’t get the co-ordinates right the display can be weird.

Here are 2 clips of Bull in a China Shop demo
1.Bull in a china shop in Moon’s gravity
2.Bull in a china shop in Earth’s gravity
The code for this can be cloned  from Github from Bulldozed

Here is a snippet of this

this.mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 556, 246, TextureOptions.BILINEAR);
this.mTumblerTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "tumblr.png", 0, 0);
this.mBitmapTextureAtlas.load();
this.mBottleTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "bottle.png",20, 29);
this.mBitmapTextureAtlas.load();
this.mGlassTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "glass.png",36, 69);
this.mBitmapTextureAtlas.load();
this.mVaseTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, "vase.png",56, 89);
this.mBitmapTextureAtlas.load();
...
...

This is very important to get right otherwise you are setting yourself for a lot of grief.

Superficially the demo looks real easy. It appears that creating a pyramid stack should be a breeze as long as you get the coordinates right. Wrong! Building a pyramid using Box2D with the effect of gravity can be a real challenge as I found out. I would build two stacks and the stack would become unstable and collapse.

Anyway here are the findings

  1. Each row is not placed directly over the object below. I leave a gap of 2 px between them The reason is the object below exerts a force ‘F’ upward. The object above exerts a force ‘mg” below and the physics engine tries to resolve this difference in forces and causes instability in the structure. So the key is a to leave a small gap in between
  2. Now that there is a gap between 2 rows the coefficient of restitution ‘e’ is made 0. Even a value as small as 0.1f can make the objects jitter and cause instability.
  3. The friction between the platform and the objects or the objects themselves is made maximum equal to 1.0f to prevent sliding of the objects.

// Add tumblers
for(int i=0; i < 21; i++) {
tumbler = new Sprite(80 + i * 25, 450, this.mTumblerTextureRegion, this.getVertexBufferObjectManager());
FIXTURE_DEF = PhysicsFactory.createFixtureDef(1f, 0.0f, 1f);
tumblerBody = PhysicsFactory.createBoxBody(this.mPhysicsWorld, tumbler, BodyType.DynamicBody, FIXTURE_DEF);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(tumbler, tumblerBody, true, true));
this.mScene.attachChild(tumbler);
}

// Add glasses
for(int i=0; i < 14; i++) {
glass = new Sprite(130 + i * 25, 428, this.mGlassTextureRegion, this.getVertexBufferObjectManager());
FIXTURE_DEF = PhysicsFactory.createFixtureDef(1f, 0.0f, 1f);
glassBody = PhysicsFactory.createBoxBody(this.mPhysicsWorld, glass, BodyType.DynamicBody, FIXTURE_DEF);
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(glass, glassBody, true, true));
this.mScene.attachChild(glass);
...
...

Hopefully if you get everything right you should have a stable structure. I had to do this through trial and error before I got it finally right. Whew!

Once you get a stable structure with the proper sprites in place most of the problem is solved. For the last part I add a bull sprite and set it off at a velocity from the point of touch.

bull = new Sprite(pX, pY, this.mBullTextureRegion, this.getVertexBufferObjectManager());
FIXTURE_DEF = PhysicsFactory.createFixtureDef(25f, 0.0f, 1f);
Log.d("here","here");
bullBody = PhysicsFactory.createBoxBody(this.mPhysicsWorld, bull, BodyType.DynamicBody, FIXTURE_DEF);
if(pX > 360)
bullBody.setLinearVelocity(-5,-5);
else
bullBody.setLinearVelocity(5,5);

DSC00031

Note: Since the sprites are not regular shapes I had to use a box shape. So the collisions are not pixel perfect.
Make sure you set up your project properly in Eclipse. The important settings are
Project->Properties->Android->Android4.2
Project->Properties->Java Compiler: Check the “Enable project specific setting” and also set compiler compliance level to 1.6
Finally click Project->Properties->Android: Under Library click ‘Add’ and add AndEngine and AndEnginePhysicsBox2DExtension
and you are good to go.

Here are 2 clips of Bull in a China Shop demo

1.Bull in a china shop in Earth’s gravity

2.Bull in a china shop in Moon’s gravity

You can clone the project from Github from Bulldozed

Have fun …

Other cool simulations using AndEngine & Box2D
1. Simulating the domino effect using Box2D and AndEngine
2. The making of Total Control Android game
3. Simulating a Web Joint in Android
4. Modeling a Car in Android
5. A closer look at “Robot horse on a Trot! in Android”

Find me on Google+

Simulating the domino effect in Android using Box2D and AndEngine

In this post I describe the steps to create a domino effect in Android. I have used Box 2D which is a physics game engine and AndEngine. The simulation is based on a demo in Java by Daniel Murphy in his site http://www.jbox2d.org/. There is a great tutorial on Box2D at http://www.iforce2d.net/b2dtut/introduction. Box2D is a really powerful 2D physics engine with collision detection, friction and restitution and all the good things of nature.

In this post I deal with some of the basic concepts of Box2D engine. At the most basic level is the ‘Body’. A body has linear,angular velocity,mass, location etc. It is then assigned a ‘shape’ which can be circle or polygon and finally we have assign the bodies to fixtures which carry properties of friction, restitution, density (density x area = mass), etc.

Finally all bodies are part of the ‘world’.
You can take a look at the domino effect in the video clip –  domino clip
The entire project can be cloned from GitHub at Dominoes

So for the domino effect I create floor,roof,left and right walls which are the shapes

//Create the floor

final VertexBufferObjectManager vertexBufferObjectManager = this.getVertexBufferObjectManager();

final Rectangle ground = new Rectangle(0, CAMERA_HEIGHT – 2, CAMERA_WIDTH, 2, vertexBufferObjectManager);

final Rectangle roof = new Rectangle(0, 0, CAMERA_WIDTH, 2, vertexBufferObjectManager);

final Rectangle left = new Rectangle(0, 0, 2, CAMERA_HEIGHT, vertexBufferObjectManager);

final Rectangle right = new Rectangle(CAMERA_WIDTH – 2, 0, 2, CAMERA_HEIGHT, vertexBufferObjectManager);

The body with the fixture is

final FixtureDef wallFixtureDef = PhysicsFactory.createFixtureDef(0, 0.5f, 0.5f);

PhysicsFactory.createBoxBody(this.mPhysicsWorld, ground, BodyType.StaticBody, wallFixtureDef);

PhysicsFactory.createBoxBody(this.mPhysicsWorld, roof, BodyType.StaticBody, wallFixtureDef);

PhysicsFactory.createBoxBody(this.mPhysicsWorld, left, BodyType.StaticBody, wallFixtureDef);

PhysicsFactory.createBoxBody(this.mPhysicsWorld, right, BodyType.StaticBody, wallFixtureDef);

Similarly I create 3 platforms on which I array vertical bricks.

The shape is created by creating a sprite.

platform1 = new Sprite(50, 100, this.mPlatformTextureRegion, this.getVertexBufferObjectManager());

The platform body is created as follows

platformBody1 = PhysicsFactory.createBoxBody(this.mPhysicsWorld, platform1, BodyType.StaticBody, FIXTURE_DEF);

The FIXTURE_DEF is the fixture which is defined as

privatestaticfinal FixtureDef FIXTURE_DEF = PhysicsFactory.createFixtureDef(50f, 0.1f, 0.5f);

where the parameters 50f,0.1f,0,5f correspond to density, coefficient of restitution and friction.

The platform is then added to the scene

this.mScene.attachChild(platform1);

I stack 37 vertical bricks on the platform

// Create 37 bricks

for(int i=0; i < 37; i++) {

brick = new Sprite(50 + i * 15, 50, this.mBrickTextureRegion, this.getVertexBufferObjectManager());

brickBody = PhysicsFactory.createBoxBody(this.mPhysicsWorld, brick, BodyType.DynamicBody, FIXTURE_DEF);

this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(brick, brickBody, true, true));

this.mScene.attachChild(brick);

brick.setUserData(brickBody);

}

I tilt the first few bricks to create the domino effect as follows

float angle = brickBody.getAngle();

Log.d(“Angle”,“angle:”+ angle);

// Tilt first 4 bricks

if (i == 0 || i == 1 || i == 2 || i == 3 || i == 4) {

brickBody.setTransform(120/PIXEL_TO_METER_RATIO_DEFAULT,80/PIXEL_TO_METER_RATIO_DEFAULT,(65 – (i*10)) * DEGTORAD);

}

Note: The PIXEL_TO_METER_RATIO_DEFAULT which divides the units.

I tried to make the end of the domino effect in the 1st platform trigger the domino effect in the 2nd which would trigger in the 3rd. However I could not make it happen consistently. So I trigger the domino effect in each of the 3 platforms by tilting the first few bricks.

Anyway it was good fun.

You can take a look at the domino effect in the domino clip

The entire project can be cloned from Dominoes

Take a look at some cool simulations using AndEngine & Box2D
1. Bull in a china shop – Behind the scenes in android
2. Creating a blob in Android using  Box2D physics Engine & AndEngine
3. The making of Total Control Android game
4. Simulating an Edge Shape in Android
5. Simulating a Web Joint in Android
6. Modeling a Car in Android
7. Fun simulation of a Chain in Android
8. “Is it animal? Is it an insect?” in Android
Find me on Google+

A Github Primer

This post gives some of the basic commands to get started on Git Hub. GitHub is the Open source source code management system that enables anybody to share code, projects, and work on other open source projects. The beauty of GitHub lies in its simplicity. A very good tutorial is given at Git Reference

I found that the using Git Hub on Linux command line is extremely simple and straight forward. This article gives the steps to push your project on to the Git Hub repository hosted on the web.

1) To get started create a GitHub account at https://github.com. Sign up for an account with your details.

2) On the GitHub page create a repository. This will be the icon next to your user account with a ‘+” sign. Let’s say I create a repository called ‘unity’

3) On Fedora Linux you can install git using the following command as root

$yum install git-core

4) Once git is installed it is a good idea to set your name and your email with commands below

$ git config –global user.name ‘tvganesh’
$ git config –global user.email tvganesh.85@gmail.com

5) Change to the directory which contains your project files .
cd unity

6) Setup for git using
git init
Initialized empty Git repository in /home/tvganesh/git/unity/.git/

7) You can check that Git has been initialized as follows which will show up a .git file
ls -a
. .. .git unity

8) Check the status of the git uodate with
git status -s
?? unity/

9) Add all the files and folders in your project directory recursively to the staging area with

git add .

10) Check that all the files & folders are in the staging area by checking the status again
git status -s
A unity/.classpath
A unity/.project
A unity/.settings/org.eclipse.jdt.core.prefs
A unity/AndroidManifest.xml
A unity/bin/jarlist.cache
A unity/ic_launcher-web.png
A unity/libs/android-support-v4.jar

The A shows that the files have been added to the staging area

11) A more detailed status check is below

[tvganesh@localhost unity]$ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
# (use “git rm –cached <file>…” to unstage)
#
# new file: unity/.classpath
# new file: unity/.project
# new file: unity/.settings/org.eclipse.jdt.core.prefs
# new file: unity/AndroidManifest.xml
# new file: unity/bin/jarlist.cache
# new file: unity/ic_launcher-web.png
# new file: unity/libs/android-support-v4.jar

12) Now commit the files to the local repository with the command below

git commit -m “Unity – Unit converter code”
[master (root-commit) aedab49] Unity – Unit converter code
39 files changed, 2068 insertions(+), 0 deletions(-)
create mode 100644 unity/.classpath
create mode 100644 unity/.project
create mode 100644 unity/.settings/org.eclipse.jdt.core.prefs
create mode 100644 unity/AndroidManifest.xml
create mode 100644 unity/bin/jarlist.cache

13) Check the status again which shows all files commmitted to the repository

git status
# On branch master
nothing to commit (working directory clean)

14) Create an alias for the remote GitHub repository
git remote add unity https://github.com/tvganesh/unity.git

15) Push your local repository to GitHub
git push unity master
Username:
Password:
Counting objects: 56, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (48/48), done.
Writing objects: 100% (56/56), 430.66 KiB, done.
Total 56 (delta 12), reused 0 (delta 0)
To https://github.com/tvganesh/unity.git
* [new branch] master -> master

Check github for update

16) If you have a README.md at Github while creating you may get the following error
To https://github.com/tvganesh/unity.git
! [rejected] master -> master (non-fast-forward)
error: failed to push some refs to ‘https://github.com/tvganesh/unity.git&#8217;
To prevent you from losing history, non-fast-forward updates were rejected
Merge the remote changes before pushing again. See the ‘Note about
fast-forwards’ section of ‘git push –help’ for details.

17) To fix this simply do

git pull unity master
git merge master

and then
git push unity master

16) Now check Git Hub you should see all your files in the repository you pushed to. You should see an exact replica

unity

17) You can clone an entire poject from GitHub using
git clone https://github.com/tvganesh/unity.git

<a href=”https://plus.google.com/103077316191161424665/?rel=author”>Find me on Google+</a>

The making of Dino Pong android game

DSC00016Dino Pong is my first android game from concept to completion. It is based on the android game engine AndEngine. This post gives the main hightights in the making of this fairly simple but interesting game.

Do take a look at my earlier post “Creating a simple android game using AndEngine” to understand how the basic game can be setup.

You can clone the entire project at Git Hub Dino Pong game

A video clip of Dino Pong in action can be seen here – Dino Pong clip

For the Dino Pong game I wanted the following

  1. 3 animated sprites that bounced off walls and moved with different velocities and paddle
  2. A DigitalOnScreenController that controls the paddle
  3. Collision detection between the paddle and the sprites and between the sprites themselves
  4. Points awarded for hitting a sprite with a paddle and points deducted for misses at the point of contact
  5. A game board showing hits, misses and the total score

So I created 3 animated sprites. Take a look at my earlier post on how to create an animated dino. So in the onCreateResources the 3 animated sprites and the paddle are created as below

Animated Sprites and paddle

// Create a ball

this.mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 64, 32, TextureOptions.BILINEAR);

this.mFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, “face_circle_tiled.png”, 0, 0, 2, 1);

this.mBitmapTextureAtlas.load();

// Create a bront

this.mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 160, 64, TextureOptions.BILINEAR);

this.mBrontTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, “bront2_tiled.png”, 0, 0, 5, 1); //

this.mBitmapTextureAtlas.load();

// Create a paddle

this.mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTOnCextureManager(), 90, 30, TextureOptions.BILINEAR);

this.mPaddleTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(this.mBitmapTextureAtlas, this, “paddle1.png”, 0, 0);

this.mBitmapTextureAtlas.load();

// Create a Box face

this.mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 64, 64, TextureOptions.BILINEAR);

this.mBoxFaceTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, “face_box_tiled.png”, 0, 0, 2, 1); // 64×32

this.mBitmapTextureAtlas.load();

In the onCreateScene the animated sprites and the paddle are added to the scene and attached to it as below

// Add ball to scene

finalfloat Y = (CAMERA_HEIGHTthis.mFaceTextureRegion.getHeight()) / 2;

ball = new Ball(X, Y, this.mFaceTextureRegion, this.getVertexBufferObjectManager());

scene.attachChild(ball);

// Add box to scene

finalfloat X1 = (CAMERA_WIDTHthis.mBoxFaceTextureRegion.getWidth()) / 2;

finalfloat Y1 = 270;

box = new Box(X1, Y1, this.mBoxFaceTextureRegion, this.getVertexBufferObjectManager());

scene.attachChild(box);

// Add paddle

finalfloat centerX = (CAMERA_WIDTHthis.mPaddleTextureRegion.getWidth()) / 2;

float centerY = 320;

paddle = new Sprite(centerX, centerY, this.mPaddleTextureRegion, this.getVertexBufferObjectManager());

final PhysicsHandler physicsHandler = new PhysicsHandler(paddle);

paddle.registerUpdateHandler(physicsHandler);

scene.attachChild(paddle);

// Create a shaking brontosaurus

finalfloat cX = (CAMERA_WIDTHthis.mBrontTextureRegion.getWidth())/2;

finalfloat cY = 50;

bront = new Bront(cX, cY, this.mBrontTextureRegion, this.getVertexBufferObjectManager());

bront.registerUpdateHandler(physicsHandler);

scene.attachChild(bront);

The paddle is registered with a physicsHandler. All the animated instances all register with the physicsHandler to be able to detect collisions.

DigitalOnScreenController for controlling paddle : For this game I have used a DigitalOnScreenController as opposed to the analog version. The digital controller seems to have a smoother movement and diagonal movements are disabled. The code for this taken from AndEngine examples.

// Add a digital on screen control

this.mDigitalOnScreenControl = new DigitalOnScreenControl(50, CAMERA_HEIGHTthis.mOnScreenControlBaseTextureRegion.getHeight() + 20, this.mCamera, this.mOnScreenControlBaseTextureRegion, this.mOnScreenControlKnobTextureRegion, 0.1f, this.getVertexBufferObjectManager(), new IOnScreenControlListener() {

@Override

publicvoid onControlChange(final BaseOnScreenControl pBaseOnScreenControl, finalfloat pValueX, finalfloat pValueY) {

physicsHandler.setVelocity(pValueX * 100, 0);

}

});

this.mDigitalOnScreenControl.getControlBase().setBlendFunction(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);

this.mDigitalOnScreenControl.getControlBase().setAlpha(0.5f);

this.mDigitalOnScreenControl.getControlBase().setScaleCenter(0, 128);

this.mDigitalOnScreenControl.getControlBase().setScale(1.25f);

this.mDigitalOnScreenControl.getControlKnob().setScale(1.25f);

this.mDigitalOnScreenControl.refreshControlKnobPosition();

scene.setChildScene(this.mDigitalOnScreenControl);

One of the thing I did was to disable vertical movements of the controlled object the paddle. Hence the physicsHandler sets the y value to ‘0’ as shown above

publicvoid onControlChange(final BaseOnScreenControl pBaseOnScreenControl, finalfloat pValueX, finalfloat pValueY) {

physicsHandler.setVelocity(pValueX * 100, 0);

}

Handling collisions :

As I mentioned above all the animated sprites (brontosaurus, face_circle & face_box) register with physics handler when the object is instantiated

privatestaticclass Bront extends AnimatedSprite {

privatefinal PhysicsHandler mPhysicsHandler;

floatx,y;

public Bront(finalfloat pX, finalfloat pY, final TiledTextureRegion pTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager) {

super(pX, pY, pTextureRegion, pVertexBufferObjectManager);

this.animate(100);

this.mPhysicsHandler = new PhysicsHandler(this);

this.registerUpdateHandler(this.mPhysicsHandler);

// Change the angle to the horizontal

this.mPhysicsHandler.setVelocity(BRONT_VELOCITY, BRONT_VELOCITY);

}

If the paddle misses the sprite then when the sprite collides with the bottom wall a point is deducted

if(this.mY < 0) {

this.mPhysicsHandler.setVelocityY(BRONT_VELOCITY);

//bText.setText(“”);

} elseif(this.mY + this.getHeight() + 80 > CAMERA_HEIGHT) {

x = this.getX();

y = this.getY();

bText.setPosition(x-10,y + 20);

bText.setText(“-1”);

misses = misses – 1;

score = score -1;

missesText.setText(“Misses: “+ misses);

scoreText.setText(“Score: “ + score);

Also the sprite is restarted from the top at the same ‘x’ coordinate

// At bottom. Restart from the top

this.setPosition(x, 0);

this.mPhysicsHandler.setVelocityY(-BRONT_VELOCITY);

The collision with the paddle, face_circle & face_box are checked here

if(paddle.collidesWith(this) || this.collidesWith(paddle)){

x = this.getX();

y = this.getY();

bText.setPosition(x+10,y+10);

bText.setText(“+1”);

hits = hits + 1;

score = score + 1;

float vx = this.mPhysicsHandler.getVelocityX();

float vy = this.mPhysicsHandler.getVelocityY();

this.mPhysicsHandler.setVelocity(-vx,-vy);

}

if(ball.collidesWith(this)){

float vx = this.mPhysicsHandler.getVelocityX();

float vy = this.mPhysicsHandler.getVelocityY();

this.mPhysicsHandler.setVelocity(-vx,-vy);

}

Similarly the collision checks are done for the other 2 sprites.

When the paddle successfuly hits a sprite the points are awarded at the point of contact

if(paddle.collidesWith(this) || this.collidesWith(paddle)){

x = this.getX();

y = this.getY();

bText.setPosition(x-10,y + 20);

bText.setText(“-1”);

The score is updated simulataneously for each hit or miss

hitsText.setText(“Hits: “+ hits);

scoreText.setText(“Score: “ + score);

hits = hits + 1;

score = score + 1;

Additional tweaks

  1. The size of the DigitalOnScreenController was shrunk by half as it seemed oversized for my Android phone

  2. A box is drawn within which the sprites can bounce off allowing space for the score at the bottom

final Line line1 = new Line(0, 0, 320, 0, 5, this.getVertexBufferObjectManager());

final Line line2 = new Line(320, 0, 320, 400, 5, this.getVertexBufferObjectManager());

final Line line3 = new Line(320, 400, 0, 400, 5, this.getVertexBufferObjectManager());

final Line line4 = new Line(0, 400, 0, 0, 5, this.getVertexBufferObjectManager());

// Add bounded rectangle to scene

scene.attachChild(line1);

scene.attachChild(line2);

scene.attachChild(line3);

scene.attachChild(line4);

  1. The velocities of the 3 sprites are made slightly different

  2. The x & y components of the velocity of the face_circle and face_box differ to enable a slightly different angle of motion.

A video clip of Dino Pong in action can be seen here – Dino Pong clip

You can clone the entire project at Git Hub  Dino Pong game

or the complete code can be downloaded at DinoPong.zip

Issues: One of the issues I see is that when the paddle hits the middle of any sprite then the sprite appears to get locked and does not bounce off. Sometimes 2 sprites also get into this ‘deadly embrace’ before getting themselves released. It appears that successive collisions happen before the velocity and position can be changed hence resulting in this lock up. Any ideas on fixing this are welcome.

Do let me know your thoughts on this game.

Find me on Google+

Creating a simple android game using AndEngine

IMG_8928AndEngine is the really cool android game engine developed by Nicolas Gramlich. This post gives the steps needed to create a simple android game using AndEngine. Please look at my previous post “Getting started with AndEngine” for details of downloading and configuring the AndEngine in your Eclipse environment.

Fortunately AndEngine comes with a lot of examples which are a good starting point for creating of a game. After you installed AndEngine on your phone do give the examples a try and understand their behavior. You should then be able to suitably mix & match different components for the game you need.

In my case as a start I wanted to develop a simple Pong game with a paddle and an animated sprite for the ball. So I checked out the following examples

  1. Drawing a Sprite – SpriteExample.java
  2. Removing a Sprite – SpriteRemoveExample.java
  3. Drawing Animated Sprites – AnimatedSpriteExample.java
  4. A Moving ball example – MovingBallExample.java
  5. Analog On Screen Control – AnalogOnScreenControlExample.java
  6. Collision Detection – CollisionDetectionExample.java

Once I was fairly familiar with the above examples I started by creating an Android Project from Eclipse. I next copied the entire contents of AnalogOnScreenControlExample .java to the /src folder in a file named Pong.java. I changed the package details and also the class name from AnalogOnScreenControlExample to Pong.

Once this is done you have to do the following steps which is very important

  1. Click Project->Properties->Java Compiler and chose “Enable project specific setting” and select 1.6
  2. Click Project->Properties->Android and select Android 4.2
  3. Click Project-> Properties->Android  and under Library click the Add button and select AndEngine as a library.

Managing a paddle with the AnalogOnScreenController

Since I wanted to move a Pong paddle instead of the sprite in the above example I downloaded a jpg file for the paddle and copied it to

/assets/gfx

You must also copy the onscreen_control_base.png and onscreen_control_knob.png to /assets/gfx folder.

Build and run you program by connecting your phone through a USB cable. You should see the on screen control and the paddle. For my game I did not need the rotary control so I removed it and only kept the control for handling the velocity of my paddle.

Once you have your basic code working you can add the other parts. For my game I needed the following

  1. Animated Sprite
  2. A moving animated sprite
  3. Collision detection of the sprite with the paddle

Animated Sprite: To create an animated sprite you have to create a tiled picture with slight variations of the image. I downloaded a jpg of a brontosaurus and used GIMP to tile the picture with 5 tiles. For this in GIMP choose Filters->Map-> and choose %. Unlink the Width & Height and set the Width to 500% and height to 100%. This will create 5 vertical adjacent tiles. Then I applied transform->shear to each individual tile so that in effect it will look like an animated dino.

One this png is created you will have to copy it to assets/gfx folders and use in onCreateResources()

this.mBitmapTextureAtlas = new BitmapTextureAtlas(this.getTextureManager(), 64, 160, TextureOptions.BILINEAR);

this.mBrontTextureRegion = BitmapTextureAtlasTextureRegionFactory.createTiledFromAsset(this.mBitmapTextureAtlas, this, “bront1_tiled.png”, 0, 0, 1, 5); //

this.mBitmapTextureAtlas.load();

This typically is animated as follows

bront = new AnimatedSprite(pX, pY, this.mBrontTextureRegion, this.getVertexBufferObjectManager());

bront.animate(200);

Creating a moving animated Sprite : For this I picked up the code from the MovingBallExample.java as follows and replaced the ball sprite with my bront sprite

final Bront bront = new Bront(cX, cY, this.mBrontTextureRegion, this.getVertexBufferObjectManager());

bront.registerUpdateHandler(physicsHandler);

scene.attachChild(bront);

….

privatestaticclass Bront extends AnimatedSprite {

public Bront(finalfloat pX, finalfloat pY, final TiledTextureRegion pTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager) {

super(pX, pY, pTextureRegion, pVertexBufferObjectManager);

this.animate(100);

Create a moving sprite For this I picked up the appropriate code from the MovingBallExample.java and massaged it a bit to handle my animated bront sprite

privatestaticclass Bront extends AnimatedSprite {

privatefinal PhysicsHandler mPhysicsHandler;

public Bront(finalfloat pX, finalfloat pY, final TiledTextureRegion pTextureRegion, final VertexBufferObjectManager pVertexBufferObjectManager) {

….

this.mPhysicsHandler = new PhysicsHandler(this);

this.registerUpdateHandler(this.mPhysicsHandler);

this.mPhysicsHandler.setVelocity(DEMO_VELOCITY, DEMO_VELOCITY);

}

@Override

protectedvoid onManagedUpdate(finalfloat pSecondsElapsed) {

if(this.mX < 0) {

this.mPhysicsHandler.setVelocityX(DEMO_VELOCITY);

} elseif(this.mX + this.getWidth() > CAMERA_WIDTH) {

this.mPhysicsHandler.setVelocityX(-DEMO_VELOCITY);

}

if(this.mY < 0) {

this.mPhysicsHandler.setVelocityY(DEMO_VELOCITY);

} elseif(this.mY + this.getHeight() > CAMERA_HEIGHT) {

this.mPhysicsHandler.setVelocityY(-DEMO_VELOCITY);

}

Handling collisions: To handle the collisions the code in CollisionDetectionExample.java comes handy. So the paddle which is controlled by the onScreenAnalogControl will detect collisions with the animated sprite as below

and reverses the velocity component on collision detection

@Override

protectedvoid onManagedUpdate(finalfloat pSecondsElapsed) {

….

if(paddle.collidesWith(this)){

float vx = this.mPhysicsHandler.getVelocityX();

float vy = this.mPhysicsHandler.getVelocityY();

this.mPhysicsHandler.setVelocity(-vx,-vy);

}

super.onManagedUpdate(pSecondsElapsed);

So thats about all. We have a basic pong game ready! The game definitely needs more enhancements which I propose to do in the coming days. Watch this space!

Checkout the video clip of the  Pong game in action.

You can download the code from Pong.zip


Find me on Google+

Getting started with AndEngine

And Engine is the Open Source Android 2D OpenGL Game Engine created by Nicolas Gramlich. This post gives the steps for getting started with this cool game engine if you are keen on developing killer games for the world.

If you are already developing in Android then you probably have Eclipse. The entire source code for AndEngine has been moved to the Github. So the first thing you need to do is to get the Eclipse Git plugin. To do this open Eclipse and select Help-> Install New Software and type in http://download.eclipse.org/egit/updates in the Work with text field and hit enter. You should see the following

egit

Since I was on Linux I chose only EGit. If you are on Windows you will also have to probably install the Win32 plugin. Once this installed close Eclipse and open it again. Now you will have to clone all the AndEngine’s code from Github. The site is AndEngine Site.

Now all the AndEngine source has to be cloned along with the set o AndEngine Examples from this site.

To do this select File->Import->Git->Projects From Git and click Next.

Select URI from the next screen and select Next.

In the Source Git Repository screen enter the URI for each of the AndEngine files and extensions as shown below

ae-2

Click Next. Choose all the default settings for all the next few screens. This will create a copy of the contents of the folders for each of the AndEngine code. Repeat the step for the AndEngine and all of its extensions

The list is as below

  1. AndEngine
  2. AndEngineAugmentedRealityExtension
  3. AndEngineLiveWallPaperExtension
  4. AndEngineMODPlayerExtension
  5. AndEngineMultiplayerExtension
  6. AndEnginePhysicsBox2DExtension
  7. AndEngineRobotiumExtension
  8. AndEngineScriptingExtension
  9. AndEngineScriptingExtensionGenerator
  10. AndEngineSVGTextureRegionExtension
  11. AndEngineTexturePackerExtension
  12. AndEngineTMXTiledMapExtension

Once you have cloned all of the above you will need to build each of them individually. Make sure you perform the following

  1. Select Project->Properties->Java Compiler. Check the ‘Enable project specific settings’ and choose compiler compliance level as 1.6
  2. Select Project->Properties->Android and choose Android 4.2 API level 17
  3. Select Project->Properties->Android, click Add button under Library and add AndEngine and other libaries AndEnginePhysicsBox2DExtension etc.

And then build the project. It should build cleanly. I did get some errors as mentioned below. A lot of time I clicked ‘Fix project’ or ‘organize imports’ and the issues went away. Anyway here are the main issues I faced

In AndEngineRobotiumExtension for the AndEngineSolo.java I had to fix the imports. The imports were erroneously showing up as org.anddev….. I had to replace it with the following

Replace

import org.anddev.andengine.engine.Engine;

import org.anddev.andengine.engine.camera.Camera;

import org.anddev.andengine.entity.IEntity;

import org.anddev.andengine.entity.IEntity.IEntityMatcher;

import org.anddev.andengine.input.touch.TouchEvent;

import org.anddev.andengine.input.touch.controller.ITouchController;

import org.anddev.andengine.ui.activity.BaseGameActivity;

import org.anddev.andengine.util.constants.Constants;

with

import org.andengine.ui.activity.*;

import org.andengine.engine.Engine;

import org.andengine.engine.camera.Camera;

import org.andengine.entity.IEntity;

import org.andengine.entity.*;

import org.andengine.input.touch.TouchEvent;

import org.andengine.input.touch.controller.ITouchController;

import org.andengine.ui.activity.BaseGameActivity;

import org.andengine.util.Constants;

After this clone AndEngineExamples and build as before. You will run into the following errors once you have fixed the imports. (If you are looking at this post a couple of months afterwards it is likely that these issues have been fixed and you do not need to worry about them)

Next there were couple of errors in the

TextBreakExample.java, line 106

BoundCameraExample.java, line 220 

SplitScreenExample.java, line 179

The fix for this is given in this link

http://www.andengine.org/forums/tutorials/andenine-examples-showing-error-t9883.html

I also had to fix an error where I had to replace IEntity.getChild() with IEntity.getChildByIndex() don’t recollect where it was

Finally I had to replace the following line with the line below. This is more of a hack

Replaced the line in TexturePackerExample.java

//final TexturePack spritesheetTexturePack = new TexturePackLoader(this.getTextureManager(), “gfx/spritesheets/”).loadFromAsset (this.getAssets().toString(), “texturepackerexample.xml”);

with this

final TexturePack spritesheetTexturePack = new TexturePackLoader(this.getAssets(),this.getTextureManager()).loadFromAsset (this.getAssets().toString(), “texturepackerexample.xml”);

At this point the build should be clean. To run the examples you will have to connect your android phone to the laptop using a USB cable. The AndEngine Examples do not work on the AVD.

I have to admit the AndEngine examples are really cool. Some clips are shown below

Filtering Collisions example

Using a Revolutejoint example

<a href=”https://plus.google.com/103077316191161424665/?rel=author”>Find me on Google+</a>

Train Spotting android app – Nuts and bolts

trainsplashTrainspotting Android app. This is my second android app from concept, design and finally to implementation. You can download this app from Google Play at Train Spotting.

In this post I discuss the details of the app threadbare. The app has all the usual goodies of android and uses the following features of Android

  • Tab Layout
  • List Layout with checkbox
  • Options Menu with add, delete and deleteAll options
  • Passing parameters between activities
  • Handling the checkbox
  • Using the assets folder
  • Alert dialog
  • Widgets like spinners, buttons, text fields etc

Actiity Flow

The picture below shows the flow between the different activities

ts-activity

Tab Layout

The app has 3 main tabs

  1. Favorites b) Locate Train c) Train At d) About.

Creating tabs is fairly straightforward

Create 3 tab xml files in the res/layout folder. The res/layout folder will also contain 3 xml files containing the icons that have to displayed when a tab is selected and when it not selected.

For the above 3 tabs the layout files are

  1. Favoritesa. Layout file – display.xml which is a list viewb. Icon file – favorites.xml
  2. Locatea. Layout file – locate_train.xml with spinners and buttonsb. Icon file – locate.xml3) About

a. Layout file – about.xml – Webview

b. Icon file – help.xml

For e.g.

display.xml has the following

<ListView xmlns:android=”http://schemas.android.com/apk/res/android&#8221;
android:id=”@android:id/list”
android:layout_width=”wrap_content”
android:layout_height=”match_parent” >

</ListView>

favorites.xml

?xml version=“1.0” encoding=“utf-8”?>

<selector xmlns:android=http://schemas.android.com/apk/res/android&#8221;>

<!– When selected, use grey –>

<item android:drawable=“@drawable/star”

android:state_selected=“true” />

<!– When not selected, use white–>

<item android:drawable=“@drawable/star_1” />

</selector>

To create the above tab layout the following needs to added to the MainActivity to create the 3 tabs

// Create 3 tabs. Favorites, Locate, About

TabHost tabHost = getTabHost();

// Favorite trains tab

TabSpec favspec = tabHost.newTabSpec(“Favorites”);

// setting Title and Icon for the Tab

favspec.setIndicator(“Favorites”, getResources().getDrawable(R.drawable.star));

Intent favoritesIntent = new Intent(this, displayTrains.class);

favspec.setContent(favoritesIntent);

// Locate Train tab

TabSpec locatespec = tabHost.newTabSpec(“Locate”);

locatespec.setIndicator(“Locate”, getResources().getDrawable(R.drawable.binoculars));

Intent locateIntent = new Intent(this, locateTrain.class);

locatespec.setContent(locateIntent);

// About Tab

TabSpec aboutspec = tabHost.newTabSpec(“About”);

aboutspec.setIndicator(“About”, getResources().getDrawable(R.drawable.help));

Intent aboutIntent = new Intent(this, about.class);

aboutspec.setContent(aboutIntent);

// Add TabSpec to TabHost

tabHost.addTab(favspec);

tabHost.addTab(locatespec);

tabHost.addTab(aboutspec);

 Screenshot with the tabsts_screen1

The app starts at the Main Activity and then immediately switches to the Favorites tab. This tab displays the current list of trains that the user has stored in the SQLiteDatabase.

Options Menu

The Favorites tab includes an Option Menu when the Options button on the device is pressed.

There are 3 options presented to the user

  1. Add b) Delete c) deleteAll

To create an Options Menu add the options to the res/menu folder as options_menu.xml

The contents of res/menu/options_menu.xml is as follows

<?xml version=“1.0” encoding=“utf-8”?>

<menu xmlns:android=http://schemas.android.com/apk/res/android&#8221;>

<item android:id=“@id/add”

android:icon=“@drawable/add”

android:title=“@string/add” />

<item android:id=“@id/delete”

android:icon=“@drawable/delete”

android:title=“@string/delete” />

<item android:id=“@id/deleteAll”

android:title=“@string/deleteAll”

android:icon=“@drawable/deleteall”/>

</menu>

This can be inflated in the Activity (displayTrains.java) as follows

publicboolean onCreateOptionsMenu(Menu menu) {

MenuInflater inflater = getMenuInflater();

inflater.inflate(R.menu.options_menu, menu);

returntrue;

}

When a user selects an option the on the OptionItemSelectedMenu is invoked. There are currently 3 actions that can be selected from the OptionsMenu

a) Add b) Delete c) DeleteAll

Add option : When this option is selected the addTrain activity is started to take user input for the train no and train name

publicboolean onOptionsItemSelected(MenuItem item) {

Intent intent;

int count;

SqlOpenHelper helper = new SqlOpenHelper(this);

ArrayList<String> r = new ArrayList<String>();

final Context context = this;

switch (item.getItemId()) {

case R.id.add:

// Switch to the addTrain Activity

intent = new Intent(context, addTrain.class);

startActivity(intent);

returntrue;

The delete and the deleteAll option are also invoked in a similar fashion from the Option Menu

case R.id.delete:

…..

returntrue;

case R.id.deleteAll:

….

}

returntrue;

default:

returnsuper.onOptionsItemSelected(item);

}

}

 Screen shot with the options menu

ts_screen21

Passing parameters between activities

Sending parameters from one activity to another (locateTrain.java)

In the LocateTrain activity when the user selects the ‘train no’ and the ‘day” for which to locate the train the WebView has to be invoked with the selected values for the train no and day. This is done as as follows. In the calling activity locateTrain

Intent intent = new Intent(context, trainAt.class);

//Setup to pass parameters to new activity

// Pass the train & the day to the trainAt Activity

Bundle b = new Bundle();

b.putString(“train”, train_tokens[0]);

b.putString(“day”, dayValue);

intent.putExtras(b);

startActivity(intent);

The values are put in the bundle ‘b’ and the the parameters are passed with the call

intent.putExtras(b). The intent is finally started with the trainAt activity.

The trainAt activity receives the passed parameters are received as follows

Receiving parameters (trainAt.java)

// Receive the passed parameters

Bundle b = getIntent().getExtras();

int trainNo = Integer.parseInt(b.getString(“train”).toString());

String value = b.getString(“day”).toString();

// Invoke the web with passed parameters

String url = “http://www.spoturtrain.com/status.php?tno=&#8221; + trainNo + “&date=” +value;

WebView myWebView = (WebView) findViewById(R.id.webview);

myWebView.loadUrl(url);

Handling delete of selected items

To handle deletion of selected trains from the listview the delete() method is called. The code and the explanation is given below

SqlOpenHelper helper = new SqlOpenHelper(this);

ArrayList<String> r = new ArrayList<String>();

ListView lv = getListView();

SparseBooleanArray a = new SparseBooleanArray();

the lv.getCheckedItemPositions() returns a sparse array which has the checked items set to true.

// Create a sparse array of checked positions

a = lv.getCheckedItemPositions();

The list is iterated and the rows which are checked are determines as below

// Determine the positions which are checked

for(int pos=0;pos<lv.getCount(); pos++){

//Log.d(“val”,”pos:”+ pos + ” ” + a.get(pos));

if(a.get(pos)){

// If item is checked add it to the items ArrayList

items.add(pos);

}

}

//Convert the integer ArrayList to an Integer Array

Integer[] itemArray = new Integer[ items.size() ];

items.toArray( itemArray );

//Delete all selected items from SQLiteDatabase by passing in the itemArray

A train array is created with the selected rows and passed to deleteTrains()

helper.deleteTrains(itemArray);

// Clear the ArrayList

items.clear();

After deleting the selected rows the ListView is again re-populated with the new list.

//Re-populate the list

r = populateResults();

listAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_multiple_choice,r);

this.setListAdapter(listAdapter);

listAdapter.notifyDataSetChanged();

lv = getListView();

lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);

Handling Cancel

As before the sparse array of checked items is obtained and each of them are set to false to uncheck them as below

// Get the checked positions in a Sparse Array

a = lv.getCheckedItemPositions();

for(int i=0;i<lv.getCount(); i++){

//Log.d(“val”,”i:”+ i + ” ” + a.get(i));

// Uncheck the checked positions

if(a.get(i)){

lv.setItemChecked(i, false);

}

}

// Clear the sparse Array. Clear the ArrayList

a.clear();

items.clear();

Using the assets folder

The About tab displays a Help file which is stored as a html in the

/assets folder.

To display the Web page, webview is used

publicclass about extends Activity {

publicvoid onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.about);

// Add the trainspot.html in assets/

WebView webView = (WebView) findViewById(R.id.trainspot);

webView.loadUrl(“file:///android_asset/trainspot.html”);

}

}

Creating an alert dialog

An alert dialog is fairly straightforward

AlertDialog.Builder builder = new AlertDialog.Builder(context);

Set the title of the dialog and the message to be displayed as below

// Set title

builder.setTitle(“Confirm delete”);

a = lv.getCheckedItemPositions();

// Set the dialog message

builder.setMessage(“Do you want to delete these ” + a.size() + ” items?”);

Add either ‘Yes’/’No’ or ‘OK’/’Cancel’ buttons and handle the actions accordingly

// Add the Yes & No buttons

builder.setPositiveButton(R.string.yes, new DialogInterface.OnClickListener() {

publicvoid onClick(DialogInterface dialog, int id) {

// User clicked Yes button

// Delete selected items

delete();

}

});

builder.setNegativeButton(R.string.no, new DialogInterface.OnClickListener() {

publicvoid onClick(DialogInterface dialog, int id) {

// User No the dialog

// Uncheck the checked items

uncheck();

dialog.cancel();

}

});

// Create the AlertDialog

AlertDialog dialog = builder.create();

// show it

dialog.show();

This post gives all the finer details of this interesting app. Do install it and give it a try.

A sample output is shown below

ts_screen41

You can clone the project from Github at Trainspotting or

The complete code of this app can be downloaded at trainspotting.zip

Happy train spotting!

You may also like
1. Unity (full) android app – With bells and whistles
2. The making of Dino Pong android game

Find me on Google+