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

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. This is the second part of a tutorial series that shows you how to make a sprite cutting game similar to the game Fruit Ninja by Halfbrick […] By Allen Tan.

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

Exit Debug Mode

You're certain that the Box2D part works as expected, so you won't be needing debug drawing anymore.

Still in HelloWorldLayer.mm, make the following changes:

// Comment these out from the draw method
ccDrawLine(_startPoint, _endPoint);
world->DrawDebugData();

// Add inside the init method
[self initBackground];

// Add this method
-(void)initBackground
{
    CGSize screen = [[CCDirector sharedDirector] winSize];
    CCSprite *background = [CCSprite spriteWithFile:@"bg.png"];
    background.position = ccp(screen.width/2,screen.height/2);
    [self addChild:background z:0];
}

Compile and run, and you should see the neat background Vicki made for this tutorial.

Monkey Forest

Visualizing The Swipe Using CCBlade

Without debug drawing, you need a new way to show the swipes. The CCBlade effect made by Ngo Duc Hiep is a perfect replacement.

Download CCBlade, extract it, and hit Option+Command+A in Xcode and add CCBlade.m and CCBlade.h to your project. Make sure that "Copy items into destination group's folder" is checked and "Create groups for any added folders" is selected.

CCBlade is maintained by a third party, so the version may differ with what this tutorial uses if it is updated. You can get the exact version of CCBlade the tutorial uses in the Classes folder of the resource kit.

You need to update CCBlade for Cocos2D 2.X, so go to CCBlade.m, rename it to CCBlade.mm, and make the following changes:

// Replace everything starting from glDisableClientState in the draw method with this
CC_NODE_DRAW_SETUP();

ccGLBlendFunc( CC_BLEND_SRC, CC_BLEND_DST );

ccGLBindTexture2D( [_texture name] );    
glVertexAttribPointer(kCCVertexAttrib_Position, 2, GL_FLOAT, GL_FALSE, sizeof(vertices[0]), vertices);
glVertexAttribPointer(kCCVertexAttrib_TexCoords, 2, GL_FLOAT, GL_FALSE, sizeof(coordinates[0]), coordinates);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 2*[path count]-2);

// Add inside the initWithMaximumPoint method
self.shaderProgram = [[CCShaderCache sharedShaderCache] programForKey:kCCShader_PositionTexture];

// Remove from the setWidth method
* CC_CONTENT_SCALE_FACTOR()

// Remove from the push method
if (CC_CONTENT_SCALE_FACTOR() != 1.0f) {
    v = ccpMult(v, CC_CONTENT_SCALE_FACTOR());
}

You made the same conversions to the drawing code as you did for PRFilledPolygon before, and removed the scale multiplier from the code since the shader program handles this now.

CCBlade populates a path array with points, and draws a textured line across those points. Right now, it updates this array in the draw method. However, it is recommended that you only do drawing calls in the draw method, and do everything else in the update method.

To better manage the path array, you will update it in HelloWorldLayer's update method.

Go to CCBlade.h and add the following inside the @interface:

@property(nonatomic,retain)NSMutableArray *path;

Switch to CCBlade.mm and add the following inside the @implementation:

@synthesize path;

Next, switch to HelloWorldLayer.h and make these changes:

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

// Add inside the @interface
CCArray *_blades;
CCBlade *_blade;
float _deltaRemainder;

// Add after the @interface
@property(nonatomic,retain)CCArray *blades;

Finally, switch to HelloWorldLayer.mm and make the following changes:

// Add inside the @implementation
@synthesize blades = _blades;

// Add inside dealloc
[_blades release];
_blades = nil;

// Add inside init, after _raycastCallback
_deltaRemainder = 0.0;
_blades = [[CCArray alloc] initWithCapacity:3];
CCTexture2D *texture = [[CCTextureCache sharedTextureCache] addImage:@"streak.png"];

for (int i = 0; i < 3; i++)
{
    CCBlade *blade = [CCBlade bladeWithMaximumPoint:50];
    blade.autoDim = NO;
    blade.texture = texture;
    
    [self addChild:blade z:2];
    [_blades addObject:blade];
}

// Add inside update, right after [self checkAndSliceObjects]
if ([_blade.path count] > 3) {
    _deltaRemainder+=dt*60*1.2;
    int pop = (int)roundf(_deltaRemainder);
    _deltaRemainder-=pop;
    [_blade pop:pop];
}

// Add inside ccTouchesBegan
CCBlade *blade;
CCARRAY_FOREACH(_blades, blade)
{
    if (blade.path.count == 0)
    {
        _blade = blade;
        [_blade push:location];
        break;
    }
}

// Add inside ccTouchesMoved
[_blade push:location];

// Add inside ccTouchesEnded
[_blade dim:YES];

You make a property for the path array so you can access it from HelloWorldLayer. You then create 3 interchangeable CCBlades to be used in the game. For each blade, you set it with 50 maximum points so they don't become too long, and assign a streak texture that should already be in your Resources folder.

You set each blade's autoDim variable to NO. CCBlade uses the term "Dim" to mean that the blade effect should fade from the tail end towards the head by popping points out of the array one by one. With this, CCBlade automatically removes points from the path array.

This is quite convenient, but since CCBlade does its auto-popping feature inside its draw method, it's better to set this to NO and control the dimming ourselves in the update method.

When the player touches the screen, you assign an unused CCBlade, and the touch pushes in location points to its path array.

Last, you tell the active CCBlade to dim itself when the player stops touching the screen.

You make the update method handle the dimming of the active CCBlade. You want it to fade at the same pace no matter what the fps is, so you multiply it with delta time and a constant value.

Since our delta time will not always be a whole number, you store the remainder for use in the next cycle to make the popping rate more constant.

Compile and run, and try out your shiny new blade effect!

Cool Blade Effect

Where To Go From Here?

Here is a sample project with all of the code from the above tutorial.

That's it for Part 2 of the series. In Part 1, you created a Watermelon Textured Polygon that falls to the bottom of the screen. Now, you are able to slice and dice the Watermelon into tiny little pieces with a cool blade.

In the next and last part of the series, you will finally turn everything you have into a complete game!


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 and Twitter.

Allen Tan

Contributors

Allen Tan

Author

Over 300 content creators. Join our team.