Cool Box2D stuff with Appcelerator Titanium

I happened upon the Appcelerator Open Mobile Marketplace the other day, and started looking through the modules.  One that caught my eye was the Box2D module.  Earlier this year, we’d been dabbling with Cocos2d which is a game engine for iPhone, which uses Box2D as one of the physics engine you could use inside it.

Box2D is an open source library originally written in C that has been ported to Flash, Java, C++, Objective C and is widely popular in the game community.  It’s not a huge stretch to see a Ti module adaptor being placed over the Objective C code, also nice because it should perform well.

I had a million and one things to do, so of course I dropped them all to see just what this shiny new bauble could do.  Right now the module is in beta and there’s zero documentation, so the best thing is to check out some examples like pinball or a Hello World (more or less), and peek at the Objective C source code for a couple proxy classes, like Body and World.

Running the example from the github repository, you get a square and a ball that basically start at the top of the screen and fall down (and off) the screen.

Objects fall from top of screen and then off bottom of screen

Here’s the code with no floor:

  1. var window = Ti.UI.createWindow();
  2. var view = Ti.UI.createView();
  3. window.add(view);
  4. window.open();
  5.  
  6. // load the module
  7. var Box2D = require(‘ti.box2d’);
  8.  
  9. // create the world, using view as the surface
  10. var world = Box2D.createWorld(view);
  11.  
  12. // create a block
  13. var redBlock = Ti.UI.createView({
  14.     backgroundColor: "red",
  15.     width: 50,
  16.     height: 50,
  17.     top: 0
  18. });
  19.  
  20. var blueBall = Ti.UI.createView({
  21.     backgroundColor: "blue",
  22.     borderRadius: 15,
  23.     width: 30,
  24.     height: 30,
  25.     top: 100
  26. });
  27.  
  28. // add the block body to the world
  29. var redBodyRef = world.addBody(redBlock, {
  30.     density: 12.0,
  31.     friction: 0.3,
  32.     restitution: 0.4,
  33.     type: "dynamic"
  34. });
  35.  
  36. // add the ball body to the world
  37. var blueBodyRef = world.addBody(blueBall, {
  38.     radius: 15,
  39.     density: 12.0,
  40.     friction: 0.3,
  41.     restitution: 0.4,
  42.     type: "dynamic"
  43. });
  44.  
  45. Ti.Gesture.addEventListener(‘orientationchange’, function(e) {
  46.     if (e.orientation == Titanium.UI.LANDSCAPE<em>LEFT) {
  47.         world.setGravity(9.91, 0);
  48.     } else if (e.orientation == Titanium.UI.LANDSCAPE</em>RIGHT) {
  49.         world.setGravity(-9.91, 0);
  50.     } else if (e.orientation == Titanium.UI.UPSIDE_PORTRAIT) {
  51.         world.setGravity(0, 9.91);
  52.     } else if (e.orientation == Titanium.UI.PORTRAIT) {
  53.         world.setGravity(0, -9.91);
  54.     }
  55. });
  56.  
  57. world.addEventListener("collision", function(e) {
  58.     if ((e.a == redBodyRef || e.b == redBodyRef) &amp;&amp; e.phase == "begin") {
  59.         Ti.API.info("the red block collided with something");
  60.         Ti.API.info(JSON.stringify(e));
  61.         Ti.Media.vibrate();
  62.     }
  63. });
  64.  
  65. // start the world
  66. world.start();

To get a floor for these objects to land on, I added this:

With Floor

Square now lands on top of ball on the floor

  1. // create a ground level for things to hit
  2. var floor = Ti.UI.createView({
  3.         backgroundColor:‘#fff’,
  4.         width:310,
  5.         height:2,
  6.         bottom:40
  7. });
  8.  
  9. var b = world.addBody(floor, {
  10.         density:12.0,
  11.         friction:0.3,
  12.         restitution:0.4,
  13.         type:‘static’
  14. });

But then I wanted to see if the objects would tumble down a hill, so the floor needed to have an angle to it.  This is where examining the implementation of the World proxy object came in handy.  the world.addBody(aBody) function returns a handle to the body it added.  With that in hand, you can then apply methods from the Body proxy object implementation, and there happens to be one in there named setAngle(someDegree). That led to this code:

Angled Floor

ball bounces, then rolls down hill. Square tumbles a bit and then comes to rest

  1. var b = world.addBody(floor, {
  2.         density:12.0,
  3.         friction:0.3,
  4.         restitution:0.4,
  5.         type:‘static’
  6. });
  7.  
  8. b.setAngle(85);

Lastly, I wanted to see if I could put up a wall that would let the ball bounce off the floor, roll down and then be stopped by the intersection of the wall and floor.  Here’s how:

And a Wall

ball has bounced off the wall and rolled back up the floor a bit

  1. // create a wall
  2. var leftWall = Ti.UI.createView({
  3.         backgroundColor:‘#fff’,
  4.         width:2,
  5.         height:200,
  6.         bottom:0,
  7.         left:0
  8. });
  9.  
  10. world.addBody(leftWall, {
  11.         density:12.0,
  12.         friction:0.3,
  13.         restitution:0.4,
  14.         type:‘static’
  15. });

I’m looking forward to playing with Box2D module in more detail, maybe over Christmas break.  Hope you gained a little insight into its workings in Titanium Appcelerator.

13 thoughts on “Cool Box2D stuff with Appcelerator Titanium

  1. Nice writeup. Since the information on this module is pretty sparse when applied directly to titanium, it’s nice to see posts that show some basic examples.

    Have you done any additional work on this?

  2. A lot can be done with Box2D for Titanium, even with the limitations of the current module. I have a game in the App Store called Bead Frenzy, which was written with Titanium using the Box2D module.

    If I had one big tip it would be the collision event listener and getting access to data. The event listener is setup like the following:

    world.addEventListener(“collision”, function(e) {
    if(e.phase == ‘begin’){
    if(e.a.view.objectType == ‘ball’ && e.b.view.objectType == ‘holder’){
    //do stuff
    }
    }
    });

    The collision event happens when a body collides with another body. The event will pass an A and B object, which are the two objects that collided. You can then get access to the view attached to that object as you see by .view

    This makes it easy to attach any amount of data you want pertaining to that object by using properties on the view. After I figured this out, it made it a lot easier determining which objects actually collided.

  3. Thanks

    i was just looking at the collision stuff, and i had wondered what a and b represented.

    Any further info you have or document resources would be great, im keen to help the community with box2d it seems like it has great potential

  4. Hey guys

    ive managed to make a simple game where you shoot objects and they dissapear.
    However i have a memory issue I’ve looked everywhere in forums and through box2D documentation but i cant seem to be able to remove the box2d body objects and views from memory
    i thought the destroyBody function would do it , but it doesnt . In the xCode profiler they stay in memory

    Any ideas?

    its driving me insane

    • My suspicion is that the memory is tied to the underlying view that the box2d body is built on. While destroyBody gets rid of the Box2d object, does it also get rid of the underlying view? If not, that’s where I bet the problem is.

      • I too think that however I can’t seem to use the remove(); I’ve contacted module support and they emailed me today ad said that it may be a bug and they will look into it.

  5. Pingback: A Simple Box2D Tutorial | Titaniummm

  6. Just to I form everyone about my memory issue

    I’ve spoken to module support they have confirmed there is an issue in the module and will be fixing it in an update

  7. Can you help me how to move object left or right using ti.Boz2D module ? I don’t want to use quicktigame2d module.

    • No, I’ve not looked at Box2d in awhile. This would probably be better directed at the general Ti Appcelerator forums.

  8. Pingback: This Week in Titanium Mobile Development: 27 Dec 2011 | TiDev

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>