How-To: 2D Physics with Box2D

Basic Tutorials concerning: GUI, Views, Activites, XML, Layouts, Intents, ...

Postby MickArea » Fri Mar 20, 2009 5:34 pm

hey, you did a great job !

but unfortunately we have always garbage collector ...
i can't imagine making a game now with physics :'( .

But we are in the good path !
MickArea
Junior Developer
Junior Developer
 
Posts: 23
Joined: Mon Feb 23, 2009 4:42 pm

Top

Postby lphpc » Tue Mar 24, 2009 3:23 am

Yes, there are a lot of garbage collector when the test is running.

Also, The tests run slowly, espicially the Pyramid test which have many objects.

I have no idea about optimization now.

Any good ideas?
lphpc
Freshman
Freshman
 
Posts: 3
Joined: Fri Mar 20, 2009 5:53 am

Postby lphpc » Fri Mar 27, 2009 3:53 am

Some discussion about box2d port of android. And a patch is available.

http://www.box2d.org/forum/viewtopic.ph ... 94&start=0
lphpc
Freshman
Freshman
 
Posts: 3
Joined: Fri Mar 20, 2009 5:53 am

Postby DarkNSF » Thu May 21, 2009 12:27 am

Seems to compile fine, but I get a NullPointerException (from an InvocationTargetException) when it makes a call to bodies[count].method

It adds 50 balls, then tries to access index position 50 (via 'count') when it should only be 49. That aside, if I comment out the code I still see no physics objects. Any ideas?


Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.     public void update() {
  3.  
  4.         // Update Physics World
  5.  
  6.         world.step(timeStep, iterations);
  7.  
  8.        
  9.  
  10.         // Print info of latest body
  11.  
  12.         if (count > 0) {
  13.  
  14.             Vec2 position = bodies[count].getPosition();
  15.  
  16.             float angle = bodies[count].getAngle();
  17.  
  18.             Log.v("Physics Test", "Pos: (" + position.x + ", " + position.y + "), Angle: " + angle);
  19.  
  20.         }
  21.  
  22.     }
  23.  
  24.  
Parsed in 0.033 seconds, using GeSHi 1.0.8.4
Valhalla Studios LLC
http://www.Valhalla-Studios.com
DarkNSF
Freshman
Freshman
 
Posts: 2
Joined: Thu May 21, 2009 12:16 am

Postby DarkNSF » Thu May 21, 2009 12:56 am

I've never really coded on hardware like this so maybe there was a reason that we were using Body[]. Using an ArrayList really cleaned up the code in my opinion..


Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. import android.app.Activity;
  2.  
  3. import android.os.Bundle;
  4.  
  5. import android.os.Handler;
  6.  
  7.  
  8.  
  9. public class Thom extends Activity
  10.  
  11. {
  12.  
  13.     PhysicsWorld theWorld;
  14.  
  15.     private Handler theAndroidHandler;
  16.  
  17.  
  18.  
  19.     @Override
  20.  
  21.     public void onCreate(Bundle savedInstanceState)
  22.  
  23.     {
  24.  
  25.         super.onCreate(savedInstanceState);
  26.  
  27.         theWorld = new PhysicsWorld();
  28.  
  29.         theWorld.create();
  30.  
  31.  
  32.  
  33.         // Add 50 Balls
  34.  
  35.         for (int i=0; i<50; i++)
  36.  
  37.         {
  38.  
  39.             theWorld.addBall();
  40.  
  41.         }
  42.  
  43.  
  44.  
  45.         // Start Regular Update
  46.  
  47.         theAndroidHandler = new Handler();
  48.  
  49.         theAndroidHandler.post(update);
  50.  
  51.     }
  52.  
  53.  
  54.  
  55.     @Override
  56.  
  57.     protected void onPause()
  58.  
  59.     {
  60.  
  61.         super.onPause();
  62.  
  63.         theAndroidHandler.removeCallbacks(update);
  64.  
  65.     }
  66.  
  67.  
  68.  
  69.     private Runnable update = new Runnable()
  70.  
  71.     {
  72.  
  73.         public void run()
  74.  
  75.         {
  76.  
  77.             theWorld.update();
  78.  
  79.             theAndroidHandler.postDelayed(update, (long) (PhysicsWorld.TIME_STEP*1000));
  80.  
  81.         }
  82.  
  83.     };
  84.  
  85. }
Parsed in 0.035 seconds, using GeSHi 1.0.8.4



Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1. import java.util.ArrayList;
  2.  
  3. import java.util.List;
  4.  
  5.  
  6.  
  7. import org.jbox2d.collision.AABB;
  8.  
  9. import org.jbox2d.collision.CircleDef;
  10.  
  11. import org.jbox2d.collision.PolygonDef;
  12.  
  13. import org.jbox2d.common.Vec2;
  14.  
  15. import org.jbox2d.dynamics.Body;
  16.  
  17. import org.jbox2d.dynamics.BodyDef;
  18.  
  19. import org.jbox2d.dynamics.World;
  20.  
  21.  
  22.  
  23. import android.util.Log;
  24.  
  25.  
  26.  
  27. /**
  28.  
  29.  *
  30.  
  31.  *
  32.  
  33.  */
  34.  
  35. public class PhysicsWorld
  36.  
  37. {
  38.  
  39.         /** */
  40.  
  41.     public static int TARGET_FPS = 40;
  42.  
  43.    
  44.  
  45.     /** */
  46.  
  47.     public static int TIME_STEP = (1000 / TARGET_FPS);
  48.  
  49.    
  50.  
  51.     /** */
  52.  
  53.     private int theIterations = 5;
  54.  
  55.  
  56.  
  57.     /** */
  58.  
  59.     private List<Body> theBodies = new ArrayList<Body>();
  60.  
  61.    
  62.  
  63.     /** */
  64.  
  65.     private World theWorld;
  66.  
  67.  
  68.  
  69.     /**
  70.  
  71.      *
  72.  
  73.      */
  74.  
  75.     public void create()
  76.  
  77.     {
  78.  
  79.         // Step 1: Create Physics World Boundaries
  80.  
  81.         AABB worldAabb = new AABB();
  82.  
  83.         worldAabb.lowerBound.set(new Vec2((float) -100.0, (float) -100.0));
  84.  
  85.         worldAabb.upperBound.set(new Vec2((float) 100.0, (float) 100.0));
  86.  
  87.        
  88.  
  89.         // Step 2: Create Physics World with Gravity
  90.  
  91.         Vec2 gravity = new Vec2((float) 0.0, (float) -10.0);
  92.  
  93.         theWorld = new World(worldAabb, gravity, true);
  94.  
  95.        
  96.  
  97.         // Step 3: Create Ground Box
  98.  
  99.         BodyDef groundBodyDef = new BodyDef();
  100.  
  101.         groundBodyDef.position.set(new Vec2((float) 0.0, (float) -10.0));
  102.  
  103.         Body groundBody = theWorld.createBody(groundBodyDef);
  104.  
  105.         PolygonDef groundShapeDef = new PolygonDef();
  106.  
  107.         groundShapeDef.setAsBox((float) 50.0, (float) 10.0);
  108.  
  109.         groundBody.createShape(groundShapeDef);
  110.  
  111.     }
  112.  
  113.  
  114.  
  115.     /**
  116.  
  117.      *
  118.  
  119.      */
  120.  
  121.     public void addBall()
  122.  
  123.     {
  124.  
  125.         // Create Dynamic Body
  126.  
  127.         BodyDef bodyDef = new BodyDef();
  128.  
  129.         bodyDef.position.set((float) 6.0+theBodies.size(), (float) 24.0);
  130.  
  131.         Body newBody = theWorld.createBody(bodyDef);
  132.  
  133.        
  134.  
  135.         // Create Shape with Properties
  136.  
  137.         CircleDef circle = new CircleDef();
  138.  
  139.         circle.radius = (float) 1.8;
  140.  
  141.         circle.density = (float) 1.0;
  142.  
  143.        
  144.  
  145.         // Assign shape to Body
  146.  
  147.         newBody.createShape(circle);
  148.  
  149.         newBody.setMassFromShapes();
  150.  
  151.  
  152.  
  153.         theBodies.add(newBody);    
  154.  
  155.     }
  156.  
  157.    
  158.  
  159.     /**
  160.  
  161.      *
  162.  
  163.      */
  164.  
  165.     public void update()
  166.  
  167.     {
  168.  
  169.         // Update Physics World
  170.  
  171.         theWorld.step(TIME_STEP, theIterations);
  172.  
  173.        
  174.  
  175.         // Print info of latest body
  176.  
  177.         if (!theBodies.isEmpty())
  178.  
  179.         {
  180.  
  181.             Vec2 position = theBodies.get(theBodies.size()-1).getPosition();
  182.  
  183.             float angle = theBodies.get(theBodies.size()-1).getAngle();
  184.  
  185.             Log.v("Physics Test", "Pos: (" + position.x + ", " + position.y + "), Angle: " + angle);
  186.  
  187.         }
  188.  
  189.     }
  190.  
  191. }
Parsed in 0.047 seconds, using GeSHi 1.0.8.4
Valhalla Studios LLC
http://www.Valhalla-Studios.com
DarkNSF
Freshman
Freshman
 
Posts: 2
Joined: Thu May 21, 2009 12:16 am

Postby Stevos » Wed Mar 24, 2010 3:22 pm

Thanks for the interesting tutorial, I've been desperate to get a physics library running on Android, but sadly no luck with anything so far.

With the posted code on the linked site, I get a force close (as does one of the other commenters on that article.)

My android debugging skills are not good yet, but from repeatedly running and commenting out sections, I have narrowed it down to a call to

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2. bodies[count] = world.createBody(bodyDef);
  3.  
  4.  
Parsed in 0.035 seconds, using GeSHi 1.0.8.4


in the addball() method. I can't narrow it down more than that yet.

Does anyone else get anything like this?
Stevos
Freshman
Freshman
 
Posts: 8
Joined: Wed Mar 24, 2010 3:17 pm

Top

Postby mikezs » Thu May 06, 2010 10:57 am

Has anyone actually run this and checked the output? When I put logging on, the first (my only) ball seems to move to (6.0,1.8 ) and stays there in a single tick. Should this happen? Shouldn't it be at (6.0,11.8 ) where it collides with the groundbox?

I'm just trying to get started and the lack of info coming out is a bit rubbish!
mikezs
Freshman
Freshman
 
Posts: 2
Joined: Thu May 06, 2010 10:54 am

Postby mikezs » Fri May 07, 2010 12:45 pm

So... I solved my own problem

Code: Select all
public int timeStep = (1000 / targetFPS);

should be:
Code: Select all
public float timeStep = (1.0f / targetFPS);
mikezs
Freshman
Freshman
 
Posts: 2
Joined: Thu May 06, 2010 10:54 am

Re: How-To: 2D Physics with Box2D

Postby Schermvlieger » Wed Oct 27, 2010 2:02 pm

Hi all,

I've started playing around with this today and have a problem; the call to world.update() does not actually update the object's x,y positions. addBall() takes it's x,y positions from the onTouch event.

The parameters I use are:

Code: Select all
World.create() {
worldAABB = new AABB();
// Step 2: Create Physics World with Gravity
Vec2 gravity = new Vec2((float) 0.0, (float) -10.0);
boolean doSleep = true;
world = new World(worldAABB, gravity, doSleep);
groundBodyDef = new BodyDef();
groundBodyDef.position.set(new Vec2((float) 0.0, (float) -10.0));
Body groundBody = world.createBody(groundBodyDef);
groundShapeDef = new PolygonDef();
groundShapeDef.setAsBox((float) 50.0, (float) 10.0);
groundBody.createShape(groundShapeDef);
}


and for the object:

Code: Select all
public void addBall(float x, float y) {
// Create Dynamic Body
BodyDef bodyDef = new BodyDef();
bodyDef.position.set(x, WORLD_H - y);
Body newBody = world.createBody(bodyDef);
// Create Shape with Properties
CircleDef circle = new CircleDef();
circle.radius = (float) 1.8;
circle.density = (float) 1.0;
// Assign shape to Body
newBody.createShape(circle);
newBody.setMassFromShapes();
myBodies.add(newBody);
// Increase Counter
count += 1;
}
Schermvlieger
Senior Developer
Senior Developer
 
Posts: 159
Joined: Fri Feb 26, 2010 1:37 pm

Re: How-To: 2D Physics with Box2D

Postby Schermvlieger » Wed Oct 27, 2010 4:14 pm

Okay problem solved, the world's lowerbound and upperbound values were not set.


The performance is horrible though ... I wonder how games like Angry Birds are handling their physics, must be in c code ...
Schermvlieger
Senior Developer
Senior Developer
 
Posts: 159
Joined: Fri Feb 26, 2010 1:37 pm

Top
Previous

Return to Novice Tutorials

Who is online

Users browsing this forum: No registered users and 11 guests