How To Make A Game Like Fruit Ninja With Box2D and Cocos2D – Part 1

This is a post by iOS Tutorial Team Member Allen Tan, an iOS developer and co-founder at White Widget. You can also find him on Google+ and Twitter. In this tutorial, you’ll learn how to make a sprite cutting game for the iPhone similar to Fruit Ninja by Halfbrick Studios using the powerful Cocos2D and […] By Allen Tan.

Leave a rating/review
Save for later
Share
You are currently viewing page 2 of 3 of this article. Click here to view the first page.

Planning our Fruits

Before creating classes for our fruits, you need to be clear on the rules that the images and their shapes have to follow. Since you will be mapping our textures to single Box2D polygons, you must also adhere to Box2D's polygon limitations. You need to keep two things in mind:

  • Polygons must be convex, meaning that no interior angle is greater than 180.
  • Polygons must not exceed 8 vertices.

You can actually work around this limitation if you allow each body to contain multiple shapes. Box2D can handle concave shapes if you use a triangulation method and make the concave shapes out of several triangles, but this is beyond the scope of the tutorial.

To keep things simple, in this tutorial you will have a 1 Body is to 1 Shape rule.

Note: PhysicsEditor, the tool we will be covering later in this tutorial, actually contains code to automatically triangulate polygons you draw into a set of convex shapes. However, like I said we're trying to keep things simple here so will make sure to draw our shapes convex so we only have one shape per body.

Take a look at these two fruits:

Concave vs Convex

Using the Banana is not a good idea because it is naturally concave. The Watermelon on the other hand is very good because you can define a convex polygon that closely resembles its shape.

If you were to define polygon shapes that follow Box2D's rules for the two fruits, you would more or less end up with these:

Box2D Shape Outline

The Watermelon polygon fits the image perfectly, while the Banana polygon has a big empty space where the image curves inward. Box2D will treat that space as part of our object, and it might make the Banana feel unnatural when it collides with other objects, or when it gets cut.

This doesn't mean that you can't use the Banana, but rather that it is just not recommended to use the Banana. In fact, the game that you will be creating in this tutorial will use this same Banana.

Creating the First Fruit

It's time to create the first fruit: the Watermelon (a slice of it at least).

Thinking back to the flow of our PolygonSprite's initialization process, you know that initWithTexture expects a Box2D body, but the step before, initWithFile, does not provide this.

The reason for this is that you need to be creating and defining the body individually per fruit, so it will have to be the very first step, initWithWorld, that creates the body and sets any other values specific to each fruit.

To create our Box2D body, you must first know the vertices of the polygon shape you want to create. There are different ways to do this, but for this tutorial, you will be using a nifty tool called PhysicsEditor. This tool is filled with features, but you will only be using it to guide us in getting the coordinates of the vertices of our polygon.

If you don't have it, download PhysicsEditor, install it, and fire it up. You will get a blank project with 3 panels/columns.

Working with PhysicsEditor is pretty straightforward. On the left, you put all the images you want to work with. On the middle, you visually define a polygon for your image. On the right, you have the parameters for the body.

Physics Editor!

Grab watermelon.png from the Images folder of the resource kit and drag it to the left panel. You should now see the Watermelon on the center panel.

Increase the magnification, found at the bottom of this panel, to a comfortable level, and then tap on the Pentagon Button on the upper part of this panel to create a 3-sided polygon shape.

Right-Click on the polygon and choose "Add Vertex" until you have 5-8 vertices in all. Move the vertices around the edges of the Watermelon, while making sure of two things:

  • The Polygon you are creating is Convex.
  • All the pixels of the Watermelon are inside the Polygon.

Note: Another shortcut to draw the shapes is to use PhysicsEditor's magic wand tool. Just set the tolerance high (5-8) so that you end up with about 5-8 points, and tweak the points from there.

Add in all the other fruits and the bomb image from the Images folder of the resource kit and do the same thing for them.

You should be defining shapes for the following images:

  • banana.png
  • bomb.png
  • grapes.png
  • pineapple.png
  • strawberry.png
  • watermelon.png

When you're finished, on the upper right corner, change the value of Exporter to "Box2D generic (PLIST)", and you should end up with something like this:

Define Shapes Easily with PhysicsEditor!

Hit "Publish", or "Publish As", to export the PLIST file containing the vertex information. Save the file as fruits.plist.

As an example, the fruits.plist you used for this tutorial is inside the Misc folder of the resource kit.

You only want to look at the information contained in the PLIST file, so do not add this file to your project, but rather, just open fruits.plist using Xcode to view its contents in an organized manner.

Click on the triangle icon beside "bodies" to expand this section and you will see the list of images that you defined shapes for. You need to drill down to the deepest level to get the Watermelon's polygon vertices like so:

The PhysicsEditor PLIST

Expand watermelon/fixtures/Item 0/polygons and you should now see another Item 0 of Type Array under polygons. This last array is your shape. If you had properly defined a convex shape with 8 or less vertices, you should only see one array under polygons.

If you see more than one, i.e Item 0 Array, Item 1 Array, etc, then it means PhysicsEditor made a complex shape because you either defined too many vertices, or you formed a concave polygon. If this happens, go back to PhysicsEditor and fix your shape.

Next, expand the Item 0 of type Array to see the final list of items. These are your vertices, and the value you see at the right side with this format { number, number } are your x & y coordinates for each vertex.

Now that you have the exact values for your polygon's vertices, you can proceed with creating the Watermelon class.

In Xcode, create a new file with the iOS\cocos2d v2.x\CCNode Class template. Make it a subclass of PolygonSprite and name it Watermelon. Open Watermelon.h and make the following changes:

// Add to top of file
#import "PolygonSprite.h"

Switch to Watermelon.m, rename it to Watermelon.mm, and add the following init method:

// Add inside the @implementation
-(id)initWithWorld:(b2World *)world
{
    int32 count = 7;
    NSString *file = @"watermelon.png";
    b2Vec2 vertices[] = {
        b2Vec2(5.0/PTM_RATIO,15.0/PTM_RATIO),
        b2Vec2(18.0/PTM_RATIO,7.0/PTM_RATIO),
        b2Vec2(32.0/PTM_RATIO,5.0/PTM_RATIO),
        b2Vec2(48.0/PTM_RATIO,7.0/PTM_RATIO),
        b2Vec2(60.0/PTM_RATIO,14.0/PTM_RATIO),
        b2Vec2(34.0/PTM_RATIO,59.0/PTM_RATIO),
        b2Vec2(28.0/PTM_RATIO,59.0/PTM_RATIO)
    };
    CGSize screen = [[CCDirector sharedDirector] winSize];
    
    b2Body *body = [self createBodyForWorld:world position:b2Vec2(screen.width/2/PTM_RATIO,screen.height/2/PTM_RATIO) rotation:0 vertices:vertices vertexCount:count density:5.0 friction:0.2 restitution:0.2];
    
    if ((self = [super initWithFile:file body:body original:YES]))
    {
        // We will initialize more values for the fruit here later
    }
    return self;
}

In the above code, you first define how many vertices there are, which in this case is 7. Next, you create an array of vertices containing all the coordinates you just saw in the PLIST. You use this information to create a body using the convenience method you defined in PolygonSprite.

You put in a little friction so that the shapes don't slide endlessly, and you also put in a little restitution so that shapes don't stop when they bounce against each other.

Last, you create the object by calling the superclass' initialization and pass in the name of the image file, the Box2D body, and state that this is an original fruit.

You need the watermelon images from the resource kit, so now would be a good time to just add all the graphic resources you need for the rest of the tutorial.

In your Project Navigator panel, right-click on Resources and select "Add Files to CutCutCut". Add the Images folder from the resource kit to the project. Make sure that "Copy items into destination group's folder" is checked and "Create groups for any added folders" is selected.

Follow the same steps to create Banana, Grapes, Pineapple, Strawberry, and Bomb.

You only tackled how to create the first fruit step by step since it is basically a rinse & repeat process for each fruit. The resource kit contains ready-made fruit and bomb classes in the Classes folder for you to look at in case you still need guidance, or you can add them all to your project if you want to skip this step.

Compile and run, and make sure everything is fine.

Allen Tan

Contributors

Allen Tan

Author

Over 300 content creators. Join our team.