Wednesday, January 16, 2013

Blob with an attitude (stiffness) in Android


DSC00044This post is an enhanced version of my earlier blob post Creating a blob in Android using Box2D physics engine and AndEngine. To introduce stiffness 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
You can clone the project from Github at Blob_v1

Tuesday, January 15, 2013

Creating a Blob in Android using Box2D physics engine & AndEngine


DSC00037Here is a short post on my attempt to create a Blob using Box2D physics engine and AndEngine. This demo tries to recreate the Blob Joint at GwtBox2D Showcase. This Blob Joint demo in Java uses a ConstantVolume Joint for creating the Blob. For my blob I use a distanceJoint for maintaining the shape of the Blob.
A Blob is created in the initial shape of an ellipse as follows
// Add 20 circle bodies around an ellipse
for (int i=0; iFIXTURE_DEF = PhysicsFactory.createFixtureDef(30f, 0.5f, 0.5f)
Vector2 v1 = new Vector2(x1,y1);
final VertexBufferObjectManager vb = this.getVertexBufferObjectManager();
circle[i] = new AnimatedSprite(x1, y1, this.mCircleFaceTextureRegion, this.getVertexBufferObjectManager());
circleBody[i] = PhysicsFactory.createCircleBody(this.mPhysicsWorld, circle[i], BodyType.DynamicBody, FIXTURE_DEF);
...
}
A distance Joint is created between every body as follows
// Create a distanceJoint between every other day
for(int i= 0;i < nBodies-1; i++) {
for(int j=i+1; j 0) {
connectionLine[i] = new Line(centers[i][0],centers[i][1],centers[i-1][0],centers[i-1][1],lineWidth,this.getVertexBufferObjectManager());
connectionLine[i].setColor(0.0f,0.0f,1.0f);
this.mScene.attachChild(connectionLine[i]);
}
// Join the first body with the last body
if(i == 19){
connectionLine[0] = new Line(centers[0][0],centers[0][1],centers[19][0],centers[19][1],lineWidth,this.getVertexBufferObjectManager());
connectionLine[0].setColor(.0f,.0f,1.0f);
this.mScene.attachChild(connectionLine[0]);
}
The connecting lines move along with the moving shapes as below
// Update connection line so that the line moves along with the body
this.mPhysicsWorld.registerPhysicsConnector(new PhysicsConnector(circle[i], circleBody[i], true, true) {
@Override
public void onUpdate(final float pSecondsElapsed) {
super.onUpdate(pSecondsElapsed);
for(int i=1;i < nBodies;i++) {
connectionLine[i].setPosition(circle[i].getX(),circle[i].getY(),circle[i-1].getX(),circle[i-1].getY());
} connectionLine[0].setPosition(circle[0].getX(),circle[0].getY(),circle[19].getX(),circle[19].getY());
}
}
);
So here is the clip of the blob in action : Blob clip
You can clone the project from Github from the Blob code

Friday, January 11, 2013

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 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
  1. Project->Properties->Android->Android4.2
  2. Project->Properties->Java Compiler: Check the “Enable project specific setting” and also set compiler compliance level to 1.6
  3. 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
You can clone the project from Github from Bulldozed
Have fun...

Wednesday, January 9, 2013

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'.
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

Thursday, January 3, 2013

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 ..." 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'
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