Simulating an Edge Shape in Android

Here is a small post on how I managed to simulate an Edge Shape in Android. I wanted to do this after I saw the Java demo of Box2D in JBox2D(see RayCast). For the Edge Shape I chose a cosine curve. I used the same method I used, mentioned in my earlier post “Making of the Total Control Android Game

The simulation can be seen at Simulating an Edge Shape on YouTube
You can clone the entire project from Github at EdgeShape.

Since it is a cosine curve I place a ball shape for every point on a cosine function, close to each other to seem continuous and create a body from the Sprite with physical properties.

for (int i = 0; i < nBodies; ++i)

{

float angle = (float) ((10.0 * PI * i)/180.0);

float y1 = 300 + (float)Math.cos(angle/20) * 120;

//Log.d(“Test”,”Test” + “x:” + x1 +”y:”+ y1);

circles[i] = new Sprite(x1, y1, this.mBallTextureRegion, this.getVertexBufferObjectManager());

circlesBody[i] = PhysicsFactory.createCircleBody(this.mPhysicsWorld, circles[i], BodyType.StaticBody, FIXTURE_DEF);

this.mScene.attachChild(circles[i]);

x1 = (float) (x1 + 0.5);

}

So this can be done for every mathematical curve. I also intended to create other curves like the Archimedes Spiral and the Lemniscate. Maybe I will leave that for a rainy day!! 🙂

However, I am not sure how to create a irregular edge shape. I will probably figure that out.

The egde shape is made to be a STATIC_BODY. I then took code of creating Animated Sprites at the point where I touch from AndEngine examples (PhysicsExample.java). To make the simulation more fun I also added a Linear Impulse to the Animated Sprite.

face = new AnimatedSprite(pX, pY, this.mCircleFaceTextureRegion, this.getVertexBufferObjectManager());

body = PhysicsFactory.createCircleBody(this.mPhysicsWorld, face, BodyType.DynamicBody, gameFixtureDef);

face.animate(200);

body.applyLinearImpulse(-200,200,pX,pY);

The effect is better if the phone is horizontal to the ground and not so great if the phone is kept vertical and the bodies do not seem to shoot off.

The simulation can be seen at Simulating an Edge Shape

You can clone the entire project from Github at EdgeShape.


Take a look at some cool simulations using AndEngine & Box2D
1. Simulating the domino effect using Box2D and AndEngine
2. Blob with an attitude(stiffness) in Android
3. The making of Total Control Android game
4. Simulating a Web Joint in Android
20. A closer look at “Robot horse on a Trot! in Android”
and many more …
Find me on Google+

Blob with an attitude in Android

DSC00044This post is an enhanced version of my earlier blob post Creating a blob in Android with Box2D physics engine and AndEngine.. To introduce tautness to the overall blob structure I used revoluteJoint between adjacent bodies as follows

}

// Create a revoluteJoint between adjacent bodies – Lacks stiffness

for( int i = 1; i < nBodies; i++ ) {

final RevoluteJointDef revoluteJointDef = new RevoluteJointDef();

revoluteJointDef.initialize(circleBody[i], circleBody[i-1], circleBody[i].getWorldCenter());

revoluteJointDef.enableMotor = false;

revoluteJointDef.motorSpeed = 0;

revoluteJointDef.maxMotorTorque = 0;

this.mPhysicsWorld.createJoint(revoluteJointDef);

}

// Create a revolute joint between first and last bodies

final RevoluteJointDef revoluteJointDef = new RevoluteJointDef();

revoluteJointDef.initialize(circleBody[0], circleBody[19], circleBody[0].getWorldCenter());

revoluteJointDef.enableMotor = false;

revoluteJointDef.motorSpeed = 0;

revoluteJointDef.maxMotorTorque = 0;

this.mPhysicsWorld.createJoint(revoluteJointDef);

The motorSpeed, maxMotorTorque is set to 0 and the enableMotor is set to false. However I found that this joint still lacks stiffness.

So I replaced the revoluteJoint with the weldJoint which is probably more appropriate

// Create a weldJoint between adjacent bodies – Weld Joint has more stiffness

for( int i = 1; i < nBodies; i++ ) {

final WeldJointDef weldJointDef = new WeldJointDef();

weldJointDef.initialize(circleBody[i], circleBody[i-1], circleBody[i].getWorldCenter());

this.mPhysicsWorld.createJoint(weldJointDef);

}

// Create a weld joint between first and last bodies

final WeldJointDef weldJointDef = new WeldJointDef();

weldJointDef.initialize(circleBody[0], circleBody[19], circleBody[0].getWorldCenter());

this.mPhysicsWorld.createJoint(weldJointDef);

Here are clips of the the Blob with more attitude

Blob with attitude – Part 1

Blob with attitude – Part 2

You can clone the project from Github at Blob_v1

Find me on Google+

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+

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+

Android soup with SQLiteDatabase, ListActivity and Options Menu

Have some Android soup made with SQLiteDatabase, ListActivity and Options Menu as ingredients! In this latest encounter with Android I create a small database that holds a list of Train numbers and names. The contents of this list is displayed to the user. The user is also given a menu to “add”, “delete” and “deleteAll” the records.

To get started I create a SqlOpenHelper class which extends the SQLiteOpenHelper. This class has the methods to create the SQLiteDatabase.

publicvoid onCreate(SQLiteDatabase db) {

createDatabase(db);

}

publicvoid createDatabase(SQLiteDatabase db) {

//Create TRAIN_TABLE

String CREATE_TRAIN_TABLE = “CREATE TABLE IF NOT EXISTS ” +

TRAINS_TABLE + “(” + TRAIN_ID + ” INTEGER PRIMARY KEY,” +

TRAIN_NO + ” INTEGER , ” + TRAIN_NAME + ” TEXT” + “)”;

Log.d(“Creating: ” , CREATE_TRAIN_TABLE);

db.execSQL(CREATE_TRAIN_TABLE);

}

Besides there are methods to

1) To add a train record

// Add a train method

publicvoid addTrain(int trainNo,String trainName) {

SQLiteDatabase db = this.getWritableDatabase();

ContentValues values = new ContentValues();

values.put(TRAIN_NO, trainNo);

values.put(TRAIN_NAME, trainName);

// Insert a new row

db.insert(TRAINS_TABLE, null, values);

db.close(); // Closing database connection

}

2) To delete a train record

// Delete a single train

publicvoid deleteTrain(Train train) {

SQLiteDatabase db = this.getWritableDatabase();

db.delete(TRAINS_TABLE, TRAIN_ID + ” = ?”,

new String[] { String.valueOf(train.getID()) });

db.close();

}

and to display all the trains in the database. The entire list is returned as a List.

3) Display all trains

// Getting all trains in SQLiteDB

public List<Train> getAllTrains() {

//Create a List

List<Train> trainList = new ArrayList<Train>();

// Create the “Select query”

String selectQuery = “SELECT * FROM ” + TRAINS_TABLE;

//Open the DB in read mode

SQLiteDatabase db = this.getReadableDatabase();

Cursor cursor = db.rawQuery(selectQuery, null);

// loop through all rows and add trains to the List

if (cursor.moveToFirst()) {

do {

Train train = new Train();

train.setID(Integer.parseInt(cursor.getString(cursor.getColumnIndex(TRAIN_ID))));

train.setTrainNo(cursor.getString(cursor.getColumnIndex(TRAIN_NO)));

train.setTrainName(cursor.getString(cursor.getColumnIndex(TRAIN_NAME)));

// Adding contact to list

trainList.add(train);

} while (cursor.moveToNext());

}

//Close DB

db.close();

// return the train list

return trainList;

}

To get started the DB has to be created with the following method in the MainActivity class

SqlOpenHelper helper = new SqlOpenHelper(this);

//Open SQLiteDB

db = this.openOrCreateDatabase(“train_no.db”, MODE_PRIVATE, null);

After creating the DB the MainActivity switches to the displayTrains activity which display the current list of of trains in the DB as follows.

 list

SqlOpenHelper helper = new SqlOpenHelper(this);

int count = helper.getTrainCount();

Log.d(“Count:”, “value =” + count);

results = populateResults();

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

this.setListAdapter(listAdapter);

The list is displayed by creating displayTrains as a ListActivity using the simple_list_item_1

In order to provide a add,delete & deleteAll function I added an Options Menu. To do this create an Option Menu in XML under res/menu

<menuxmlns: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 is then inflated in displayTrains activity in which I wanted the Options Menu to appear as follows

publicboolean onCreateOptionsMenu(Menu menu) {

MenuInflater inflater = getMenuInflater();

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

returntrue;

}

Icons for the Options Menu have to added in the drawable folder.

options

For some reason icons do not show up in my ADT but when I debugged on my phone it shows.

When the Add Option is clicked it takes it to the addTrains activity which inputs the Train Number & Train Name. The user is then given the option to save.

add

This returns the activity to display Trains where the entire list is redisplayed.

The delete option was a little tricky. The selected record is deleted as follows

helper.deleteTrain(selectedItem);

where the selectedItem selects a row in which we have to determine the trainID and delete the record with that ID. This is done as below

publicvoid deleteTrain(Train train) {

SQLiteDatabase db = this.getWritableDatabase();

db.delete(TRAINS_TABLE, TRAIN_ID + ” = ?”,

new String[] { String.valueOf(train.getID()) });

db.close();

}

After deleting the record from the DB the list has to be refreshed. I repopulate the listAdapter and pass it to the ListActivity as bwlow. I am not sure if this is the most efficient methid.

r = populateResults();

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

this.setListAdapter(listAdapter);

listAdapter.notifyDataSetChanged();

Finally the deleteAll deletes all the records in the DB as shown below

publicvoid deleteAllTrains() {

SQLiteDatabase db = this.getWritableDatabase();

db.delete(TRAINS_TABLE, null, null);

db.close();

}

This was some fun. The entire code can be downloaded at DB.zip

Find me on Google+

Unity(full) android App: With bells and whistles

In this post I discuss a fairly complete Android App – Unity which is a simple unit converter. The android app has all the good stuff from Android including activities, intents, spinners, launch icons and a splash screen to boot as below. Download it from Google Play : Unity – Unit Converter . To know more about the app read on …

compasses

I have enhanced my earlier basic Unity app to start with a Splash Screen before moving onto an initial screen with buttons for various unit conversion like mass,length,volume etc

This is shown below

unity-1

When any of these buttons are clicked it goes to the appropriate conversion screen. This is done by starting the appropriate activity. An activity is invoked by the intent which starts the activity.

Hence the MainActivity.java has an intent and activity for each of the buttons mass,length,volume in the addListenerOnButton as follows

publicvoid addListenerOnButton() {

//Mass activity

massButton = (Button) findViewById(R.id.button1);

massButton.setTextAppearance(context,R.style.ButtonFontStyle);

massButton.setOnClickListener(new OnClickListener() {

publicvoid onClick(View arg0) {

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

startActivity(intent);

}

});

//Length activity

lengthButton = (Button) findViewById(R.id.button2);

lengthButton.setTextAppearance(context,R.style.ButtonFontStyle);

lengthButton.setOnClickListener(new OnClickListener() {

publicvoid onClick(View arg0) {

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

startActivity(intent);

}

});

When the “Mass button” is clicked it activates a new intent based on the massActivity.java class.

The massActivity.java file performs the following main functions

  1. Changes the layout to the one defined in mass.xml under res/layout.mass.xml
  2. Instantiates a massAdapter as an ArrayAdapter
  3. Passes the massAdapter to both the spinners in the View
  4. A convert method is invoked when the Convert button is clicked. This method does the actual calculation
  5. Finally a ‘Home’ button is used to go back to the MainActivity class

publicclass massActivity extends Activity {

String[] massUnits = {“gram”,“kilogram”,“ounce”,“pound”,“ton”};

//double massConversion[][] = new double[5][5];

doublemassConversion[][] = newdouble [][]{

{1.0,0.001,3.527e-2,2.205e-3,1.102e-6},

{1000.0,1.0,35.27,2.205,1.102e-3},

{28.35,28.38e-2,1,6.25e-2,3.125e-5},

{453.6,0.4536,16.0,1.0,.0005},

{9.072e-5,907.2,3.2e4,2000.0,1}

};

protectedvoid onCreate(Bundle savedInstanceState) {

ArrayAdapter<String> massAdapter = new ArrayAdapter<String> (this,

android.R.layout.simple_spinner_item,massUnits);

sp1 = (Spinner) findViewById(R.id.spinner1);

sp1.setAdapter(massAdapter);

sp1.setOnItemSelectedListener(new OnItemSelectedListener() {

publicvoid onItemSelected(AdapterView<?> argo0, View arg1,

int arg2, long arg3) {

intitem = sp1.getSelectedItemPosition();

}

publicvoid onNothingSelected(AdapterView<?> arg0) {

}

});

sp2 = (Spinner) findViewById(R.id.spinner2);

sp2.setAdapter(massAdapter);

sp2.setOnItemSelectedListener(new OnItemSelectedListener() {

publicvoid onItemSelected(AdapterView<?> argo0, View arg1,

int arg2, long arg3) {

intitem = sp2.getSelectedItemPosition();

/

}

});

}

publicvoid convert(View view) {

double inputValue = Double.parseDouble(text1.getText().toString());

int item1 = sp1.getSelectedItemPosition();

int item2 = sp2.getSelectedItemPosition();

double value = massConversion[item1][item2];

double convertedValue = inputValue * value;

txtConvertedValue.setText(String.valueOf(convertedValue));;

}

The Home button takes back to the Main screen

publicvoid home(View view) {

final Context context = this;

Intent intent = new Intent(context,

MainActivity.class);

startActivity(intent);

}

The mass.xml screen has 1 Textfield for input, a TextView for output, 2 spinners for handling the fromUnit & toUnit and a Convert & a Home button. The mass.xml is shown below

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

android:layout_width=“fill_parent”

android:layout_height=“fill_parent” >

<TableRow

android:id=“@+id/tableRow1”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content” >

<TextView

android:id=“@+id/textView1”

android:layout_width=“wrap_content”

android:layout_height=“wrap_content”

android:layout_column=“0”

android:layout_span=“4”

android:text=“@string/massConversion”

android:textAppearance=“?android:attr/textAppearanceMedium” />

</TableRow>

<TableRow

<TextView

android:id=“@+id/textView2”

/>

<EditText

android:id=“@+id/editText1”

android:inputType=“numberDecimal” />

</TableRow>

<TableRow

<TextView

android:id=“@+id/textView3”

android:text=“@string/convertedValue” >

<TextView

android:id=“@+id/txtConvertedValue”>

</TableRow>

<TableRow

android:id=“@+id/tableRow5”

<Spinner

android:id=“@+id/spinner1”>

</TableRow>

<TableRow

android:id=“@+id/tableRow6”

<Spinner

android:id=“@+id/spinner2”>

</TableRow>

<TableRow

android:id=“@+id/tableRow11>

<Button

android:onClick=“convert”

android:text=“@string/Convert” />

<Button

android:onClick=“home”

android:text=“@string/home” />

</TableRow>

</TableLayout>

unity-5

Note: Ensure that you add this new activity massActivity to AndroidManifest.xml

As shown

<application

<activity

android:name=”com.example.test.massActivity”

android:label=”@string/app_name” >

</activity>

</application>

</manifest>

Similar code can be replicated for the other buttons and other conversion units.

Once this is done your application is ready. It is now time to create a suitable “icon” for your android app. I found GIMP utility extremely useful in creating icons. GIMP cam be downloaded from http://www.gimp.org. This requires some learning ramp-up. So I took the easy route and downloaded ready made icon from OpenClipArt.org which has a huge collection of icons.

The specified dimensions for the icons based on the resolution of the android device is given in http://developer.android.com/guide/practices/ui_guidelines/icon_design_launcher.html

and should be

  • Low density screens (ldpi): 36x36px, 120dpi
  • Medium density screens (mdpi): 48x48px, 160dpi
  • High density screens (hdpi): 72x72px, 240dpi
  • Extra high density screens (xdpi): 96x96px, 320dpi

Copy all the icons to the directory below and rename the png files to ic_launcher.png

  • Low density icon : res/drawable-ldpi
  • Medium density icon : res/drawable-mdpi
  • High density icon : res/drawable-hdpi
  • Extra high density icon : res/drawable-xdpi

WhenyoubuildandruntheapponyouremulatoryoushouldseeyouriconinsteadofthestandardAndroidicon.

It is worth mentioning a problem that I faced initially and had me stumped. I would make some changes and get the error “R cannot be resolved to a variable”.

AftertryingtounsuccessfullycleanandrebuildtheprojectseveraltimesItriedtodiginmore.MysearchwithGoogleprovedfutilewithsomepostscomplainingthatEclipsewasclobberingfiles.TheissueusuallyhappenswhentheR.javafilecannotbegeneratedwhenyoubuildtheproject.Thisusuallyhappenswhenthereissomeissueinyour /resdirectory.Checkifthereareanyredmarksinyourlayout,strings.xmlorAndroidManifest.xmletcfile, fixthem, rebuild and theproblemshouldgoaway.

Finally I added an initial splash screen. For this I took the code from O’Reilly’s cook book “Splash screens in Android”. A splash *.jpg or *.png has to be added to the res/drawable folders

Remember to change the AndroidManifest.xml to have the app open up with the splash screen and then switch the MainActivity.java.

A snippet is shown below

<activity

android:name=“com.tvganesh.unity.SplashScreen”

android:noHistory=“true”

android:label=“@string/app_name” >

<intent-filter>

<action android:name=“android.intent.action.MAIN” />

<category android:name=“android.intent.category.LAUNCHER” />

</intent-filter>

</activity>

<activity

android:name=“com.tvganesh.unity.MainActivity”

android:label=“@string/app_name” >

</activity>

<activity

android:name=“com.tvganesh.unity.massActivity”

android:label=“@string/app_name” >

</activity>

….

With this app is also set to rock ‘n roll. I also managed to submit the app to Google Play. To publish in Google Play you need to do the following

  1. Create a signed app package. For this right click the package, select Android Tools->Export Signed Application Package and follow the prompts. Upload the *.apk file in Google Play
  2. You will also need 2 screenshots of the app & a 512×512 icon.

And you should be through.

The Unity project can be cloned from Git Hub at Unity project or

The entire Unity – Unit converter app can be downloaded at Unity-Unit Converter

Find me on Google+