Cocos2D is a powerful library for the iPhone that can save you a lot of time while building your iPhone game. It has sprite support, cool graphical effects, animations, physics libraries, sound engines, and a lot more.
I am just starting to learn Cocos2D, and while there are various useful tutorials on getting started with Cocos2D out there, I couldn’t find anything quite like what I was looking for – making a very simple but functional game with animation, collisions, and audio without using too many advanced features. I ended up making a simple game of my own, and thought I’d write a tutorial based on my experience in case it might be useful to other newcomers.
This tutorial will walk you through the process of creating a simple game for your iPhone with Cocos2D, from start to finish. You can follow along with the tutorial, or just jump straight to the sample project at the end of the article. And yes. There will be ninjas.
Downloading and Installing Cocos2D
You can download Cocos2D from the Cocos2D Google Code page. As of this blog post, the latest version is 0.99.0-final – this is what we’ll be using for the tutorial.
After you pull down the code, you’ll want to install the useful project templates. Open up a Terminal window to the directory you downloaded Cocos2D to, and enter the following command: ./install_template.sh
Note that you can optionally pass a parameter to the install script if you have XCode installed to a non-standard directory (like you might have done if you have more than one version of the SDK on your machine).
Hello, Cocos2D!
Let’s start by getting a simple Hello World project up and running by using the Cocos2D template we just installed. Start up XCode and create a new Cocos2D project by selecting the cocos2d-0.99.0 Application template, and name the project “Cocos2DSimpleGame”.
Go ahead and build and run the template as-is. If all works OK, you should see the following:
Cocos2D is organized into the concept of “scenes”, which are kind of like “levels” or “screens” for a game. For example you might have a scene for the initial menu for the game, another for the main action of the game, and a game over scene to end. Inside scenes, you can have a number of layers (kind of like in Photoshop), and layers can contain nodes such as sprites, labels, menus, or more. And nodes can contain other nodes as well (i.e. a sprite could have a child sprite inside it).
If you take a look at the sample project, you’ll see there’s just one scene – HelloWorldScene – and we’re going to start implementing our main gameplay in there. Go ahead and open it up – you’ll see that right now in the init method it’s adding a label that says “Hello World” to the scene. We’re going to take that out, and put a sprite in instead.
Adding A Sprite
Before we can add a sprite, we’ll need some images to work with. You can either create your own, or use the ones my lovely wife has created for the project: a Player image, a Projectile image, and a Target image.
Once you’ve obtained the images, drag them over to the resources folder in XCode, and make sure “Copy items into destination group’s folder (if needed)” is checked.
Now that we have our images, we have to figure out where we want to place the player. Note that in Cocos2D the bottom left corner of the screen has coordinates of (0,0) and the x and y values increase as you move to the upper right. Since this project is in landscape mode, this means that the upper right corner is (480, 320).
Also note that by default when we set the position of an object, the position is relative to the center of the sprite we are adding. So if we wanted our player sprite to be aligned with the left edge of the screen horizontally, and vertically centered:
- For the x coordinate of the position, we’d set it to [player sprite's width]/2.
- For the y coordinate of the position, we’d set it to [window height]/2
Here’s a picture that helps illustrate this a bit better:
So let’s give it a shot! Open up the Classes folder and click on HelloWorldScene.m, and replace the init method with the following:
-(id) init { if( (self=[super init] )) { CGSize winSize = [[CCDirector sharedDirector] winSize]; CCSprite *player = [CCSprite spriteWithFile:@"Player.png" rect:CGRectMake(0, 0, 27, 40)]; player.position = ccp(player.contentSize.width/2, winSize.height/2); [self addChild:player]; } return self; } |
You can compile and run it, and your sprite should appear just fine, but note that the background defaults to black. For this artwork, white would look a lot better. One easy way to set the background of a layer in Cocos2D to a custom color is to use the CCColoredLayer class. So let’s give this a shot. Click on HelloWorldScene.h and change the HelloWorld interface declaration to read as follows:
@interface HelloWorld : CCColorLayer |
Then click on HelloWorldScene.m and make a slight modification to the init method so we can set the background color to white:
if( (self=[super initWithColor:ccc4(255,255,255,255)] )) { |
Go ahead and compile and run, and you should see your sprite on top of a white background. w00t our ninja looks ready for action!
Moving Targets
Next we want to add some targets into our scene for our ninja to combat. To make things more interesting, we want the targets to be moving – otherwise there wouldn’t be much of a challenge! So let’s create the targets slightly off screen to the right, and set up an action for them telling them to move to the left.
Add the following method right before the init method:
-(void)addTarget { CCSprite *target = [CCSprite spriteWithFile:@"Target.png" rect:CGRectMake(0, 0, 27, 40)]; // Determine where to spawn the target along the Y axis CGSize winSize = [[CCDirector sharedDirector] winSize]; int minY = target.contentSize.height/2; int maxY = winSize.height - target.contentSize.height/2; int rangeY = maxY - minY; int actualY = (arc4random() % rangeY) + minY; // Create the target slightly off-screen along the right edge, // and along a random position along the Y axis as calculated above target.position = ccp(winSize.width + (target.contentSize.width/2), actualY); [self addChild:target]; // Determine speed of the target int minDuration = 2.0; int maxDuration = 4.0; int rangeDuration = maxDuration - minDuration; int actualDuration = (arc4random() % rangeDuration) + minDuration; // Create the actions id actionMove = [CCMoveTo actionWithDuration:actualDuration position:ccp(-target.contentSize.width/2, actualY)]; id actionMoveDone = [CCCallFuncN actionWithTarget:self selector:@selector(spriteMoveFinished:)]; [target runAction:[CCSequence actions:actionMove, actionMoveDone, nil]]; } |
I’ve spelled out things in a verbose manner here to make things as easy to understand as possible. The first part should make sense based on what we’ve discussed so far: we do some simple calculations to determine where we want to create the object, set the position of the object, and add it to the scene the same way we did for the player sprite.
The new element here is adding actions. Cocos2D provides a lot of extremely handy built-in actions you can use to animate your sprites, such as move actions, jump actions, fade actions, animation actions, and more. Here we use three actions on the target:
- CCMoveTo: We use the CCMoveTo action to direct the object to move off-screen to the left. Note that we can specify the duration for how long the movement should take, and here we vary the speed randomly from 2-4 seconds.
- CCCallFuncN: The CCCallFuncN function allows us to specify a callback to occur on our object when the action is performed. We are specifying a callback called “spriteMoveFinished” that we haven’t written yet – more below.
- CCSequence: The CCSequence action allows us to chain together a sequence of actions that are performed in order, one at a time. This way, we can have the CCMoveTo action perform first, and once it is complete perform the CCCallFuncN action.
Next, add the callback function that we referred to in the CCCallFuncN action. You can add this right before addTarget:
-(void)spriteMoveFinished:(id)sender { CCSprite *sprite = (CCSprite *)sender; [self removeChild:sprite cleanup:YES]; } |
The purpose of this function is to remove the sprite from the scene once it is off-screen. This is important so that we don’t leak memory over time by having tons of unused sprites sitting off-screen. Note that there are other (and better) ways to address this problem such as having reusable arrays of sprites, but for this beginner tutorial we are taking the simple path.
One last thing before we go. We need to actually call the method to create targets! And to make things fun, let’s have targets continuously spawning over time. We can accomplish this in Cocos2D by scheduling a callback function to be periodically called. Once per second should do for this. So add the following call to your init method before you return:
[self schedule:@selector(gameLogic:) interval:1.0]; |
And then implement the callback function simply as follows:
-(void)gameLogic:(ccTime)dt { [self addTarget]; } |
That’s it! So now if you compile and run the project, now you should see targets happily moving across the screen:
Shooting Projectiles
At this point, the ninja is just begging for some action – so let’s add shooting! There are many ways we could implement shooting, but for this game we are going to make it so when the user taps the screen, it shoots a projectile from the player in the direction of the tap.
I want to use a CCMoveTo action to implement this to keep things at a beginner level, but in order to use this we have to do a little math. This is because the CCMoveTo requires us to give a destination for the projectile, but we can’t just use the touch point because the touch point represents just the direction to shoot relative to the player. We actually want to keep the bullet moving through the touch point until the bullet goes off-screen.
Here’s a picture that illustrates the matter:
So as you can see, we have a small triangle created by the x and y offset from the origin point to the touch point. We just need to make a big triangle with the same ratio – and we know we want one of the endpoints to be off the screen.
Ok, so onto the code. First we have to enable touches on our layer. Add the following line to your init method:
self.isTouchEnabled = YES; |
Since we’ve enabled touches on our layer, we will now receive callbacks on touch events. So let’s implement the ccTouchesEnded method, which is called whenever the user completes a touch, as follows:
- (void)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { // Choose one of the touches to work with UITouch *touch = [touches anyObject]; CGPoint location = [touch locationInView:[touch view]]; location = [[CCDirector sharedDirector] convertToGL:location]; // Set up initial location of projectile CGSize winSize = [[CCDirector sharedDirector] winSize]; CCSprite *projectile = [CCSprite spriteWithFile:@"Projectile.png" rect:CGRectMake(0, 0, 20, 20)]; projectile.position = ccp(20, winSize.height/2); // Determine offset of location to projectile int offX = location.x - projectile.position.x; int offY = location.y - projectile.position.y; // Bail out if we are shooting down or backwards if (offX <= 0) return; // Ok to add now - we've double checked position [self addChild:projectile]; // Determine where we wish to shoot the projectile to int realX = winSize.width + (projectile.contentSize.width/2); float ratio = (float) offY / (float) offX; int realY = (realX * ratio) + projectile.position.y; CGPoint realDest = ccp(realX, realY); // Determine the length of how far we're shooting int offRealX = realX - projectile.position.x; int offRealY = realY - projectile.position.y; float length = sqrtf((offRealX*offRealX)+(offRealY*offRealY)); float velocity = 480/1; // 480pixels/1sec float realMoveDuration = length/velocity; // Move projectile to actual endpoint [projectile runAction:[CCSequence actions: [CCMoveTo actionWithDuration:realMoveDuration position:realDest], [CCCallFuncN actionWithTarget:self selector:@selector(spriteMoveFinished:)], nil]]; } |
In the first portion, we choose one of the touches to work with, get the location in the current view, then call convertToGL to convert the coordinates to our current layout. This is important to do since we are in landscape mode.
Next we load up the projectile sprite and set the initial position as usual. We then determine where we wish to move the projectile to, using the vector between the player and the touch as a guide, according to the algorithm described previously.
Note that the algorithm isn’t ideal. We’re forcing the bullet to keep moving until it reaches the offscreen X position – even if we would have gone offscreen in the Y position first! There are various ways to address this including checking for the shortest length to go offscreen, having our game logic callback check for offscreen projectiles and removing rather than using the callback method, etc. but for this beginner tutorial we’ll keep it as-is.
The last thing we have to do is determine the duration for the movement. We want the bullet to be shot at a constant rate despite the direction of the shot, so again we have to do a little math. We can figure out how far we’re moving by using the Pythagorean Theorem. Remember from geometry, that is the rule that says the length of the hypotenuse of a triangle is equal to the square root of the sum of the squares of the two sides.
Once we have the distance, we just divide that by the velocity in order to get the duration. This is because velocity = distance over time, or in other words time = distance over velocity.
The rest is setting the actions just like we did for the targets. Compile and run, and now your ninja should be able to fire away at the oncoming hordes!
Collision Detection
So now we have shurikens flying everywhere – but what our ninja really wants to do is to lay some smack down. So let’s add in some code to detect when our projectiles intersect our targets.
There are various ways to solve this with Cocos2D, including using one of the included physics libraries: Box2D or Chipmunk. However to keep things simple, we are going to implement simple collision detection ourselves.
To do this, we first need to keep better track of the targets and projectiles currently in the scene. Add the following to your HelloWorldScene class declaration:
NSMutableArray *_targets; NSMutableArray *_projectiles; |
And initialize the arrays in your init method:
_targets = [[NSMutableArray alloc] init]; _projectiles = [[NSMutableArray alloc] init]; |
And while we’re thinking of it, clean up the memory in your dealloc method:
[_targets release]; _targets = nil; [_projectiles release]; _projectiles = nil; |
Now, modify your addTarget method to add the new target to the targets array and set a tag for future use:
target.tag = 1; [_targets addObject:target]; |
And modify your ccTouchesEnded method to add the new projectile to the projectiles array and set a tag for future use:
projectile.tag = 2; [_projectiles addObject:projectile]; |
Finally, modify your spriteMoveFinished method to remove the sprite from the appropriate array based on the tag:
if (sprite.tag == 1) { // target [_targets removeObject:sprite]; } else if (sprite.tag == 2) { // projectile [_projectiles removeObject:sprite]; } |
Compile and run the project to make sure everything is still working OK. There should be no noticeable difference at this point, but now we have the bookkeeping we need to implement some collision detection.
Now add the following method to HelloWorldScene:
- (void)update:(ccTime)dt { NSMutableArray *projectilesToDelete = [[NSMutableArray alloc] init]; for (CCSprite *projectile in _projectiles) { CGRect projectileRect = CGRectMake( projectile.position.x - (projectile.contentSize.width/2), projectile.position.y - (projectile.contentSize.height/2), projectile.contentSize.width, projectile.contentSize.height); NSMutableArray *targetsToDelete = [[NSMutableArray alloc] init]; for (CCSprite *target in _targets) { CGRect targetRect = CGRectMake( target.position.x - (target.contentSize.width/2), target.position.y - (target.contentSize.height/2), target.contentSize.width, target.contentSize.height); if (CGRectIntersectsRect(projectileRect, targetRect)) { [targetsToDelete addObject:target]; } } for (CCSprite *target in targetsToDelete) { [_targets removeObject:target]; [self removeChild:target cleanup:YES]; } if (targetsToDelete.count > 0) { [projectilesToDelete addObject:projectile]; } [targetsToDelete release]; } for (CCSprite *projectile in projectilesToDelete) { [_projectiles removeObject:projectile]; [self removeChild:projectile cleanup:YES]; } [projectilesToDelete release]; } |
The above should be pretty clear. We just iterate through our projectiles and targets, creating rectangles corresponding to their bounding boxes, and use CGRectIntersectsRect to check for intersections. If any are found, we remove them from the scene and from the arrays. Note that we have to add the objects to a “toDelete” array because you can’t remove an object from an array while you are iterating through it. Again, there are more optimal ways to implement this kind of thing, but I am going for the simple approach.
You just need one more thing before you’re ready to roll – schedule this method to run as often as possible by adding the following line to your init method:
[self schedule:@selector(update:)]; |
Give it a compile and run, and now when your projectiles intersect targets they should disappear!
Finishing Touches
We’re pretty close to having a workable (but extremely simple) game now. We just need to add some sound effects and music (since what kind of game doesn’t have sound!) and some simple game logic.
If you’ve been following my blog series on audio programming for the iPhone, you’ll be extremely pleased to hear how simple the Cocos2D developers have made it to play basic sound effects in your game.
First, drag some background music and a shooting sound effect into your resources folder. Feel free to use the cool background music I made or my awesome pew-pew sound effect, or make your own.
Then, add the following import to the top of your HelloWorldScene.m:
#import "SimpleAudioEngine.h" |
In your init method, start up the background music as follows:
[[SimpleAudioEngine sharedEngine] playBackgroundMusic:@"background-music-aac.caf"]; |
0.99-final update: It seems there might be a minor bug in 0.99-final where the background music will only play once (whereas it should loop) – either that or I’m doing something wrong. For a workaround, see the comments at the end of this article.
And in your ccTouchesEnded method play the sound effect as follows:
[[SimpleAudioEngine sharedEngine] playEffect:@"pew-pew-lei.caf"]; |
Now, let’s create a new scene that will serve as our “You Win” or “You Lose” indicator. Click on the Classes folder and go to File\New File, and choose Objective-C class, and make sure subclass of NSObject is selected. Click Next, then type in GameOverScene as the filename, and make sure “Also create GameOverScene.h” is checked.
Then replace GameOverScene.h with the following code:
#import "cocos2d.h" @interface GameOverLayer : CCColorLayer { CCLabel *_label; } @property (nonatomic, retain) CCLabel *label; @end @interface GameOverScene : CCScene { GameOverLayer *_layer; } @property (nonatomic, retain) GameOverLayer *layer; @end |
Then replace GameOverScene.m with the following code:
#import "GameOverScene.h" #import "HelloWorldScene.h" @implementation GameOverScene @synthesize layer = _layer; - (id)init { if ((self = [super init])) { self.layer = [GameOverLayer node]; [self addChild:_layer]; } return self; } - (void)dealloc { [_layer release]; _layer = nil; [super dealloc]; } @end @implementation GameOverLayer @synthesize label = _label; -(id) init { if( (self=[super initWithColor:ccc4(255,255,255,255)] )) { CGSize winSize = [[CCDirector sharedDirector] winSize]; self.label = [CCLabel labelWithString:@"" fontName:@"Arial" fontSize:32]; _label.color = ccc3(0,0,0); _label.position = ccp(winSize.width/2, winSize.height/2); [self addChild:_label]; [self runAction:[CCSequence actions: [CCDelayTime actionWithDuration:3], [CCCallFunc actionWithTarget:self selector:@selector(gameOverDone)], nil]]; } return self; } - (void)gameOverDone { [[CCDirector sharedDirector] replaceScene:[HelloWorld scene]]; } - (void)dealloc { [_label release]; _label = nil; [super dealloc]; } @end |
Note that there are two different objects here: a scene and a layer. The scene can contain any number of layers, however in this example it just has one. The layer just puts a label in the middle of the screen, and schedules a transition to occur 3 seconds in the future back to the HelloWorld scene.
Finally, let’s add some extremely basic game logic. First, let’s keep track of the projectiles the player has destroyed. Add a member variable to your HelloWorld class in HelloWorldScene.h as follows:
int _projectilesDestroyed; |
Inside HelloWorldScene.m, add an import for the GameOverScene class:
#import "GameOverScene.h" |
Increment the count and check for the win condition in your update method inside the targetsToDelete loop right after removeChild:target:
_projectilesDestroyed++; if (_projectilesDestroyed > 30) { GameOverScene *gameOverScene = [GameOverScene node]; [gameOverScene.layer.label setString:@"You Win!"]; [[CCDirector sharedDirector] replaceScene:gameOverScene]; } |
And finally let’s make it so that if even one target gets by, you lose. Modify the spriteMoveFinished method by adding the following code inside the tag == 1 case right after removeChild:sprite:
GameOverScene *gameOverScene = [GameOverScene node]; [gameOverScene.layer.label setString:@"You Lose :["]; [[CCDirector sharedDirector] replaceScene:gameOverScene]; |
Go ahead and give it a compile and run, and you should now have win and lose conditions and see a game over scene when appropriate!
Gimme The Code!
And that’s a wrap! Here’s the full code for the simple Cocos2D iPhone game that we developed thus far.
Where To Go From Here?
This project could be a nice basis for playing around some more with Cocos2D by adding some new features into the project. Maybe try adding in a bar chart to show how many more targets you have to destroy before you win (check out the drawPrimitivesTest sample project for examples of how to do that). Maybe add cooler death animations for when the monsters are destroyed (see ActionsTest, EffectsTest, and EffectsAdvancedTest projects for that). Maybe add more sounds, artwork, or gameplay logic just for fun. The sky’s the limit!
If you want to keep going with this tutorial series, check out How To Add A Rotating Turret to this game!
Also, if you’d like to keep learning more about Cocos2D, check out my tutorials on how to create buttons in Cocos2D, intro to Box2D, or how to create a simple Breakout game.
Feel free to chime in if you know of any better ways to do various things with this project or if there are any problems – like I said this is the first time I’ve played with Cocos2D so I have a lot left to learn!
Category: iPhone






Hi. Thanks for this tutor. Very interesting article.
This is the clearest explanation of getting started with cocos2d I have seen.
Thanks!
Great job Ray, you’ve covered most the basics here. I wish you had this out before. Only thing I can think of that people always ask about that isn’t covered here is a little more on using multi-touch.
Bookmarked.
Ray, Thanks a ton for this article/example. I’ve been programming for a long time, but the iPhone is a new platform for me and it really helps one’s confidence to quickly and easily get a simple game/program up and running with minimal muss and fuss.
Keep up the good work and thanks again!
-Ed
Thanks for the tutorial…. the best of it’s kind on the web. It’s good to go from the beginning of a cocos until the end. The cocos community thanks you!
Thank you so much for putting this tutorial together! You did a great job explaining everything and have made learning a new language just a bit easier. Thanks again!
Thank you for this tutorial, very interesting and instructive !!
Thanks again
Thanks. It’s really helpful!!
Wow thanks everybody, glad it was useful! :]
Hi. Thanks for article.
That’s great! Thank you for your tutorial. :)
Very good tutorial, thank you !!
A little mistake: when you define the bounding box of the target, you use the width and height of the projectile.
Nice catch Eric! I’ve updated the post and sample project to fix that. Thanks!
Thanks for this tutorial! Much appreciated.
Just a note: the pew-pew sound effect doesn’t play when running the app in the Simulator under OS 3.0. 3.1+ seems to be fine though.
@dejo – Hm that is strange, just gave it a try over here and the pew-pew sound plays ok on the 3.0 Simulator for me. Anyone have any idea what the problem could be here?
Bravo, Ray! I was getting pretty frustrated with iPhone game development in general and this made things a heck of a lot more clearer. Thank you and keep ‘em coming!
You mentioned a few times of “simple” implementations. Can you elaborate more on the “complex” implementation. I’d be interested in seeing how to use Box2d(?) to handle collision detection. Your example used “CGRectIntersectsRect”.
@Muller – great, best of luck with your game!
@Kim – That sounds like a great idea for a future post! :]
Cocos 0.99.0-final out now:
http://cocos2d-iphone.googlecode.com/files/cocos2d-iphone-0.99.0-final.tar.gz
Nice, thanks for the heads up Bas. If I have time I’ll update this tutorial for the 0.99 final release.
Edit: updated! Thanks again! :]
Ray, I am also finding that, if I comment out the call the start the background music, then when the first pew-pew needs to be played, the whole app stalls momentarily before it plays. (I’m guessing this is because there is some setup involved the first time a sound is played). Any suggestions?
Yes, the first time you use the SimpleSoundEngine it initializes itself, which can take a while. One solution is to use a function called preloadEffect that lets you load your sound effects into memory before you use them:
[[SimpleAudioEngine sharedEngine] preloadEffect:@”pew-pew-lei.caf”];
You would put that in your init method. Since this is the first use of SimpleAudioEngine, it will initialize it as well as loading your effects, so no stutter!
In a real game, you’d have a loading screen that would display while time intensive functions like this are called.
Ray, thanks. That helps.
(Sorry to be such a PITA but here I go again…)
Next issue: The background music doesn’t seem to endlessly loop and only plays once. A bug perhaps?
Hm that is strange, it repeats OK for me. You’re using version 0.99 (rc or final) right?
There’s another version of playBackgroundMusic you can call to specify whether or not to loop the music:
[[SimpleAudioEngine sharedEngine] playBackgroundMusic:@”background-music-aac.caf” loop:TRUE];
However in 0.99 the default is to loop, so I’m not sure why it isn’t looping for you…
nice article!
Yes, I’m using version 0.99 final.
I tried using loop:TRUE but to no effect.
(I’m running the iPhone SDK 3.1.3 under Snow Leopard).
Hm – then I’m not sure!
It’s a great tutorial! It helped me a lot understanding Cocoa2D.
Thanks!
P.
This is an amazing tutorial. Thanks so much!
Another little mistake, you should add the projectile to the scene after the test (line 186) :
// Bail out if we are shooting down or backwards
if (offX <= 0) return;
is successful, otherwise the projectile is added and stays in place unnecessarily until the end.
I've compiled the game on my iPod and it's already fun to play. I've added a rotation movement to the projectile and it's really easy.
The background music works just fine on the device but as mentioned before, it doesn't endlessly loop in the simulator, so maybe the simulator is the problem ?
I’ve just had a look on Cocos2D site, the problem of background music in the simulator is mentioned in this FAQ :
http://www.cocos2d-iphone.org/wiki/doku.php/cocosdenshion:faq#background_music_seems_unreliable_in_the_simulator
@dejo – Aha! I’ve finally reproduced and found out a fix for the background music stopping problem that you mentioned.
It turns out it works fine in 0.99-rc, but not in 0.99-final. I think a minor bug was introduced in 0.99-final, but I was able to get it working by adding the following code at line 72 of CDAudioManager.m (under cocos2d Sources/CocosDenshion):
- (void)setNumberOfLoops:(NSInteger)theNumberOfLoops { numberOfLoops = theNumberOfLoops; audioSourcePlayer.numberOfLoops = theNumberOfLoops; }I’ll let the cocos2D guys know about this in case this is a bug – but this workaround should get you by in the meantime. I’ve updated the sample code with the workaround and mentioned this issue in the post as well. Thanks for letting me know about this!
@eric – Another great catch, thanks again! Post and sample code updated with the fix.
Thanks for the tutorial…much as I like the sound effect, others may like this link f0r some 8 bit sounds ;-) http://thirdcog.eu/apps/cfxr
I simply cannot thank you enough for this well structured and clear example. I have been tearing my hair out trying to get a foothold to do an iphone game for a client. This was all I needed after looking at so many frameworks.
I’ve been programming for over 30 years!!!
Many thanks!
Hey thanks Indy, I hadn’t seen that before, quite awesome!
And I’m glad it came in handy Stan, best of luck on the game! :]
Hi,
Bit of fun….made the sprite fade out on hit:
In update()
// We have processed all the targets for this single projectile and so can remove from the
// _targets array, as this will mean one less target to check for the remaining projectiles
for (CCSprite *target in targetsToDelete) {
[_targets removeObject:target];
// stop the target moving or else despite it fading, it will still be moving to the left and could
// go off screen to trigger game over
[target stopAllActions];
// chain two actions together, one a fade action and then call a function to remove the target sprite
id disappear = [CCFadeTo actionWithDuration:.5 opacity:0];
id actionMoveDone = [CCCallFuncN actionWithTarget:self selector:@selector(targetHit:)];
[target runAction:[CCSequence actions:disappear, actionMoveDone, nil]];
//[self removeChild:target cleanup:YES];
_projectilesDestroyed++;
_projectilesDestroyed++;
if (_projectilesDestroyed > 30) {
GameOverScene *gameOverScene = [GameOverScene node];
[gameOverScene.layer.label setString:@"You Win!"];
[[CCDirector sharedDirector] replaceScene:gameOverScene];
}
}
And created a new method which is called when the target is hit:
-(void) targetHit:(id) sender {
CCSprite *sprite = (CCSprite *) sender;
[self removeChild:sprite cleanup:YES];
}
I’ve been playing around with cocos2d now and then in my free time since 0.73, but I still found this article entertaining and quite useful. Very well done!
On a side note, after spending a few minutes clicking through your other posts it was an easy decision to add you to my google reader feed :)
Thank’s you so much!
Thanks for your great work!
I thought this should be the ‘DEFAULT’ cocos2d demo.Definitely!
This is a great tutorial! Thanks for sharing it.
Great tutorial. Best intro to Cocos2d I’ve found. Thanks.
It feels like Stan Gilbert was in my head! I’ve been a freelance programmer since 1983. I’ve also spent the last week agonizing over how to get my head around graphic programming for the iPhone.
I’ve learned more in the last hour than in the last 2 days. All I can say is thanks.
Great and interesting tutorial. I will make my next iPhone game with cocos2d. It’s really good engine.
Thanks sooooooo much for the tutorial. This is the best iphone game tutorial for beginner =] .
Great tutorial! I was looking for a clear and easy way to begin coding Cocos2d games and this tutorial really helps. You’ve saved me a lot of frustration!
Anyone else getting a
“HelloWorldScene may not respond to ‘+schedule:interval:’” warning when adding the sheduled event to call addTarget?
I’ve probably just typed something incorrectly somewhere above it, but hey :)
Great tute!
oh good. I was adding it to +(id)init rather than -(id)init.
‘scuse my sillyness!
Thanks for the tutorial,Ray. I am wondering if you can give us a tutorial about linking two classes. For example, instead of adding targets directly in the GameScene, could you implement an enemy class.
@Indy: Very cool!
@King: That sounds like a good idea! Maybe I can incorporate that into a future tutorial, I’ve added that to my post idea list.
@Everyone else: Thanks much for the encouraging and kind words! :]
I’ve skimmed through this and it looks great. As soon as I get my hands on XCode I’ll run through your tutorial. I was looking for something like this, Cocos2d tutorials are very fragmented!
Learn a lot from your passage. Thanks!
Everything is clear.
Excellent tutorial, thanks! One question though–you are incrementing _projectilesDestroyed twice in the update:(ccTime)dt method…is that just accidental?
Oops! Good catch Francis, that was a typo on the web page (but luckily not in the sample project). I fixed it, thanks!
Like the tutorial. Was woundering if you could do a part 2 with some extras. My main question would be how we can rotate the player to match the direction you are firing. I know it doesn’t look right with this image but would be a good tutorial as most games do this at a minimum.
I you dont feel like doing a full tutorial then if you could email me about this.
@Jason – That sounds like a great idea for a future tutorial – I’ve added it to my idea list!
I finally had a chance to plug the code into the compiler and give it a try. It’s pretty good, Actions look very useful!
Noticed that you get a Game Over screen if one of the projectiles goes offscreen without hitting a target. It’s fixable with a simple check of the sprite’s tag, to call the game over screen only when it is a target.
Now it’s time to look at your Box2d tutorial!
@Solivagant – Yes actions are one of the coolest things about Cocos2D imho!
Regarding the tag check, I actually mentioned that in the tutorial, but I can see that it might not have been very clear since it was at the tail end of a paragraph. I went back and bolded it to hopefully make it more clear, thanks! :]
All I can say is thank you Ray. This tutorial was wonderful and sparked hope as many others have pointed out in a lackluster area of cocos2D (examples). Going to “suggest” to the Cocos team to make this the default Cocos2D default app :P.
p.s. keep up the wonderful work with the tutorials!!
Hello!! thanks a lot ray for such a wonderful tutorial. I want to increase the difficulty of the game like removing the target after 3 or 4 collisions. I wonder if you could help to solve this out. thanks.
Hi!
One more person to join the thanks list! Great work and keep it up!
I have a question more of an Obj-C nature – you write that you can’t remove elements from array while iterating – but then after finishing the collision detection loop you iterate through the …toDelete arrays to remove the elements, so can you? can’t you? what’s the rule? – I know it’s not directly game dev related but rather language but I’d be grateful if you could clear it out – the rest is perfect and looking forward to going through the rest of your materials.
Once again thanks for introducing me to Cocos2d!
Hi Ray,
Awesome straight forward tutorial – the best I have seen for cocos2d!! Thanks!!!!!
I would also like to echo interest in a have a “part 2 tutorial” with some extras. I think adding a simple main menu, basic score system (maybe with a simple leaderboard), second level with increased difficulty (scene 2) and rotate the player to match the direction you are firing (as suggested by Jason E) would make this a killer followup tutorial.
All the best! Keep the tutorials coming!
Ray, you are my hero. :)
@Tomas – Ah yes good question! The trick is you can’t remove an element from an array while you are iterating through that array. Note that when we iterate through the xxToDelete arrays we aren’t removing items from the xxToDelete arrays – we are removing them from the other arrays (targets and projectiles) or the scene itself, which is OK.
@Khuram, @robert – Great ideas! I’ve written these ideas down for a potential sequel to this post. Thanks guys!
Thanks so much! This is exactly the speed I needed since I’m a complete newb to gaming (writing games anyway). Most tutorials I’ve seen assumed I knew way too much. This has helped a bunch!
Ray!!!!!! you are my Hero too… thank you sooo.. much for every single tutorial. God bless you.
Ray, i know this is a strange question but i dont just want to do it. i wanna make a game kinda similar to this and i wanna know if its okay with you if a use some of the code from this in my game?
also, any suggestions on where t learn about coding AI for this?
thanks,
Joseph
@Joseph – Yeah definitely, go for it! Best of luck on your game! :]
Re: AI coding – haven’t looked into this myself. But if you find anything cool or useful let me know! :]
Thank you, by the way, i am having trouble creating a new page with the Box2D to go from a menu to the first level of a game.
- (void)PlayButtonTapped:(id)sender {
[_label setString:@"Last Button: Play"];
Level1 *level1 = [Level1 node];
[[CCDirector sharedDirector] replaceScene:level1];
}
thats in helloworldscene.mm
#import “cocos2d.h”
#import “Box2D.h”
@interface Level1 : CCColorLayer {
}
@end
@interface Level1Scene : CCScene {
Level1 *_layer;
}
@property (nonatomic, retain) Level1 *layer;
@end
thats in Level1.h
#import “Level1.h”
@implementation Level1
+(id) scene
{
// ‘scene’ is an autorelease object.
CCScene *scene = [CCScene node];
// ‘layer’ is an autorelease object.
Level1 *layer = [Level1 node];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
-(id) init
{
// always call “super” init
// Apple recommends to re-assign “self” with the “super” return value
if( (self=[super initWithColor:ccc4(255,255,255,255)] )) {
// ask director the the window size
CGSize winSize = [[CCDirector sharedDirector] winSize];
}
return self;
}
@end
and thats in Level1.mm
any suggestions?
i kind of figured things out, all i really had to do was copy the gameOverScene files and change it to a .mm and it worked, as strange as it sounds
I love you, i simply love you… oh my god, you are so fucking great! Mega-exelent tutorial, i never see a more cleaver, simply and understandable tutorial like this…. you deserve to work in app develop program. i hope the best, thanks for be so great and share with us your knowledge.
nice work <3
After completing the tutorial and successfully running the game I have noticed that the animation of the “Target” sprites and “Projectile” sprites is not consistently smooth.
They both move across the screen smoothly at first, but then every 2 or 3 seconds there is a noticeable jerk to their movement. They seem to jerk forwards and then backwards rapidly as they are traveling across the screen. Somewhat like a stutter-step movement.
In addition, every time a Projectile collides with a Target this same stutter-step jerk movement occurs with everything that is moving across the screen.
At first I thought maybe this was just happening in the iPhone simulator, but when I tested the Game on my iPod Touch device, it does the exact same thing.
Why is this happening??
I have noticed this same type of jerky stutter movement on the “official” Cocos2D Demo videos that are posted on YouTube.
In complete contrast, is the newly released iPhone game called “Zombie Smash”! I have watched demo videos of this game (which uses Cocos2D and Chipmunk) and I have not noticed any jerkiness or stuttering to the game’s movement. It just looks perfectly smooth, like it should be..
That game is MANY orders of magnitude more complex than the game in this tutorial, so why does the tutorial game produce such non-smooth, jerky movement? And why do the Coco2D demos show the same bad looking motion?
I just found the solution to the problem!!
Under “Active Configuration” in Xcode (from the drop down on upper left of screen), you need to check “Release” and make sure “Debug” is NOT checked. I had Debug checked, and this must be generating a bunch of debug statements on the fly in a similar manner to having “trace” statements enabled when you compile a Flash project (which will make your Flash game slow to a crawl).
After making this change, recompiling and testing on my IPod Touch the tutorial game runs PERFECTLY SMOOTH now!! Yeay!! It even runs smooth with a 480 x 320 backdrop png image and a 480 x 320 overlay image. And with the double full screen png images it stays in the 50 to 60 FPS range! My God, this is wonderful! lol I am now officially impressed by Cocos2D!!! Wow, this makes me so happy :):):)
In comparison with DEBUG checked using my double full screen png files I was getting 20 to 30 FPS plus the jerky stuttering movement.
Thanks Ray, your tutorial was very helpful for me to make my Take a Dump App.
Thanks again
Fantastic tutorial! You have made my day with the knowledge that there are more of your great tutorials for me to read. Thank you.
One general question:
What is the purpose/benefit of the extra layer of abstraction created by declaring a “_label” variable and then declaring a property for “label” (thereby creating a getter and setter for “label”) and setting label = _label in the synthesize statement?
Hi
I want to draw a path by help of touch and projectile will move on that path only ,if on that path enemy came then they will collide or projectile will move straight from that end point.can it be possible.how i draw the path by help of finger , sprit will draw and also refer that path for movement.can you answer me.
thanks
@Jason – Rather than not using properties at all and just using member variables, you mean?
Personally I often find it easier to use properties rather than direct member variables so that it takes care of the memory management for me and I don’t constantly have to be remembering what kind of behavior I want for a member variable. I find that when I handle the memory management myself, I’m more likely to make forgetful mistakes.
So generally I like to use properties for setting variables (self.foo = xxx) and for releasing variables (self.foo = nil) but use the raw member variable for read access. I like naming the member variable with an underscore so I instantly know what I’m using at a glance.
Different programmers use different methods though, so really it’s just whatever works for you as long as everything cleans up in the end :]
@Ram: I haven’t really looked into this myself, but my first thoughts would be that you need to track the points at which the finger moves in an array, and then have a custom draw method to make a nice display for the line connecting the points. Then in your game logic, you can periodically move the sprite to the next section of the line. If there is a collision, you can clear out the stored points and change the behavior however you want. Sounds like a fun project!
Thanks for this tutorial, nicely done!
Unless I’m missing it, you neglected to mention that the needs to be added to HelloWorldScene in order to receive the touch events first introduced with the projectile.
@Thomas – I feel like a word is missing in your sentence above in “that the needs to be added to HelloWorldScene”… what needs to be added?
Oops, yes, sorry. I think you neglected to indicate that the was required to get to the ccTouchesEnded method to fire.
Thanks Ray. A really helpful tutorial :-)
Gosh this is mangling what I write when I use brackets, missing word after ‘that the’ is CCTargetedTouchDelegate
thanks ray .
Great article! Just what I needed to get me started, thank you :)
Hi Ray,
Great tutorial!!
Quick question, how would you detect collision between the player and a target?
I can’t seem to get the intersectsrect to work :/
Greetings from Finland! Thank you for your wonderful tutorials. Definitely the best way to learn cocos2d! You’re the best!
hello,
awesome tutorial! quick question, what is the best way to call this game from a tableview tabbar nav controller? (i.e. button that would take user to the game)
thanks, Simon
Hi Ray =) i’ve got one question for you about collision detection using CGRect like you do, how can you detect that two sprites are in collision when they are rectangles and that one of them has been rotated?? i can’t figure out the way to transform the CGRect so it’s at the same place as the rotated sprite… any idea? xD
thanks in advance :) you and your tutorials rock!! xD
@Swift: You should be able to check for collisions between any objects (including player and target) with a similar method of checking for rectangle intersection like we did for the projectiles and monsters.
@simon: One way is to add the top level view controller to the CCDirector window as a subview with code like the following:
And then remove the top level view controller from its superview when you’re ready to start the Cocos2D scenes.
@Saliom: You can use this method to run a transform on the rect according to the rotation, etc. (see CCNode::boundingBox for an example):
huhu cool, i looked about a rotation in a CGRect but didn’t think about a transform, very big thanks Ray ;)
Thanks a lot! Your tutorials are very clear and helpful!
Thanks. it is useful and easy to understand.
Thanks a lot !
I was looking for this “Cocos2d for dummies” tutorial for 2 days!
Thanks again! ;p
Hey first i want to say thanks a lot for the tutorial, it’s been a great help :)
I am having a problem when i run the program with the targets coming across the screen…. every few seconds they will stutter … not moving smoothly all the time… there is another comment above about the same problem and he says that he found a solution of setting the active config to release instead of debug, however this solution is not working for me i wonder if you would have any idea what the problem might be? Anybody else having a similar problem?
I would really appreciate your help!!
Thanks again for the great tutorials hope to see more :)
Hello Ray! Thanks for this amazing tutorial but i have one question. Why do you need an array to track the projectiles and the targets, can you just have a
if(CGRectIntersectsRect[x rect],[y rect])
{
//DO STUFF HERE
}
I love this tutorial! I just don’t get one part.
“Add the following to your HelloWorldScene class declaration:”
Where’s the class declaration?
Nevermind. I looked at the finished project and figured everything out. I may make a game out of this! Thanks for the help!
@Barry: When you have slowdown effects like that with Cocos2D, I usually like to check the following “low hanging fruit”:
– Make sure there are as few object allocations in the “critical path” as possible – things run much more smoothly if you allocate your objects in advance.
– Make sure there are no NSLog statements – they are slow.
– Make sure you’re using sprite sheets instead of regular sprites (see my Use Box2D For Just Collision Detection tutorial for info on that).
– Make sure you preload sound effects and textures.
– If all else fails, try profiling the code to see where the performance issue is!
@Atman: Do you mean why do we need to have the “projectilesToDelete” array etc? The reason for that is you can’t modify an array (such as by removing elements from it) while you are iterating through that array.
Ray, I love your tutorials! I noticed in the latest release of Cocos2d-iphone that they changed the name of the script to install templates. I think it’s install-templates.sh now. Thought it was worth a comment since this is such a popular place to start learning cocos2d.
@Ray Wenderlich
“Do you mean why do we need to have the “projectilesToDelete” array etc? The reason for that is you can’t modify an array (such as by removing elements from it) while you are iterating through that array.”
I do not agree. We can delete objects from array if we do iterating from the end of array. Then we are sure that index never will get out of size of the array
@William: Cool, thanks for the heads up!
@Gregory: Good point. I suppose I should have clarified that by saying “you can’t modify an array (such as by removing elements from it) while you are it iterating through that array while using fast enumeration syntax (i.e. for (CCSprite *projectile in projectiles).
Trying to modify an array while using fast enumeration syntax will result in an NSGenericException. However you are right that I could have rewritten the loop to go through it backwards, which would allow removing elements while going through:
for(int i = projectiles.count-1; i >= 0; i--) { // Do stuff, OK to remove current element }So good point, thanks for bringing it up!
@Ray Wenderlich
Yes, thanks and sorry I did not read all code in example :) but I always try to iterate backward when I have to remove some objects from array, I do not need the second array, it is quite a bit faster and needs less memory usage.
I have started yesterday learning of cocos2d and I found this usefull site. thanks for tutorials, they put some ligth on my mind hwo to use cocos2d
Thanks a lot for this tutorial! Very helpful!
I got a crash saying EXC_BAD_ACCESS when I’m trying to remove the sprite from _targets or _projectiles. Could you please tell me what could possibly be the problem? Thank you in advance!
It seems like for some reasons the sprite that is executing spriteFinishedMove isn’t passed as an argument. I try printing out the sender by using NSLog(@”%@”,sender), and it gave me the same error. :(
Sorry for spamming your entry but I just found the cause of the error. I was calling a wrong class. It is supposed to be CCCallFunc’N', with a capital N at the end. But I was using CCCallFunc, without an N. :( *sigh*
thxs for this tutorial. It’s great tutorial for getting start up with game in cocos2d.Really great :)
Thank you so much… i have been playing around with cocos2d for a while and done some stuff but this tutorial just made me learn so much and so clear written… perfect…
thanks man
Great Tutorial……
can you suggest me some links and books for iphone-cocos2d projects
please reply….Thankyou
Could you please explain why do you have separate between scene and layer, and alloc and autorelease it yourself? I thought scene and layer are autorelease classes already.
@monty: Unfortunately there are no books out yet on cocos2D – however I know two people who are writing one. So for now, the best way to learn is by tutorials online, the cocos2D sample projects, and the cocos2D forums.
If you’re looking for good books on programming for the iPhone in general, I have two I recommend on my sidebar.
@Hima: Scene is meant to represent a “screen” in a game. Each scene can have multiple Layers, for example one for a HUD control, one for the main objects, one for a background.
In this example, we keep things simple with a single Scene and a single Layer. When we create a scene we also create a layer and add it to the Scene as a child. We create the layer as autorelease so that the only retain count on the layer is only 1 once the method ends (for being in the array of children for the scene).
Not sure if that makes it clear or not, send me an email if you have further questions.
Have to say WOW ..thanks buddy for wonderful tutorial
Wow.. Just seen this on iTunes..
http://itunes.apple.com/gb/app/ninjas-vs-zombies/id359146853?mt=8
That’s not even cool.. how can someone find it acceptable to rip off your code EXACTLY as you’ve written it..
Just thought i’d bring it to your attention..
@Swift: Hehe yeah somebody else brought that to my attention as well. I don’t really mind though in this case, because the whole reason I wrote this tutorial was to make it easier for people to get started making their own iPhone games! And I kind of expected someone would make something similar sooner or later.
I’m actually glad to be able to have helped the guy get a game working, and at least he changed the art! :]
@Ray: Thank you so much for this great tutorial.
Great Job.
I was facing some problems in my game but It really helped me to complete my game.
Thanx Again
This is probably the best tutorial I have ever read. Ever. thank you much for sharing your knowledge. I will likely be adding you on my credits list when I get my game up (when that happens haha)
Hi Ray,
I’m a bit late replying but thanks for the advise regarding the slowing down issues …. its actually working ok when i test it on the iphone itself instead of the simulator so i’m happy with it so far :) My game should be done in a few weeks hopefully and i was wondering if it’d be ok with you if i tell people about it here? Maybe people can see an example from it about what can be done with cocos 2d! Maybe you could check it out yourself, it will be 79c but i will be making a donation as soon as it’s finished so that would well cover you if you wanted to have a look at it, also i could post my email address so that anyone who has questions about how i done a certain part of the game they could email me and i could let them know!
Anyway it’s cool if you prefer that i don’t as i wouldn’t want you to think i was using the forum for shameless promotion so i just thought i’d ask first :)
Either way i couldn’t have made the game without these tutorials so i am very grateful thanks so much!!
Barry
This is the best tutorial I’ve ever seen.
Thank you very much Ray..
Hi Ray,
your posts are invaluable resource for everyone :)
Just one note – the *square* of the hypotenuse is equal to the sum of the squares of the other sides of the triangle ;)
Marin
@Awais, @Mark, @March: Thanks so much for the kind words!
@Barry: Feel free to post a link to your game here! I’m glad to have been able to help a bit.
@Marin: Wow, can’t believe I missed that, thanks! Post updated :]
For all those who might be stupid like me.. If you get crash on the callback… Please make sure you set the action to use “CallFuncN” not “CallFunc”. Really hosed myself… 3 hours I’ll never get back.
— sigh!
Great tutorial though. Did learn a lot :)
Hi Ray,
I’m beginner in iphone game development.I have read your tutorial and made simple game in cocos2d.It’s a such nice tutorial.
But I’m having 1 doubt.
I’ve found from lots of tutorial that most of games are developed using OpenGL ES framework even if such nice cocos2d framework.not getting that why open Gl ES is so much used ?
So is it necessary that will i have to learn openGl ES framework for 2D game development in iphone or cocos2d is enough for making 2D iphone games?
@Nirmal:
It’s not required to use OpenGL ES to make 2D games, you can also use Quartz, but OpenGL ES is much faster than Quartz, so therefore it’s used way more, cause what developers mostly aim for is a great performance when picking a framework.
Mastering OpenGL ES isn’t neccesary for using cocos2d, since cocos2d does all the hard OpenGL ES work for you, which is why cocos2d is such a great solution.
Thanks so much :)
I’m looking to delay an action, however the solution here isn’t enough.
Stacking CCDelayTime and CCCallFunc on a CCSequence action list would generally work, but I want to call a method and also pass in some arguments. However, calling @selector(method:) will only allow me to pass the definition.
What’s the best solution to delayTime before I call a method with arguments?
@Johannes: Thanks for responding to Nirmal! I agree with your response! :]
@Pete: Check out the CCCallFuncND action, that lets you pass an argument to your callback. See ActionsTest for an example.
A-w-e-s-o-m-e
Any good tutorial on animated sprites? Going for the next step!
:)
@Xavi: Actually a tutorial on that subject just might be coming soon! O:-]
Ray, is there a way to incorporate this into a view based application? Could you do a tutorial on that?
Ray, is it possible to have 360° shooting of the projectile.
@Philip: Perhaps, added to the idea list! In the meantime though, what you need to do is just move the code that the Cocos2D template usually puts into the App Delegate into the viewDidLoad of your view controller, and modify the “attachInView” line to point to your view controller’s view rather than the window’s view.
@Anonymous: Yes, and there’s an example of how to do this in the “Tom the Turret” example that Steve Oldmeadow and I wrote. It’s available in Steve’s CocosDenshion development branch, or you can wait until it makes its way into the Cocos2D mainline in the future.
Spent the weekend walking through your tutorial. Excellent stuff! I’ve had a real hard time getting into XCode, but looking at this tutorial has really helped. Thanks :)
Ray –
Great tutorial.
Should the code compile and run properly in Xcode v 3.2.3?
I am able to compile and run the shooting projectiles portion of the tutorial, and it compiles, runs however when I touch the screen it does not shoot the projectiles.
Any help would be great!
ahhh… looks like the line “self.isTouchEnabled = YES;” needs to be imbedded in the if statement in the init method.
Really good tutorial, many thanks for sharing your knowledge !
Absolutely fantastic tutorial to get a complete beginner up to speed!
Please keep them coming, hungry for more…
Thanks
I still cannot get the pew-pew-lei sound to play? I have tried on various targets but still no joy.
Have tried the preloadEffect too?
Oddly tho the background music plays a treat!
Any ideas?
Thanks
@elpuerco: I just downloaded the sample project and it appears to be playing the pew-pew-lei sound OK for me. Have you tried the sample project (and trying both a device and the simulator – sometimes the simulator has issues)?
You are right, thanks…it all works fine on the device
;-))
Can you suggest what tool a novice should use to make their own music and sound affects?
Great tutorials…..having a lot of fun learning!
@Elpuerco: w00t glad it works!
Check out my series on Audio 101 for iPhone Developers for tips on good software to use to make music and sound effects!
But the TLDR version is: Garage Band, Audacity, CXFR :]
Hi, so your tutorials have me racing into games programming using your techniques and COCOS2D and so far all is going well on the iPhone.
But ideally I want to replicate this tutorials output to the iPad, which it does but only as an iPhone version running in an iPad window?
When I choose to create a new cocos2d app the option to upgrade project to target iPad is disabled?
Does cocos2d template not allow switching to iPad?
Thanks
After much searching have found you need to select the actual target itself in order to get the menu option to be enabled.
I was selecting the top level group Targets hence the greyed out option!
Have posted this one the cocos2d forums but will aske here too ;-)
I have just managed to get my iPad startup application to display a background image, but it is in the wrong position and size?
I use this in my init method:
-(id) init
{
// always call “super” init
// Apple recommends to re-assign “self” with the “super” return value
if( (self=[super init] )) {
CCSprite *bg = [CCSprite spriteWithFile:@"myimage-ipad.png"
rect: CGRectMake(0, 0, 1024, 768)];
bg.position = ccp(0,0);
[self addChild:bg];
}
return self;
}
But what I get is this image in the lower left of the iPad landscape view, as if taking up the lower left quarter of the dispay?
The image is 1024 * 768
Do I need to tell cocos2d something to make it display image in correct size?
Thanks
answered ;-)
You only use the spriteWithFile:rect: method if you want to create a sprite based on a section of an image, such as a sprite sheet. If you want to use the whole image use the regular spriteWithFile method.
Sprites have a default anchor point in the center. If you set the position to 0,0 then the center of the image is at 0,0. To make the image center on the iPad you need to put it at the center of the screen, like this:
CGSize s = [CCDirector sharedDirector].winSize;
[bg setPosition:ccp(s.width/2, s.height/2)];
This will position the image centered in the screen, every time.
Hello
i want to place a background image in Layer.
what method or function should i use for that as
you used :
if( (self=[super initWithColor:ccc4(255, 255, 255, 255)] ))
for colored background.
please reply me if you have time.
thank you for your time.
I used this to place an image as my background. I read that this was the way to do it…someone correct me if i am wrong!
CGSize winSize = [[CCDirector sharedDirector] winSize];
CCSprite *bg = [CCSprite spriteWithFile:@"mybackground.png"];
[bg setPosition:ccp(winSize.width/2, winSize.height/2)];
[self addChild:bg];
@elpuerco: Glad you got the questions you had earlier resolved – sorry it took me a while to get to these comments!
The code you showed @Asad about how to place an image as your background is good. One thing to keep in mind is that by default, the anchor point for a sprite is the exact middle of the sprite. So wherever you set the position to will be the middle of the sprite (not the lower left corner or something), unless of course you change the anchor point.
Hey my game is out now on the app store :) it’s called monkey punch, it’s completely made using cocos 2d. If anyone would like to check it out the link is below … thanks Ray for permission to post it :) I am a complete beginner and these tutorials were so valuable to me as a great starting point!!
Anyone here can email me at admin@monkeypunchgame.com and ask any questions about the game or the process of submitting an app to apple i’ll be happy to answer questions or take suggestions.
Good luck with the games to everyone!
Thanks.
Ooops forgot to give the link to the game!!
http://itunes.apple.com/ie/app/monkey-punch/id378776540?mt=8
@Barry: Congrats Barry and best of luck with the Monkey Punch!
Hi Sir,
I am using your sample code, i want to add one more functionality to your code, when the player hits the target with projectile, i want to add fire effect to the scene. Please help me in this case.
Thank your so mcuh,
Muzammil
thanks Ray, u help me a lot!
if u solve the “sound once problem”, please update it :)
@Muzammil: All you need to do is create your effect node (such as CCParticleFire) and add it to your scene.
@catge: I’m not sure what you’re referring to?
Hi Ray,
We are trying out a small game.
Could we use your sound files in our game
pew-pew-lei.caf
background-music-aac.caf
Thank you
Regards
Abhilash Vijayakumar
Ray (or anyone looking at this blog) – is there a way to implement some code to pause the game using a button?
Hi Ray,
I am trying to learn the correct way to deal with touches in cocos2d regarding sprites. I read that only cclayers can have touches so from this I presume no matter how mant objects I have on the screen ALL touches have to be processed by the cclayer?
In normal cocoa I would sub-class an UIImage and have my touch detection in that sub-class, but I understand this is not the way to do it in cocos2d?
I have now managed to get my app to detect the touches for two sprites I have setup as buttons to control the players sprite movement like this:
- (void)ccTouchesBegan:(NSSet*)touches withEvent:(UIEvent*)event {
UITouch* touch = [touches anyObject];
CGPoint location = [[CCDirector sharedDirector] convertToGL: [touch locationInView:[touch view]]];
CGSize s = [[CCDirector sharedDirector] winSize];
if ( CGRectContainsPoint(leftButtonRect, location) ) {
[player runAction:[CCSequence actions:
[CCMoveTo actionWithDuration: 0.5 position: ccp(player.contentSize.width / 2, player.position.y)],nil]];
return;
}
if ( CGRectContainsPoint(rightButtonRect, location)) {
[player runAction:[CCSequence actions:
[CCMoveTo actionWithDuration: 0.5 position: ccp(s.width - player.contentSize.width / 2, player.position.y)],nil]];
}
}
- (void)ccTouchesEnded:(NSSet*)touches withEvent:(UIEvent*)event {
[player stopAllActions];
}
This works OK when I have two buttons for direction movement, but now I am adding a fire button and am finding that if I am holding down one of the movement buttons then at the same time press the fire button the movement is cancelled.
I’m trying to understand the TargetedTouchDelegate but it appears to be hurting my brain!
Any tips?
Thanks
@Abhilash: Sure, and good luck with your game!
@Art: Yeah that’s pretty easy, just add a button with the following tutorial:
http://www.raywenderlich.com/414/how-to-create-buttons-in-cocos2d-simple-radio-and-toggle
And in your button’s callback, call [[CCDirector sharedDirector] pause].
@elpuerco: You might want to check out the above button tutorial as well, that might be better than implementing your own button classes.
@Ray… thanks – that pauses the game, but what do I do to start it up again with that same “state”?
@Art: There’s a corresponding method [[CCDirector sharedDirector] resume.
Thanks a lot of this entry !
I’m very interested in creating games with cocos2d, but its documents are written by English and bad contents.
But ! Your Entry is very easy English and high quality !So, I understand cocos2d more than before read.
Thanks to this entry, I translated this entry to Japanese.because I want to let everybody know cocos2d merit !
If you understand Japanese or love Japan(WHY Ninja?), read!
http://d.hatena.ne.jp/jarinosuke0808/20100704/1278224685
Hi Ray
Yes my first attempt at the buttons was to implement the menu approach but soon I realised a problem.
I need to detect when the user holds and releases buttons so when holding the left button the player moves left and when the release the button the movement stops.
The menu approach just kicks off the movement and continues moving regardless of holding the button or not.
I have using the code sample I posted the left and right movement working as required but now trying to implement the fire button without it interrupting the movement button operation.
Does that make sense?
Thanks
Maybe helpful for those looking for music for their apps?
http://www.freesound.org/
hey Ray,
thanks for the tutorial, but i have a question if you don’t mind. i’ve been trying to add a menu screen to this tutorial. i was success in adding the menu scene, however, this game alone seems to be working when it is on the HelloWorldScene.h/.m. I was wondering what the problem was…if there was some special codes need if i wanted to use the codes above on a different .h/.m.? for example, NewGame.h/.m.
thanks!
Wow! Thanks a lot for this excellent tutorial!
Finally now I am able to develop something to Iphone! This is the best newbie’s tutorial of all!
@jarinosuke: Very cool! Thanks for taking the time to translate the article and provide the backlinks. I do love Japan – I was there visiting a friend about a year ago! Visited Tokyo, Misawa, Osaka, and another city famous for its ceramics which I have forgotten :] Was a blast, and we loved the sushi!
@elpuerco: Ah I see, you may want to either customize the way the buttons work by customizing the ccTouchBegan/ended methods, or look into using a Cocos2D joystick class like SneakyJoystick:
http://github.com/wiseganesha/SneakyJoystick
Thanks for sharing the link too!
@Phil: Might want to check out part 3 of this tutorial, where we cover how to use different scenes in different files. Hopefully that will help!
@Cezar: Thanks – and good luck with your upcoming apps! :]
I was wondering if you could show me how to make it so when the “ninja star” gets to the position of the touch it does an action.
dear ray
How to apply an animation Targets
Look forward to your reply
@Stefan: To do that, replace the call to [targetsToDelete addObject:target] with whatever you want to do inside the update method.
@CB: I’m sorry I’m not quite sure what you’re asking? But since it’s about animation, the following tutorial might help:
http://www.raywenderlich.com/1271/how-to-use-animations-and-sprite-sheets-in-cocos2d
Sorry Ray。
I only speak a little English。
I want to say
CCSprite *target = [CCSprite spriteWithFile:@"Target.png"
rect:CGRectMake(0, 0, 27, 40)];
I created an animation, but is unsuccessful.
How to target the right shows an animation.
And auto move.
Thank you.
You are the man, thanks so much!
This is how I got my app to handle different button taps:
#import "cocos2d.h" #import "ButtonDelegate.h" @interface Button : CCSprite { id delegate; int buttonType; } @property (nonatomic, assign) id delegate; @property int buttonType; @end -------------------------------------- #import "Button.h" @implementation Button @synthesize buttonType, delegate; - (CGRect)rect { CGSize s = [self.texture contentSize]; return CGRectMake(-s.width / 2, -s.height / 2, s.width, s.height); } - (void)onEnter { [[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self priority:0 swallowsTouches:YES]; [super onEnter]; } - (void)onExit { [[CCTouchDispatcher sharedDispatcher] removeDelegate:self]; [super onExit]; } - (BOOL)containsTouchLocation:(UITouch *)touch { return CGRectContainsPoint(self.rect, [self convertTouchToNodeSpaceAR:touch]); } - (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event { if ( ![self containsTouchLocation:touch] ) return NO; return YES; } - (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event { switch (self.buttonType) { case 0: [delegate movePlayerLeft]; break; case 1: [delegate movePlayerRight]; break; case 2: [delegate stopPlayerMovement]; break; default: break; } } @end --------------------------------------- // ButtonDelegate.h @protocol ButtonDelegate @optional -(void)movePlayerLeft; -(void)movePlayerRight; -(void)stopPlayerMovement; @end;-))
@CB: If the animation tutorial doesn’t help, another good example of how to implement animations is SpriteTest.m that comes with Cocos2D. In particular, check out lines 1508-1521 in Cocos2D v 0.99.4-rc3.
@elpuerco: Cool, thanks for sharing! Formatted your comment a bit to show the code better too :]
What do you mean when you say, “After you pull down the code, you’ll want to install the useful project templates. Open up a Terminal window to the directory you downloaded Cocos2D to, and enter the following command: ./install_template.sh,” could you please go into further detail? Sorry, I’m absolutely new to this field Programming and getting more and more frustrated.
Thanks ray of enthusiasm to help
Thank u
谢谢你。
I was trying to figure out ways to change the sound effects and the images, just to test out the ways I can change it. Thanks so much for the guide! It really helped me a lot!
@R Sarsam: Ah no problem – there is a lot to learn at the beginning, isn’t there? Anyway Terminal is an application that comes with Mac OSX that lets you type in raw commands to the OS. To run it, go to Applications\Utilities\Terminal. You also may want to read up on basic Unix commands to switch directories etc, such as:
Command Line Fundamentals PDF
@BBQ, @CB: Great glad it helped! :]
Sorry I think you misunderstood. I was wondering for help on how to change the images and the sounds. When I tried putting my own effect in for the other one, it wouldn’t work even though I changed where it is referenced in the application.
This tutorial is really awesome and I’ll definitely recommend it to my friends :). I took an entire class on iPhone development at my school and this tutorial has been far more useful for starting a game project.
Hi! I’m new to programming in general and I really like your tutorial. However, I have encounter a problem. Everything was working fine just before I started implementing the moving targets. Just before the projectile part, I tried compiling and it did without error, but it does not seem to be loading on my ipodtouch, (it stays on the cocos2d screen for ever) and on the simulator it just crash as soon as I open it. Could you help me please?
This is my entire coding if need be.
//
// HelloWorldLayer.m
// Test1
//
// Created by Tassos Karras on 10-07-16.
// Copyright __MyCompanyName__ 2010. All rights reserved.
//
// Import the interfaces
#import “HelloWorldScene.h”
// HelloWorld implementation
@implementation HelloWorld
+(id) scene
{
// ‘scene’ is an autorelease object.
CCScene *scene = [CCScene node];
// ‘layer’ is an autorelease object.
HelloWorld *layer = [HelloWorld node];
// add layer as a child to scene
[scene addChild: layer];
// return the scene
return scene;
}
-(void)spriteMoveFinished:(id)sender {
CCSprite *sprite = (CCSprite *)sender;
[self removeChild:sprite cleanup:YES];
}
-(void)addTarget {
CCSprite *target = [CCSprite spriteWithFile:@"Target.png"
rect:CGRectMake(0, 0, 27, 40)];
//Determine where to spawn the target along the Y axis
CGSize winSize = [[CCDirector sharedDirector] winSize];
int minY = target.contentSize.height/2;
int maxY = winSize.height – target.contentSize.height/2;
int rangeY = maxY – minY;
int actualY = (arc4random() % rangeY) + minY;
//Create the target slightly off-screen along the right edge,
//and along a random position along the Y axis as calculated above
target.position = ccp(winSize.width + (target.contentSize.width/2), actualY);
[self addChild:target];
//Determine speed of the target
int minDuration = 2.0;
int maxDuration = 4.0;
int rangeDuration = maxDuration – minDuration;
int actualDuration = (arc4random() % rangeDuration) + minDuration;
//Create the actions
id actionMove = [CCMoveTo actionWithDuration:actualDuration
position:ccp(-target.contentSize.width/2, actualY)];
id actionMoveDone = [CCCallFuncN actionWithTarget:self
selector:@selector(spriteMoveFinished:)];
[target runAction:[CCSequence actions:actionMove, actionMoveDone, nil]];
}
-(void)gameLogic:(ccTime)dt {
[self addTarget];
}
// on “init” you need to initialize your instance
-(id) init
{
if( (self=[super initWithColor:ccc4(255, 255, 255, 255)] )) {
CGSize winSize = [[CCDirector sharedDirector] winSize];
CCSprite *player = [CCSprite spriteWithFile:@"Player.png"
rect:CGRectMake(0, 0, 27, 40)];
player.position = ccp(player.contentSize.width/2, winSize.height/2);
[self addChild:player]; }
[self schedule:@selector(gamelogic:) interval:1.0];
return self;
}
// on “dealloc” you need to release all your retained objects
- (void) dealloc
{
// in case you have something to dealloc, do it in this method
// in this particular example nothing needs to be released.
// cocos2d will automatically release all the children (Label)
// don’t forget to call “super dealloc”
[super dealloc];
}
@end
Hey Tassos,
When asking for help you need to give a little more so people can help. Try looking inside the console to see any errors and then post them here. It is much easier when we know what the problem is.
@BBQ: There’s no reason you shouldn’t be able to replace the sounds with your own, as long as you included it in your project and it is in a sound format supported by the iPhone.
@William: Wow thanks, that is a nice compliment! Thanks for passing on the article as well.
@Tarros: When you have a problem like that (it’s staying on the cocos2D loading screen forever), a good way to debug is to set a breakpoint inside the init method for your scene and step through until you find the area where the problem is. A lot of times, it’s due to referencing a file that isn’t there or some such.
I found my problem, I wrote gamelogic [self schedule:@selector(gamelogic:) interval:1.0];
when I should have wrote gameLogic (L not l)…
Thanx for the tip, but if you dont mind me asking, how exactly do you debug using breakpoint? I know I can press on break point at the top of xcode, but i’m unsure on what to do afterward. If its not too complicated, could you please explain? I’m sure that would be a great help later on. Thanx a lot for your tutorial, you explain really well.
@Tassos: Explaining the debugger in XCode is a large topic (too large to discuss in a comment!) but luckily the folks at Apple have written a great guide:
http://developer.apple.com/mac/library/documentation/DeveloperTools/Conceptual/XcodeDebugging/000-Introduction/Introduction.html
It’s definitely worth the time to learn, a debugger is an invaluable tool for a programmer!
I have followed the tutorial through the end of “Moving Targets.” I get a warning in Xcode on the line
[self addTarget]
that – ‘HelloWorld’ may not respond to ‘-addTarget’.
The game runs, but then crashes as soon as a bad guy would be removed after it has moved off the screen. I have checked my program multiple times and cannot find where I made a mistake. Any help would be really appreciated.
Hi Ray,
Thank you for your excellent tutorials and permission to use the music files. Pls find our first game ‘Fire Stick Man’ link below.
http://itunes.apple.com/us/app/fire-stick-man/id381652896?mt=8
Regards
Abhilash Vijayakumar
thanks a lot for this great article
@smd: That indicates that you are calling a method on the HelloWorld class named addTarget, but the compiler cannot find such a method. I would check that your method is spelled correctly, and that you have added it inside the @implementation HelloWorld section (not the @implementation HelloWorldScene section).
@Abhilash: Congrats on your release!
thanks a lot for this wonderful tutorial .
Thanks so much Ray for this article. It’s the best article I’ve found on using Cocos2d for the iPhone. I have been debating on whether or not to use a third party SDK, such as Ansca Corona, but I find that Cocos2d is nice because it’s using pretty standard Apple stuff, and it’s not difficult once you have someone knowledgeable and friendly, such as you, help to get you started.
Best of luck to you and your future endeavors!
David
@David: Thanks, glad it was helpful! Yeah I’ve been quite happy with Cocos2D, I think it’s a great framework and has an active and friendly community. Best of luck to you as well!
Hey again Ray :)
I just noticed something:
CGRect projectileRect = CGRectMake(
projectile.position.x – (projectile.contentSize.width/2),
projectile.position.y – (projectile.contentSize.height/2),
projectile.contentSize.width,
projectile.contentSize.height);
Why is the collision bounding box a half before the sprite?
I mean, why just not:
CGRectMake(
projectile.position.x,
projectile.position.y,
projectile.contentSize.width,
projectile.contentSize.height);
Since it is “bounding” the sprite?
I tried, but really didn’t understand it :P
Thanks!
Hmm is it because the update function run before the draw? So a bounding box is drawn on the next sprite’s position and check collision ahead?
Nice tutorial……
@Alfred: That’s because the anchor point of the sprite by default is (0.5, 0.5), which means exactly in the middle of the sprite. So when or get/set the sprite’s position, that is actually getting/setting the position of the center of the sprite. So to get the bounding box, you have to subtract half the width/height of the sprite to get the full box!
This tutorial is really amazing, and got me developing really quickly, but I have one question: How do I turn this into an iPad app? I have downloaded the latest version of xcode, and I’ve ran the actual app in the iPad simulator, but how do I make it an iPad app? If you don’t know, its fine, but just let me know.
Very good tutorial. It gives just enough information– not too simple and not too complex. You should write a book.
@Sean: To upgrade this game for the iPad, open up Targets, select Cocos2DSimpleGame, then click Project\Upgrade Current Target for iPad in the menu. Select One Universal application, and click OK.
At this point you should be able to run the game on the iPad. However you’ll probably want to tweak the values in the game (such as the speed of the monsters, size of the sprites, etc) because as-is they are optimized for the size of the iPhone screen.
I’m having the same question as Sean Spencer. I tried using your solution. I went to Project>Set Active Target>Cocos2dSimpleGame. When I went to click on the Upgrade Current Target for iPad, it didn’t work. Is it not in the menu? Please help!
As a side note, I have Xcode version 3.2.3 and the iOS 4 SDK. I am using the cocos2d version 0.99.3
@BBQ: You have to make sure you have the target selected, or the menu item will be grayed out.
excellent tutorial, thanks so much for the great job =)
Hi,
Nice tutorial but i have one problem can you help me?
I want to add background image for this game and after that want to give menu to change background image of this game.
So after select new background image that image should be come in game background
can you say me how can i do it?
Right now i have done below things but its showing me old background image only.
I have created 3 scenes one is game, second is menu and third is set background now if user will click on change background menu then i am using UIImagePicker control to give choice for background images after that if user will choose any image then i am adding that image into game scene. for add image in game i have created object of game in set background file.
But its not working so can you help me?
@Nandini: Once you have the UIImage, you can initialize a sprite with [CCSprite spriteWithCGImage:image.CGImage], and add that to your scene.
Thank you for reply
Its not working :(
i have called that layer object and add image on that layer but its not showing latest image.
Thanks,
@Nandini: That should work, if it’s not you’ll have to debug through your project and see where the problem is. Try first by having the background sprite use an image that comes with your project and make sure that works, then try replacing the sprite image with one from the image picker, etc…. basically narrow it down step by step.
Thanks for excellent tutorial. I have a question. In GameOverScene.m you have a method called gameOverDone that looks like:
- (void)gameOverDone {
[[CCDirector sharedDirector] replaceScene:[HelloWorld scene]];
}
Isn’t the call [HelloWorld scene]] creating a new Helloworld scene and a layer on top of the existing Helloworld scene and layer. I’m new to cocos2d so probably I miss something in my understanding.
Hi Ray,
Thank you so much for help me.
Yeah you are right
its working now
but now i have another problem
like after set new background my object is not showing in game layer
Its looking like zindex problem if i am setting it z:-1 to new image then old background and objects are coming but if i will set z:0 then new background coming only no objects are there
can you help me on this problem?
Thank you,
Forget my earlier question. The answer can be found at
http://www.cocos2d-iphone.org/forum/topic/8457
Hi,
Its done
Thanks,
@Bob, Nandini: Heh was about to reply to you guys but looks like you got it working! Sorry it took me a while to respond, but glad it’s working for you.
Hey Ray,
Thanks for the awesome tutorials. They really helped getting me started!
Quick question though, when I call the HelloWorld scene again from the GameOver scene, my app errors out with a EXC_BAD_ACCESS code.
I did major changes to the tutorial app and am wondering if this is because something I forgot to dealloc before calling the game over scene?
@Sulz: The only way to find the cause for something like that is via debugging, as it depends on the app. Here’s a couple things to try:
1) Set a breakpoint in the init method for your HelloWorld scene and step through until you narrow down where it’s crashing.
2) Set the NSZombieEnabled argument in your executable options, which sometimes helps narrow down the cause
3) Tried and true “comment out code till it works” then backtrack from there :]
Good luck!
Well I managed to identify the problem is here:
// ‘layer’ is an autorelease object.
HelloWorld *layer = [HelloWorld node];
// add layer as a child to scene
[scene addChild: layer];
When it runs the addChild line it errors out. Any ideas? I can’t seem to figure out why!
Found it!
I was manually releasing the _layer on the GameOver.m file, but found that if you addChild, you should let Cocos automatically release it using only the super dealloc.
Ray, is it possible to have 360° shooting of the projectile??? The link you posted doesnt work anymore!
@Ray
How must I change the code you written that I can shoot 360°??
@Ray ok i found it now…
but i have an another question:
How can i implement a joystick (from the sneakyjosytick library) and shoot with that?
CAN YOU PLEASE MAKE A CODE SNIPPET OR A TUT?
please
you are the best i know
Wonderful tutorial!
One question, when the screen is replaced with the win/lose scene. Why is the screen only kept for a few seconds and is changed to back to the original screen? Thanks!
Thanks for your hard work! It’s very useful for me.
@Suiz: Glad you got it working!
@stuffCoolStuff: I’ve added the idea of writing a SneakyJoystick tutorial to my idea list!
@mjshi: No particular reason except that’s how I decided to make it work.
Just to let everybody know, if there’s an error installing the templates you might need add a “-f” flag after “install-templates.sh”, you also might need to add “sudo” before all that.
Hi Ray,
Thanks for another great post. I downloaded the code and tried running as is after selecting the provisioning profile and sdk, but I get the following error when trying to run it:
Check dependencies
[BEROR]No architectures to compile for (ONLY_ACTIVE_ARCH=YES, active arch=armv6, VALID_ARCHS=i386 ppc ppc64 ppc7400 ppc970 x86_64).
Do you know how to correct this? I am still new at all this. Please advise. Thanks!
Hi Ray,
Please ignore the previous post,
August 17, 2010 at 1:13 am, since I manually re-created the project above and it works fine now. Excellent, excellent tutorial!!! Keep these coming.
Hi Ray,
Thank you very much for this tutorial. I have gone through it and have a far better understanding of cocos2d now. I have also started a new project and used bits of code here and there from this tutorial for creating my own space shooter game now (obviously with lots of changes and my own twists). Progressing nicely!
Hi Ray,
I have test this sample project with memory leak in simulator and some memory leak is showing in audiotoolbox.
so for that should i do anything?
should we release SimpleAudioEngine?
Thanks,
Awesome dude. nice explanation you had provided. It’s really help me a lot to understand the basic of Coco2d.
@Sean: Awesome, best of luck with your game!
@Nandini: If there’s a memory leak I’d recommend dropping a note in the Apple bug tracker or cocos2D bug tracker (depending on where the leak is) so it can be fixed if appropriate. But I’ve shipped two projects with Cocos2D w/ SimpleAudioEngine code as-is so if there’s a leak it’s not noticeable in practice.
Hey Ray what should I do if I want to make the ninja stars rotate at the same time they are moving forward?
Best Regards
Hi Ray,
Thank you so much for your tutorial. I wanted to add a custom image in the NewLevelScene background (the one that has “Get ready!”). I wanted to base it off of what level you’re on.
In my app delegate file, I added:
Level *level1 = [[[Level alloc] initWithLevelNum:1 spawnRate:2 bgImageName:@”bg.png” mapBgImageName:@”levelMap1.jpg”] autorelease];
In NewLevelScene.m I am trying to access the new image by doing something like:
Cocos2DSimpleGameAppDelegate *delegate = [[UIApplication sharedApplication] delegate];
NSLog(@”delegate.curLevel.mapBgImageName is %s”, delegate.curLevel.mapBgImageName);
but it says “unknown component of property”. Do you have any idea why I can’t get a reference to the jpg like that?
Edit: Sorry I figured it out! I did something like…
if(delegate.curLevelIndex == 0) {
} … and based on what this value was, I picked the image to show.
Sorry to comment so many times! I sort of have it working but do you have a suggestion that is more elegant? I have 9 levels and so far it’s a mess of if statements. Thank you!
@Ray Thank you very much! I have got my own control system using the accelerometer going now :) Your tutorials have given me a great start :)
@Carlos,
I learnt how to do rotation the other day. As far as I know, the best way to rotate a sprite is use an action.
I do:
id action = [CCRepeatForever actionWithAction: [CCRotateBy actionWithDuration:3 angle:360]];
[projectile runAction:action];
where projectile is the sprite I want to rotate and 3 is the amount of seconds the action should take to complete. 360 is the degrees to rotate the sprite. i.e. a full circle. Hope that helps :)
Thanks Ray! worked like a charm!
Thank you and your wife so much.
In fact, i have used your blog before, like xml etc…
Really really thanks.
Hello,
and thanks for the great tutorial.
Regarding the sound problem, i.e. that the background music does not play constantly in a loop but stops after its first playback.
It is NOT a software issue as described, either a version bug.
The problem is in the sound format, or the sound file itself.
I opened the file and saved it under a different name, and with bit depth 16 bit.
No changes in code, and the background sound loops and loops and loops. :)
Years of software testing taught me, to look for a bug in the most obvious place, that is the file itself in this case.
cocos2d 0.99.5
Dino
@Carlos: You can use the CCSpawn action to run multiple actions at once. See the HelloActionsSample that comes with Cocos2D for an example.
@Janice: For suggestions on how to handle multiple levels, check out part 3 of this tutorial.
@Sean: Awesome! Best of luck with your projects – and thanks so much for helping out everyone here too!
@Dino: w00t thanks for sharing that so that others may benefit!
This is the article I’m looking for. Thanks!
Great tutorial!
One question about the sound loop issue. With which application do you open the sound file? And, how do you then modify the bit depth?
Thanks
Jon