RSS

Box2D Swipe Interaction

14 Dec


This tutorial will explain how to interact with Box2D objects by swiping. I wrote this tutorial in response to this thread on the cocos2d forums.

Note that this tutorial uses my TRBox2D wrapper. The TRBox2D class is a subclass of the CCSprite class which contains some convenience methods and the following objects:

    b2Body *body;
    b2Fixture *fixture;
 
    b2RevoluteJoint *revoluteJoint;
    b2PrismaticJoint *prismaticJoint;
    b2DistanceJoint *distanceJoint;
    b2MouseJoint *mouseJoint;
 
    int touchHash;

Preparation

Download the Box2DSwipe project from here. Once you’ve done that open up the project in Xcode and run it on the iOS Simulator. This should be the result:

You may notice that my screenshot above shows two circles. The big circle is the ball and the small circle is what I call the swipe body. The small circle only appears when you touch the screen. While your finger remains on the screen a Box2D mousejoint is constantly dragging the smaller circle towards your finger. Once you release your finger both the small circle and the mousejoint are destroyed.

How this project was made

  • The Box2DSwipe project was created from the standard cocos2d Box2D template.
  • The latest version of TRBox2D v0.5 was added the project. (direct link here).
  • HelloWorldLayer.h and HelloWorldLayer.mm were customised & heavily commented

HelloWorldLayer.h (Interface)

There’s not much exciting happening in the header file. Points of note are the import of the TRBox2D class and the addition of some variables to the interface. The code commenting should explain the variable purpose.

    TRBox2D *ground; // The ground body (used for limiting the world to the screen size)
    TRBox2D *ball;  // This is the physics body tied to a cocos2d sprite
    TRBox2D *swipe; // This is a small Box2D circle created when you put your finger on the screen

HelloWorldLayer.mm (Implementation)

The implementation is broken down into two main parts: Physics and Touch Events. The physics part I’ve explained in other tutorials so I will focus on the touch events.

The first thing you will notice in the TOUCH HANDLING section of the HelloWorldLayer.mm file is this method:

createSwipeBodyAtPosition:(CGPoint)position size:(float)size sprite:(NSString*)sprite angle:(float)angle

Now what that method does is simply return a little TRBox2D circle to whatever part of your code asked for it. When you call the method you can vary the size of the circle or even specify a sprite to show when the circle appears as well as the angle of the sprite. Note that the circle will only appear when you have Box2D debug mode on. You turn off debug mode by commenting out world->DrawDebugData(); in the draw method.

The rest of the methods in the TOUCH HANDLING section are standard cocos2d ones for handling touch events. For the sake of simplicity I stripped out multitouch handling that I use in iSoccer. If you’re interested in learning about that let me know and I might extend this tutorial.

Anyway we’ve used three cocos2d touch handling methods: ccTouchesBegan, ccTouchesMoved and ccTouchesEnded. The first thing I do in any of those methods is to sort through the touches and make two variables touchLocation and touchLocationInWorld. touchLocation is for the cocos2d sprite location and touchLocationInWorld is for the related Box2D body location.

  • The ccTouchesBegan method creates a swipe body if one doesn’t already exist and attaches a mousejoint to it.
  • The ccTouchesMoved method changes the target of the mousejoint to wherever you touched.
  • The ccTouchesEnded method destroys the swipe body and associated mouse joint.

That’s it!

If you liked this tutorial or found something wrong with it please let me know!

If you want to support my work and have an iPad please consider purchasing iSoccer *wink*

-Tim

Go to the Tutorials Index


Be Sociable, Share!
     

    About Tim Roadley

    I'm a senior analytics software consultant at eMite Pty Ltd primarily focused on delivering business intelligence dashboards, currently for one of Australia’s major banks. I'm also working on a revamped version of eMite's iOS App for release under iOS 7. Prior to eMite, I was Infrastructure Manager at Cuscal Pty Ltd where I was heavily involved in designing and implementing a payments switch that drives 1300+ ATM’s Australia wide. I have several apps on the App Store, including Teamwork, iSoccer and now Grocery Dude and Grocery Cloud. In my down time I enjoy spending time with my wonderful wife Tracey and two lovely children Tyler and Taliah.
    9 Comments

    Posted by on December 14, 2011 in iOS Tutorials

     

    9 Responses to Box2D Swipe Interaction

    1. Fede

      December 30, 2011 at 9:40 pm

      That is absolutely GREAT!!!!

      The multi touch gestures would be nice to have as an extension for this tutorial!

      Thank you so much for this incredible tutorial!

       
      • Tim Roadley

        December 31, 2011 at 7:04 am

        Glad you liked it, that’s a great idea for the next tutorial :) I’ll write that up in a couple of weeks when I return to work!

         
      • Tim Roadley

        January 16, 2012 at 8:49 am

        Glad you like them, I may just add them soon now that my holidays are over ;-)

         
    2. Manraj

      January 3, 2012 at 5:28 am

      Hi there, your tutorials are brilliant, but a quick question, how do you incorporate your swipe classes that you wrote so that you actually can flick the ball rather than you pushing the ball around. For example, the ball is stationary to begin with, one you have swipe the ball in the direction, and you remove the finger off the screen, the ball then flicks/ moves to that direction you swiped?

      Kind regards

       
      • Tim Roadley

        January 3, 2012 at 6:52 am

        That sounds like it would need a totally different approach entirely, without using mouse joints at all.

        First you would have to track the start and end points of the line being drawn via touchesbegan and touchesended.

        When you have those points the distance between the points would be used to determine the power of the hit.

        The direction of the line would determine trajectory.

        With all that worked out I would then fire a method that creates a b2_kinematic body, moves it from the start point to the end point at a specific speed using box2d’s setlinearvelocity commands

        The b2_kinematic body should then also be destroyed when it reaches the end point.

        Alternatively you could just applylinearvelocity directly to a point on the ball, which is probably a better way to go.

        Does that help?

         
    3. vaseem

      May 9, 2012 at 3:13 pm

      HI Tim.
      I m very thankful to write a very good templet .I have port your game templet in c++.CAN U WRITE TRBOX2D IN C++.
      It will be very helpful for development cocos2d-x.

       
      • Tim Roadley

        May 12, 2012 at 7:45 am

        My C++ skill isn’t good enough to write that I’m afraid, I wrote the wrapper to stop me having to use C++ ;)

         
    4. Roberto

      May 18, 2012 at 6:25 am

      Hi Tim

      Can you please send me the multitouch part of the code so I can learn how to deal with that ? I have tried so much things but the apple docs are complicated for me.

      Thanks in advance

       

    Leave a Reply