T he time has come!. No more boring stuff. We are going to write the gameplay. We are going to create two sprites, the hero and the enemy. When we drag the hero, the enemy will follow him, if he reaches the hero, the game is over.
If you just found this page you may like to know where are the previous parts of the series:
Part I:
http://www.oscarvgg.com/your-first-game-in-cocos2d-part-1-menus-and-transitions/
Part II:
http://www.oscarvgg.com/your-first-game-in-cocos2d-part-2-sprites-and-more-transitions/
Adding Characters
I looked up in google and found the perfect characters for our game: Mario and Bowser. Drag the following images to the resources folder just like we did with other images in the previous chapters. Check “Copy items into destination group’s folder” and click Add.


Go to GamePlay.m and add the following code to create the tags that we are going to give to our sprites:
1 2 3 4 | enum { kTagHero, kTagEnemy }; |
We need to give tags to our objects in the scene to be able to find them later because they are not attributes of the class. You will understand this better when we use it.
Scroll down to the init method and position yourself right before the closing curly brace of the if statement. Here we need to tell the world this view is going to receive touches adding the following line:
1 | self.isTouchEnabled = YES; |
Then we create the two characters and give them the tags we created to identify them.
1 2 3 4 5 6 7 | CCSprite *hero = [CCSprite spriteWithFile:@"hero.png"]; hero.position = ccp(60, 160); [self addChild:hero z:2 tag:kTagHero]; CCSprite *enemy = [CCSprite spriteWithFile:@"enemy.png"]; enemy.position = ccp(440, 160); [self addChild:enemy z:1 tag:kTagEnemy]; |
Now we need to make the enemy move to the position of the hero.
1 2 3 | [enemy runAction:[CCMoveTo actionWithDuration:5.0 position:ccp(hero.position.x, hero.position.y)] ]; |
Responding to touches
Ok, at the moment, if you run the project, the enemy will move to the position of the hero. What we need now is let the hero scape from the enemy’s claws. To do so we need drag it to a different position, so let’s add touch listener.
1 2 3 4 5 6 | -(BOOL) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { return YES; } -(BOOL) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { return YES; } |
ccTouchesBegan to know that the screen has been touched and ccTouchesMoved to know that our finger is moving over the screen. We are interested in the second one.
In ccTouchesMoved we have to grab that touch and convert it from real world coordinates to a point in game coordinates. Adding the next code before the return statement will do it for us:
1 2 3 | UITouch *myTouch = [touches anyObject]; CGPoint point = [myTouch locationInView:[myTouch view]]; point = [[CCDirector sharedDirector] convertToGL:point]; |
Then we call the hero by the tag and set it position to our finger position:
1 2 | CCNode *hero = [self getChildByTag:kTagHero]; [hero setPosition:point]; |
The hero is in a safe place now, but the enemy did not stand idly. We need to make him follow the hero to it’s new point:
1 2 3 4 | CCNode *enemy = [self getChildByTag:kTagEnemy]; [enemy runAction:[CCMoveTo actionWithDuration:5.0 position:ccp(hero.position.x, hero.position.y)] ]; |
ccTouchesMoved should look like this after all this changes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | -(BOOL) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { UITouch *myTouch = [touches anyObject]; CGPoint point = [myTouch locationInView:[myTouch view]]; point = [[CCDirector sharedDirector] convertToGL:point]; CCNode *hero = [self getChildByTag:kTagHero]; [hero setPosition:point]; CCNode *enemy = [self getChildByTag:kTagEnemy]; [enemy runAction:[CCMoveTo actionWithDuration:5.0 position:ccp(hero.position.x, hero.position.y) ]]; return YES; } |
What is next?. We have to create a function that check if the enemy reached the hero and a game over scene. Let’s go first for the Game Over scene.
Game Over Scene
Right click the “Classes” folder and click add->New File. Select Cocos2D->ccNode and click Choose. Give it a name, mine is going to be called “GameOver.m”
Open GameOver.m. Add the scene method like we did with the other scenes we created previously. it should look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 | +(id) scene { // 'scene' is an autorelease object. CCScene *scene = [CCScene node]; // 'layer' is an autorelease object. GameOver *layer = [GameOver node]; // add layer as a child to scene [scene addChild: layer]; // return the scene return scene; } |
Right after that we create the init method. Add two labels, one to let the user know the game is over and other to tell him to touch the screen to go to main menu:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | -(id) init{ if( (self=[super init] )) { self.isTouchEnabled = YES; CCLabel* label = [CCLabel labelWithString:@"Game Over" fontName:@"Marker Felt" fontSize:60]; label.position = ccp(240, 240); CCLabel* label2 = [CCLabel labelWithString:@"Touch to go to main menu" fontName:@"Marker Felt" fontSize:35]; label2.position = ccp(240, 131.67f); [self addChild: label]; [self addChild: label2]; } return self; } |
To make it true we have to add the touch listener and the call to go to main menu:
1 2 3 4 5 6 7 8 9 | -(BOOL) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { [[CCDirector sharedDirector] replaceScene:[CCFadeTransition transitionWithDuration:1 scene:[HelloWorld node] ]]; return YES; } |
Don’t forget to: #import “HelloWorldScene.h”. Now Let’s go back to GamePlay.m.
Detecting Collisions
To see if the characters collided we need to add a little of mathematic.
By checking the distance between the two pivot points of the sprites we can determinate how close or far they are from each other. Fist we need to determinate the size of the collision body of the character (this is not a real body, is just the distance other sprite should be from the pivot of my sprite to consider they are colliding). i’m going to say that for my characters the body is going to be 45 points, so when they are 45 points or less from each other they are colliding.

But when should i check the distance between them?. Well, all the time, so we need to schedule our collisions method to be called as often as we want. I’m going to call it every 0.01 seconds. How?. Easy, before the closing curly brace of the if statement of the init method add:
1 2 | [self schedule:@selector(SpritesDidColide) interval:.01]; |
Now init should look like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | -(id) init { if( (self=[super init] )) { CCMenuItem *Pause = [CCMenuItemImage itemFromNormalImage:@"pausebutton.png" selectedImage: @"pausebutton.png" target:self selector:@selector(pause:)]; CCMenu *PauseButton = [CCMenu menuWithItems: Pause, nil]; PauseButton.position = ccp(25, 295); [self addChild:PauseButton z:1000]; self.isTouchEnabled = YES; CCSprite *hero = [CCSprite spriteWithFile:@"hero.png"]; hero.position = ccp(60, 160); [self addChild:hero z:2 tag:kTagHero]; CCSprite *enemy = [CCSprite spriteWithFile:@"enemy.png"]; enemy.position = ccp(440, 160); [self addChild:enemy z:1 tag:kTagEnemy]; [enemy runAction:[CCMoveTo actionWithDuration:5.0 position:ccp(hero.position.x, hero.position.y) ]]; [self schedule:@selector(SpritesDidColide) interval:.01]; } return self; } |
Let’s write SpritesDidColide:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | -(void) SpritesDidColide { CCNode *enemy = [self getChildByTag:kTagEnemy]; CCNode *hero = [self getChildByTag:kTagHero]; float xDif = enemy.position.x - hero.position.x; float yDif = enemy.position.y - hero.position.y; float distance = sqrt(xDif * xDif + yDif * yDif); if (distance < 45) { [self unschedule:@selector(SpritesDidColide)]; [[CCDirector sharedDirector] replaceScene: [CCFadeTransition transitionWithDuration:1 scene:[GameOver node] ]]; } } |
Here we calculated the distance between the two pivot points, then we checked if it was lower than 45 points. If it is, then we stop calling the method and send the player to the game over scene.
Conclusion
Congratulations!. You just finished your first Cocos2D for iPhone game. That bring us to the end of this series. But don’t worry, i will be posting more Cocos2D tutorials in the future.
Where to go from here
If you are serious about this you should practice making some games. Do them more and more complicated every time and you’ll get more experience. Maybe some day i will download one of your games from the AppStore.



interesting, thanks
Hi
Thank you so much for your tutorial.It is working very well.Now i am adding some more features in to this,how to quit from the entire application if i am clicking a “Quit” or “Exit”menu item.I used [[CCDirector sharedDirector] end],but not working.Please help me to solve this problem.
Ok, here is the thing. You can not quit iPhone Apps from the app itself…
Nice Tutorial, Oscar!
One thing – Bowser moves real slow when you’re touching the screen .. maybe you can address that in the next tutorial?
Hero and Enemy won’t display during gameplay. I’ve double checked all the code and must be missing something. Can you post the entire project as a download so I can check it against the one I made in the tutorial?
Never mind. I accidentally had a “return self;” just before the part that adds the sprite characters.
You can just deny these 2 comments. Thanks
Hi,
I got a error when i wrote self.isTouchEnabled = YES; in init method. If i remove it then it was running successfully but i didnt get touch events. Please give me your solution.
i actually have the same problem. it says Request for member ‘isTouchEnabled’ in something not a structure or union. here is my init:
-(id) init {
if( (self=[super init] )) {
CCMenuItem *Pause = [CCMenuItemImage itemFromNormalImage:@"pausebutton.png"
selectedImage:@"pausebutton.png"
target:self
selector:@selector(pause:)];
CCMenu *PauseButton = [CCMenu menuWithItems: Pause, nil];
PauseButton.position = ccp(25, 295);
[self addChild:PauseButton z:1000];
self.isTouchEnabled = YES;
CCSprite *hero = [CCSprite spriteWithFile:@"mainguy.png"];
hero.position = ccp(60, 160);
[self addChild:hero z:2 tag:kTagHero];
CCSprite *enemy = [CCSprite spriteWithFile:@"base2.png"];
enemy.position = ccp(440, 160);
[self addChild:enemy z:1 tag:kTagZombie];
[enemy runAction:[CCMoveTo actionWithDuration:5.0
position:ccp(hero.position.x, hero.position.y)]
];
}
return self;
}
You most be missing a curly brace or an @ sign or forgot to import the header. Double check your class definition.
This rocks my world.
This stuff is great.
I’m just getting my head around obj c and you have really helped explain it a lot.
Cheers,
Thank you, I actually find objective-c very different than common languages, the syntax is hard to learn when you have worked all your life with java, c# or any similar, but it have become a challenge to me to learn this, and I love challenges!
Hi,
Your tutorial is excellent
just one question though i keep getting warnings on these 2:
***GamePlay.m:81: warning: conflicting types for ‘-(BOOL)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event’
-(BOOL) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
return YES;
}
***GamePlay.m:86: warning: conflicting types for ‘-(BOOL)ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event’***
-(BOOL) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
UITouch *myTouch = [touches anyObject];
CGPoint point = [myTouch locationInView:[myTouch view]];
point = [[CCDirector sharedDirector] convertToGL:point];
CCNode *hero = [self getChildByTag:kTagHero];
[hero setPosition:point];
CCNode *enemy = [self getChildByTag:kTagEnemy]; [enemy runAction:[CCMoveTo actionWithDuration:5.0 position:ccp(hero.position.x, hero.position.y)]];
return YES;
}
Any ideas at all|?
Cheers
can you please provide the complete source code for this project?
Ummm, don’t think so – sorry
Its really great… Thanks for ur tutorial…..
Hi. I like your website but i can tell it probably isn’t getting much traffic? If you want to help imrpove that check this website out, he has a short video that i really suggest you watch. Commission Crusher P.S this isn’t my website and i’m not spamming your blog, i don’t care if you delete this comment. I am only trying to help you improve your site.
Hi Oscar,
Thanks for the great tutorials. Son geniales!
I wanted to add something: in your ccTouchesBegan: and ccTouchesMoved: methods, I was getting warnings saying something like “conflicting data types”, so I changed the return type of each of these methods to (void) instead of (BOOL).
One question: should we be releasing any objects here or doing any other memory management? I’m pretty new to Objective-C and Cocos2D, so I’m still trying to figure out when to manage memory and when it’s managed for me.
Thanks,
Jonathan
Hi OscerVGG
Thanks for posting tutorials.
My pleasure!
Great tutorial, really enjoyed it. Just a few issues:
-(BOOL) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
return YES;
}
-(BOOL) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
return YES;
}
Should be:
-(void) ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
}
-(void) ccTouchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
}
And:
CCLabel* label = [CCLabel labelWithString:@"Game Over"
fontName:@"Marker Felt"
fontSize:60];
should be:
CCLabelTTF* label = [CCLabelTTF labelWithString:@"Game Over"
fontName:@"Marker Felt"
fontSize:60];
And:
CCLabel* label2 = [CCLabel labelWithString:@"Touch to go to main menu"
fontName:@"Marker Felt"
fontSize:35];
should be:
CCLabelTTF* label2 = [CCLabelTTF labelWithString:@"Touch to go to main menu"
fontName:@"Marker Felt"
fontSize:35];
And:
[[CCDirector sharedDirector]
replaceScene:
[CCFadeTransition
transitionWithDuration:1
scene:[GameOver node]
]];
Should be:
[[CCDirector sharedDirector]
replaceScene:
[CCTransitionFade
transitionWithDuration:1
scene:[GameOver node]
]];
Finally a bounding box collision detection can be more accurate in this case:
- (void)spritesDidCollide
{
CCNode *enemy = [self getChildByTag:kTagEnemy];
CCNode *hero = [self getChildByTag:kTagHero];
float enemyHalfHeight = enemy.contentSize.height / 2;
float enemyHalfWidth = enemy.contentSize.width / 2;
float heroHalfHeight = hero.contentSize.height / 2;
float heroHalfWidth = hero.contentSize.width / 2;
if ((enemy.position.x – enemyHalfWidth hero.position.x – heroHalfWidth) && // Enemy right side, hero left side
(enemy.position.y + enemyHalfHeight > hero.position.y – heroHalfHeight) && // Enemy top side, hero bottom side
(enemy.position.y – enemyHalfHeight < hero.position.y + heroHalfHeight)) // Enemy bottom side, hero top side
{
[self unschedule:@selector(spritesDidCollide)];
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:1 scene:[GameOver node]]];
}
}
My previous comment didn’t appear to copy correctly (third time’s the charm!). The correct collision detection if statement is:
if ((enemy.position.x – enemyHalfWidth hero.position.x – heroHalfWidth) && // Enemy right side, hero left side
(enemy.position.y + enemyHalfHeight > hero.position.y – heroHalfHeight) && // Enemy top side, hero bottom side
(enemy.position.y – enemyHalfHeight < hero.position.y + heroHalfHeight)) // Enemy bottom side, hero top side
Great tutorial!!!
thanks!
[self unschedule:@selector(spritesDidCollide)];
[[CCDirector sharedDirector] replaceScene:[CCTransitionFade transitionWithDuration:1 scene:[GameOver node]]];
}
}
hi…. oscar. i have a question in this part can you help me. i want to try to code in this replaceScene part that if they collide the hero cannot pass through to the enemy. like a game “un block me”. can you give me an example on how to do that?
thank you