Tutorial Cocos2d Create Your Simple Game – 4: Simple Sprites Rect Collision Detection and GameOver Screen

Good morning guys, following my last tutorial “Tutorial Cocos2d – 3: Adding a Joystick to your iPad/iPhone Game”. Today I will show a little of collisions for Cocos2D.

Well we have a lot of different algorism for collisions, some of them is a little more practical and simple and that is what we are doing today.

The first code we will be workin on is Rectangle collision. Well, what is it?

it is very simple, around our Sprites we “draw” a simple “Rectangle” to check the collision, of course the algorithm is not very accurate over the true sprite’s borders, but it is very practical, simple and “light”.

Here I will continue from where we stopped from my last tutorial, if you are here just for the collisions try to follow bellow and if you have any question or problems post your comment asking, I will do my best to help.

Adding the Sprites

First of all we will need two sprites to make this collision happens. One of them we already have our “spaceship” (the cat bellow from the last tutorial).

spaceship

with the filename: “spaceship.png”

The other sprite that we don’t have yet, will be an evil “meteor”.

Imagem

Save the image above with the name meteor.png and put it inside the Group “Resources/” in our project on XCode.

Now we have a second sprite and we are ready to make a collision.

First of all let’s go to our Game.h and declare our meteor there.

Any place inside of  “@interface Game : CCLayer {  }” Add:

CCSprite* meteor;

We yet need to add two more variable that will be the Rect of the meteor and player. So add this two var bellow:

    CGRect playerRect;
CGRect meteorRect;

The code shall be looking something like this:

Imagem

Now, let’s head to the file: Game.m , if you don’t remember, it is where “everything” of our game runs up. And it is where our “player = [CCSprite spriteWithFile:@”spaceship.png”];” was build.

And now let’s “build” the codes for our meteor.

Any place inside of “if((self=[super init])){ }” Add:

  meteor = [CCSprite spriteWithFile:@”meteor.png”];

[self sendMeteor];

Here we are assign the meteor.png to the variable meteor and the “[self sendMeteor]” it is calling a function called “sendMeteor” and now we are going to create this function and move the meteor to the player position.

Moving the Meteor to the Player’s position

To move the meteor to where the player is, it is really simple, first let’s create a simple function to call the meteor:

-(void) sendMeteor{
meteor.position = ccp(800, 160);
[self addChild:meteor z:200];

meteor runAction:[CCMoveTo actionWithDuration:3.0
position:ccp(player.position.x, player.position.y)]
}

Ok, what this code means?

The meteor.position set the position where our meteor are going to start, [self addChild:meteor] it is going to put our meteor over the game layer. and the runAction will run the action CCMoveTo that will take 3.0 seconds to move our meteor from where he is now to the player.position.

if you run the code now, you will se meteor going to the player’s start position and stopping there, we don’t want it, we want the meteor goes throught the player’s position so let’s make some changes over the runAction:

[meteor runAction:[CCMoveBy actionWithDuration:6.0
position:ccpMult(ccpNormalize(ccpSub(player.position,meteor.position)), 1000)]];

I pretend soon to make a tutorial just to explain some actions and the difference between MoveBy and MoveTo, but to put what this code means. It will move our meteor 1000 pixels at 6.0 seconds through the player’s position. And that will make look our game a little better.

The Colision

Now is the best part, when our collision happens.

In my version of collision here, I did this way:

First let’s create a function called “rectPlayer” and “rectMeteor” like bellow:

-(CGRect) rectPlayer
{
return CGRectMake(player.position.x – (player.contentSize.width/2),
player.position.y – (player.contentSize.height/2),
player.contentSize.width, player.contentSize.height);
}

-(CGRect) rectMeteor
{
return CGRectMake(meteor.position.x – (meteor.contentSize.width/2),
meteor.position.y – (meteor.contentSize.height/2),
meteor.contentSize.width, meteor.contentSize.height);
}

Both Method will return a “rectangle” for the sprite player and meteor. This way we can check the colision.

Now let’s head to the function “tick” yet inside our Game.m, if you don’t remember it, it is where our Joystick move our player’s sprite.

So add this code bellow:

    playerRect=[self rectPlayer];
meteorRect=[self rectMeteor];
if(CGRectIntersectsRect(playerRect,meteorRect))
{
CCLOG(@”:(“);
}

So this code mean, that almost every mileseconds this tick is called and it will draw an imaginary (invisible) rectangle over the player’s sprite and do the same to the meteor and check if the meteor is touching the player through rectangle collisions.

Imagem

and inside of this if(CGRectIntersectsRect(playerRect,meteorRect)){} we are going to throw the play to the GameOver Screen.

The GameOver Screen

So, let’s create our GameOver node:

Right click over our Class’s name (here is Tutorial) and choose New File

Imagem

Select CCNode class, click “Next”.

Give it a name, here will be “GameOver”.

Check the box of your project is it isn’t and click “Create”.

Now we have GameOver.h and GameOver.m

let’s head to the GameOver.m:

first of all import our HelloWorldLayer.h (it is where our star screen are).

#import “HelloWorldLayer.h”

Now add our main scene:

+(id) scene {
CCScene *scene = [CCScene node];
GameOver *layer = [GameOver node];
[scene addChild: layer];
return scene;
}

Now let’s add the init with the “GameOver” message showing up:

-(id) init{

if( (self=[super init] )) {

self.isTouchEnabled = YES;
CCLabelTTF *label = [CCLabelTTF labelWithString:@”GameOver”
fontName:@”Courier New”
fontSize:40];
label.position = ccp(240, 240);

[self addChild: label];

}
return self;
}

For the last, if you touch  the screen it will back to our Start Screen.

-(BOOL) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

[[CCDirector sharedDirector]
replaceScene:[CCTransitionFade
transitionWithDuration:1
scene:[HelloWorldLayer node]
]];
return YES;
}

Your GameOver.m code shall look something like this:

Imagem

Now, let’s back to our Game.m and the first thing you’re gonna do, is to add the #import “GameOver.h” on the top of the code, above or bellow of the “#import “Game.h” :

#import “GameOver.h”

Now go back to our “if(CGRectIntersectsRect(playerRect,meteorRect)){}” and here inside, add:

[[CCDirector sharedDirector]
replaceScene:
[CCTransitionFade
transitionWithDuration:1
scene:[GameOver node]
]];

Ready. This code will be called when the collision between the player and the meteor happens. 🙂

Your Game.m code shall looks like:

ImagemImagem

Well guys, that is all for today, in the next tutorial we are going to work on a More Simple Collision and continue to develop this simple game, if you wanna check CLICK HERE. Cya guys. 🙂

9 thoughts on “Tutorial Cocos2d Create Your Simple Game – 4: Simple Sprites Rect Collision Detection and GameOver Screen

    1. Hello Carlosanto, check if your sendMeteor method is inside of Game.m
      the full method code is:
      -(void) sendMeteor{

      meteor.position = ccp(800, 160);
[self addChild:meteor z:200];
      [meteor runAction:[CCMoveBy actionWithDuration:6.0
      position:ccpMult(ccpNormalize(ccpSub(player.position,meteor.position)), 1000)]];

      }

      I hope help you O_o

  1. Hey, I went through all of these tutorials wondering why the GameOver scene’s touches wouldn’t work. I don’t know if it’s because I’m using xcode 4.6 or not, but I found that to get the touch to replace the scene with HelloWorldLayer node you need to add this line in the init of GameOver.m :

    [[CCTouchDispatcher sharedDispatcher]addTargetedDelegate:self priority:0 swallowsTouches:YES];

    1. sorry right after replying this I realized that this made it so that if you tapped the screen in any scene, start screen, game or gameover it would transition back to the start screen. I’ve figured out how to fix it.
      Place this line into the -(BOOL)ccTouchBegan: withEvent: function after the [[CCDirector sharedDirector] line:

      [[CCTouchDispatcher sharedDispatcher]removeAllDelegates];

      sorry about that.

  2. Hello admin, i see your site needs fresh content. Daily updates
    will rank your blog in google higher, content is
    king nowadays. If you are to lazy to write unique
    content everyday you should search in google for:
    Ightsero’s Essential Tool

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s