navigate site menu

Start learning with our library of video tutorials taught by experts. Get started

Building and Monetizing Game Apps for iOS
Mark Todd

Building and Monetizing Game Apps for iOS

with Todd Perkins

 


Author Todd Perkins uses Objective-C and Xcode to build Mole It!, a full-featured game app for the iPhone and iPad that can be downloaded for free from the iOS App Store. The finished app implements Game Center functionality as well as channels for generating revenue. The course also introduces the open-source gaming framework cocos2d and explains the fundamental classes necessary for creating a game. Todd also shows how to incorporate multi-touch capabilities, customize a game's appearance, set up iAds and in-app purchasing, and configure leaderboards that record and display scores.
Topics include:
  • Using scenes, layers, and sprites
  • Accessing accelerometer data
  • Understanding cocos2d actions
  • Creating simple frame animations
  • Handling touches in a game
  • Adding sound
  • Enabling a pause feature
  • Including support for Retina display and the iPad
  • Understanding iAd, Store Kit, and Game Kit delegate methods
  • Using the cocos2d forums

show more

author
Todd Perkins
subject
Developer, Mobile Apps, Games
software
iOS 5, 4, Xcode 4
level
Intermediate
duration
2h 58m
released
Oct 25, 2011

Share this course

Ready to join? get started


Keep up with news, tips, and latest courses.

submit Course details submit clicked more info

Please wait...

Search the closed captioning text for this course by entering the keyword you’d like to search, or browse the closed captioning text by selecting the chapter name below and choosing the video title you’d like to review.



Introduction
Welcome
00:04Hi! I am Todd Perkins.
00:06Welcome to Building and Monetizing Game Apps for iOS.
00:10In this course, you will learn the ins and outs of working with cocos2d to use
00:14Xcode to build an iOS game.
00:17The game is full-featured and implements multi-touch Game Center leaderboards,
00:24in-app purchases, iAds, and many other features using cocos2d.
00:28We will start with the basics,
00:32learning how cocos2d works.
00:33You'll learn the fundamental classes of cocos2d, and you will use those classes
00:39to build a full-featured game.
00:42I hope you're ready for an exciting experience building and monetizing game
00:46apps for iOS.
Collapse this transcript
What you should know before watching this course
00:00Due to the advanced nature of this course, I highly recommend coming in with a
00:05background in iOS experience.
00:08You should be familiar with Objective-C and feel very comfortable doing
00:12object-oriented programming.
00:14While you don't have to know every Objective-C class, you should be familiar with
00:19saving data to user defaults, NSString, NSArray, and NSMutableArray, and working
00:25with primitive data types like integers and floats.
00:28If all of those things sounded familiar to you, great; you're ready to move
00:31forward and get started.
00:33If any of that sounded foreign to you, I recommend looking at the Objective-C
00:37and iOS courses in the Online Training Library.
00:40It's best that you feel comfortable with object-oriented programming and
00:44Objective-C before moving forward with this course.
00:47Now if you feel comfortable then you're ready to go.
Collapse this transcript
Using the exercise files
00:00If you are a Premium subscriber to lynda.com or have purchased this title on a
00:04disc, then you have access to the exercise files for this course.
00:09Exercise files are organized by chapters.
00:12Outside of all the chapters is a folder called assets.
00:15That folder contains all of the assets for the projects we will be working with
00:19as we build Mole Hit! application.
00:21The individual chapters contain folders, and those folders contain the start and
00:26final versions of each project we will be working on in a particular movie.
00:31As you go throughout the course, you'll see what files you need to open up on your screen.
00:36If you have access to the exercise files, don't worry; you can still follow along.
00:40Throughout the course I'll explain how you could set up your files in the
00:44same way so that you could follow along and build a similar application on your own.
00:48So once your exercise files are set up, you're ready to move forward with
00:52building and monetizing an iOS game.
Collapse this transcript
Fixing errors in Xcode 4.6
Collapse this transcript
Viewing the finished game
00:00The game we are going to build in this course is based on the free version of Mole It!
00:04that you can find in the App Store.
00:06So if you'd like to follow along, feel free to download that game.
00:11From the main menu, you'll see some buttons at the bottom, such as Game Center,
00:16More Games, and Skins.
00:18Game Center will show a leaderboard with all of the scores ranked from highest
00:24to lowest, so that players can compete with other players all around the world.
00:29More Games shows a link to other games created by my company, Wedgekase Games.
00:34Skins enables you to choose between different artwork sets of the game.
00:38So you can click on the alien to use the Jetpack Handyman skin based on
00:43another game called Jetpack Handyman, or you can click on the mole and use the standard moleskin.
00:50Click to play the game.
00:52So here you can tap on the various moles, and you will see that the score goes up
00:56as you tap them. And when you miss a mole, a carrot disappears.
01:01Once all the carrots are gone, you get a game-over.
01:04You will also notice blue moles and yellow moles.
01:08The blue moles take two taps, and the yellow moles must be tapped simultaneously.
01:15So once you get a game-over, you can choose to play again or return to the main menu.
01:20Some additional features of this game that we will add later on are in-app
01:24purchases to purchase the Jetpack Handyman skin and we will add iAds so that you
01:30can generate revenue while people are playing your game.
01:34So as you can see, we are going to be building a full-featured game
01:38throughout this course,
01:39so I hope you're ready for a good time.
Collapse this transcript
1. Getting to Know Cocos2d
Understanding cocos2d
00:00You may be wondering why I chose cocos2d over all of the other alternatives
00:04for making an iOS game.
00:06There are two main reasons for that:
00:08for one, cocos2d uses Xcode, which I really like, and the second reason is
00:13that cocos2d I've found is the easiest way that you can create a full-powered iOS game--
00:20in other words, it's the easiest to understand and the easiest to learn over all
00:24of the other alternatives.
00:26So if you just start with Xcode without cocos2d, the closest thing to creating a
00:30game is the template for the OpenGL ES application.
00:34Now if you test this application in the simulator, you'll see that all you get
00:39is a square that moves up and down--not very exciting.
00:47Further, let's take a look at all of the code it takes to make that square move up and down.
00:52So if I scroll down in TestViewController.m, you will see a lot of code, and it
00:56will take a while to really understand what's going on.
01:01Now let's look at a cocos2d example.
01:03Here is my cocos2d project.
01:05The init method contains all of the basic code to create the app, and you will
01:09see that it's pretty easy to understand, and you can kind of guess what it's
01:12going to do before you even test the app.
01:14I will just test the app right now, and we will take a look at it in the simulator.
01:17Again, if you don't have the template installed, don't even worry about writing
01:22the code or following along for this; just watch my screen.
01:24So all we have is Hello World text on the screen.
01:30It's not moving like the square, but we do have a lot less code.
01:33Let me show you that we can just animate that just like the square moves with
01:38one line of code. Granted it may be a complex line of code, but it's one line of code.
01:42So let's take a look at how easy it is to move the label up and down with one line of code.
01:47So all we do is run a command--
01:49again, you don't have to worry about following along with this; just watch my screen.
01:52Send a message to that label that says Hello World.
01:56We tell it to run an action.
01:57The action is something that's going to go on forever.
02:01So I type CCRepeatForever, an actionWithAction, and the action is going to be
02:06something that moves it down and moves it back again.
02:09So that's a sequence of different actions.
02:12I am going to separate this on different lines so it's a little easier to read.
02:16I know I said it would be one line, but technically this could obviously fit on one line.
02:20I am just doing this for readability purposes.
02:23So I tell it to move in one second, and I will tell it to move down a hundred pixels.
02:37This is an X-Y coordinate right here.
02:39I'll just copy and paste that line, and that's it.
02:47I'll test this in the simulator, and you'll see Hello World moving up and down.
02:52Now that's not super impressive, but keep in mind, that took one line of code
03:01from the basic cocos2d template.
03:04So it's clear that cocos2d is more concise and easier to understand than just
03:10starting with a blank OpenGL ES application.
03:13To go back to my first point, why I like cocos2d,
03:16g we get to use Xcode, so we have access to all of the code hinting, code coloring,
03:21and all the other features that make it easy to create an iOS application.
03:24So throughout this chapter, we will start at the beginning and you'll learn how
03:28to make basic gameplay elements using cocos2d.
Collapse this transcript
Downloading and installing cocos2d
00:00Now let's take a look at downloading and installing the cocos2d template.
00:05You can find them at cocos2d-iphone.org.
00:09At that site, I've clicked the Download link and I've downloaded the
00:11latest stable version.
00:13So you can click to download it here.
00:14Once you download it, double-click the file to unzip it.
00:20So you'll see that I have the folder here in my Downloads folder.
00:24In Terminal, which you can find in the Utilities folder within your Applications
00:28folder, change the directory to that cocos2d directory by typing "cd" and a space.
00:34Then click and drag the cocos2d folder into Terminal.
00:39Once you do that, press Enter and the directory will be changed.
00:42Now we'll install the templates by typing "./install-templates.sh -u -f" and then press Return.
00:55You will be able to tell that Terminal is doing something like this.
01:01It will take a few seconds and then say Done at the bottom of the screen, and
01:05from there you can close Terminal, and the temples are installed successfully.
01:08You can confirm that everything is working by going to Xcode and then clicking
01:13File > New > New Project.
01:16In the New Project area, you should have a section under iOS called cocos2d, and
01:21in there you should have different options for different cocos2d projects.
01:25I'll choose cocos2d, click Next, create a project called Test, save it on the Desktop.
01:33Once it's created, I'll simply test it in the simulator to make sure it's working.
01:36If it's working properly, you should see the simple Hello World app on the screen.
01:47There it is!
01:49So I'll quit the simulator, and now we've successfully installed cocos2d.
Collapse this transcript
Understanding scenes, layers, and sprites
00:00The basic building blocks of cocos2d are scenes, layers, and sprites.
00:05Scenes are managed by the director, with a class name of CCDirector.
00:11Think of the director as controlling the main thing that you're seeing on
00:14the screen at one time.
00:15So for example, there may be one scene called the Main menu.
00:19The cocos2d class for that is called CCScene.
00:22Think of CC in cocos2d being short for coco.
00:26So you may have another scene called Game.
00:29So the director would control whether you're looking at the Main menu or the game.
00:34Scenes can contain layers and sprites.
00:38A sprite is a visual object, like the mole here on the screen.
00:42So a scene can contain sprites.
00:45It can also contain layers.
00:47Layers can contain their own sprite as well.
00:50So if you look here, the red bounding box shows the CCLayer (blueMoles), which has three moles.
00:57One of those is a sprite named blueMole, which you can see with the
01:02green bounding box.
01:04So let's take a look at what scenes, layers, and sprites would look like in code.
01:09Here I have a blank cocos2d template project called ScenesLayersSprites and an
01:15AppDelegate.m. I am going to scroll down to the bottom of applicationDidFinishLaunching.
01:20You'll notice as you scroll down that you will see the director is initialized.
01:24So we access that sharedDirector instance. It has a GL view.
01:31This is all stuff that's written for you and you'll probably never have to mess with.
01:35At the very bottom of that method you will see CCDirector sharedDirector
01:39runWithScene, and then HelloWorldLayer scene is passed in.
01:44So the runWithScene method enables you to switch between scenes.
01:48So let's go to the HelloWorldLayer scene, which we can find at HelloWorldLayer.m.
01:53Let's take a look at the Scene method first.
01:56Scene creates a blank CCScene, which is accessed by the node method.
02:04The node method turns an allocated, initialized, and auto-released object.
02:10This applies for layers, sprites, and scenes.
02:14So it's a quick way to create an auto-released object.
02:17So we create a scene, and we create an instance of HelloWorldLayer, add the
02:23HelloWorldLayer to the scene and return the scene.
02:29Note that you don't have to run it like this.
02:32The cocos2d template does because a CC layer already has touch functionality
02:37built-in, but usually when I create a project I just have it run the node of the
02:41main scene I want to run.
02:43So we will take a look at how that looks later on.
02:45So in the init method we can see sprites added to the screen.
02:48An example of a sprite is a CCLabelTTF.
02:53So that's a visual object that we place on the screen.
02:55We add it to the screen using the addChild method.
02:59If you've ever used Flash in ActionScript, you might be familiar with the
03:04addChild method already.
03:05It works in the exact same way with cocos2d.
03:08Each child you add is added in front of the previous child, unless you specify a
03:14Z position, so you can control layering between sprites.
03:18So to recap, cocos2d classes start with CC, the director manages scenes
03:23which are different organized parts of your game, and scenes can contain
03:27layers and sprites.
03:29Sprites are visual objects and layers are groups of sprites.
Collapse this transcript
Positioning sprites
00:00cocos2d uses a bottom-left X-Y origin.
00:04So the bottom-left position is at 0 X and 0 Y, since the point system on the
00:10iPhone goes from 0 to 480 horizontally and 0 to 320 vertically, and we have X at
00:200, Y at 320 at the top left, X at 480, Y at 320 at the top right and X at 480, Y
00:27at 0 at the bottom-right.
00:28Keep in mind too that when you're working with retina display, the coordinate
00:31system does not change.
00:32This is again because the coordinate system is based on points and not pixels.
00:37So let's take a look at positioning a sprite.
00:40So we have a sprite on the screen here and its X-Y origin is in the center.
00:45So if you don't mess with its position, its X position is 0 and its Y position
00:50is 0, which puts the sprite at the bottom left of the screen.
00:54So if you wanted to move it to the top, you would set its X to 0 and its Y
01:00to 320; to the top-right would be X 480, Y 320; and the bottom-right would be X 480, Y 0.
01:06So let's take a look at that in code.
01:09I'm going to go to HelloWorldLayer.m. Now this is just the default cocos2d template.
01:17So what I'm going to do is erase all the code inside of the if statement in the init method.
01:22Now the first thing that we need to do is to get a sprite on the screen.
01:26To do that, we will need a file to load in.
01:29Now I've already dragged in the assets folder here in the resources
01:32folder, you'll see.
01:33If you don't have access to this, then you can just import any PNG file into your app.
01:40So I am just going to open up mole.png, and that looks like exactly what I want.
01:45So back in my code, I am going to create a sprite by typing CCSprite.
01:51Remember, everything has that CC prefix. Asterisk.
01:56We'll call this mole.
01:57We will set it equal to, in brackets, CCSprite.
02:02Now to get auto-released objects in cocos2d, you can almost always use a class method,
02:07so that saves you a lot of time;
02:09you don't have to allocate most objects.
02:11So CCSprite, and then I'm going to call sprite with file and just pass in an
02:16NSString for mole.png.
02:19That's really all there is to it.
02:20So you create the mole in memory, and then you have to add it as a child so it
02:26appears on the screen.
02:27So in order to see anything visually, it needs to be the child of some other object.
02:33So on the next line, in brackets, self addChild:mole.
02:39Now before you test the app in the simulator, I want you to guess where it's going to appear.
02:47Keep in mind it has a default X and Y of (0,0).
02:52There it is, the bottom-left.
02:54Did you guess right?
02:57Let's look at changing the position.
02:59So let's say I want to make it 100 X and 100 Y. Simple, mole.position.
03:05You could do this before or after addChild; that's fine.
03:08Then in cocos2d we always set the X and Y position at the same time,
03:13so set it equal to CCP, which takes an X and Y coordinate.
03:18Now CCP is actually just a shortcut for CGPointMake, a little shorter than CGPointMake.
03:26So I prefer using ccp.
03:29So in parentheses, after ccp--keep in mind that's lowercase--type in (100, 100).
03:35So we put this in X and Y of 100, and that will align the middle of the mole
03:40with an X and Y of 100.
03:41So test it again and took a look at the simulator. There we go!
03:49So that's about it.
03:52If you look right here in the center of the mole, that's just about 100 pixels
03:58up and 100 pixels to the right.
04:00I am judging by it being about a fourth of the screen size.
04:07Also, keep in mind that the position of the mole is based on the size of the
04:11full PNG file and not the size of the artwork itself.
04:15So in this case the size of the file is a little bit bigger than the actual area of mole,
04:20so just keep that in mind.
04:22Now let's say we wanted to put the mole at the center of the screen.
04:25Now we could do 480x320 divided by 2, which would be 240,160.
04:30We can test, and there is the mole in the center. Nice!
04:43Close the simulator.
04:45But what if we design this for the iPad?
04:47Remember, the iPad has not just a different resolution, but a different aspect
04:51ratio from the iPhone,
04:53so this wouldn't work right.
04:55We would need some kind of variable that represents the whole width and whole
04:58height of the screen.
04:59So to get that, above the mole, create a CGSize object.
05:03We will just call it s, no asterisk, and we will set it equal to, in brackets,
05:11I am going to type an extras set of brackets and type "CCDirector sharedDirector"
05:18and then in the outer brackets, "winSize."
05:21So that gives me a width and a height of the screen.
05:25So I could change 240 to s.width, divided by 2 and change 160 to s.height
05:32divided by 2, and test the app again in the simulator.
05:36You will see that the mole is again in the center of the screen. There we go!
05:43So whatever size your display is, you can get its width and height through the
05:49director's winSize property.
05:51So to recap, cocos2d uses X-Y coordinates that start at the bottom-left, and
05:57objects, like sprites, have the registration point, or X-Y origin, in the center.
Collapse this transcript
Adjusting basic sprite properties
00:00Now we'll take a look at the most common sprite properties that you'll be
00:03adjusting. I'm in HelloWorldLayer.m, in the init method.
00:08So we have the mole on the screen at center.
00:10Now let's add a background.
00:12So I'm going to type CCSprite, and we'll call this bg, and we'll initialize it to
00:18CCSprite spriteWithFile. This is going to be called bg.png.
00:22Then I'll simply add it to the stage.
00:25So self addChild:bg.
00:29Let's see what we get in the simulator.
00:30Now keep in mind that the background file is the whole size of the screen,
00:37so where do you think it's going to show up on the screen when the application loads?
00:41The answer is that the center of the background will be aligned with the bottom
00:45left of the screen.
00:46You'll also notice that the background is covering up the mole.
00:50So we want it to do two things here.
00:52We want to put the background behind the mole, for one, and then have the
00:56background to be centered as a second thing.
00:59So we'll close the simulator and then in the addChild method that we called, type
01:04a space, and another method includes a Z position.
01:09This is an integer, so I can type in -1.
01:13So everything is at 0 by default, and as you add more children, they
01:17automatically get placed in front of other objects if you don't tell it
01:21specifically what z position to be at.
01:24So by passing in z at -1, then we put the background behind the mole.
01:29Now we want to position it in the center of the screen.
01:32I mentioned earlier that the background is the same size as the screen, so we
01:37could have it centered just like the mole and it would be in the center. Or we
01:41can look at another option, which is to change its anchor point.
01:45Remember, the default anchor points of objects are in the center.
01:50So we could shift that to be anywhere we want on the object.
01:54Let's take a look at how that works.
01:57Go right below the line where we create the background and then type
02:00bg.anchorPoint, and we set this using a coco point as well.
02:06So ccp. And here it's not coordinates, but it's a percentage. So it's from 0 to 1.
02:15So 0 would be, the anchor point would be set at the left of an object for the
02:19first value and 1 would be all the way at the right.
02:22So the default is .5 for X and .5 for Y. That's right in the center.
02:28So if we wanted to change the anchor point to say the bottom-left, it would be (0, 0).
02:34So when you do that the default position is going to be at 0, 0, which is going
02:39to align the bottom-left of the object at the bottom-left of the stage.
02:44And since the background is the same size as the screen, it's going to fill the whole screen.
02:49So let's test the app in simulator. There we go.
03:02Now let's take a look at some other properties that we can modify.
03:04So we've already looked at position and anchor point, so let's take a look at rotation.
03:08So right under where we set the mole position, type "mole.rotation" and here you
03:14can just set a value between 0 and 360.
03:18So let's say I set its rotation to 180.
03:21We'll test. See what we get.
03:23Now the mole is upside down.
03:28So you can mess with rotation if you ever want to adjust that on an object.
03:35There's also scale, a value between 0 and 1--0 being 0% scale and 1 being 100--
03:44or you can go past 1.
03:45So what I'm going to do is just type in .25 and then test the app.
03:51There we go. It's a tiny, little mole.
03:59Note that you can change scale X and scale Y independently.
04:02So if I change scale to scaleX and test the app again in the simulator, you'll
04:07see the mole only scales on the horizontal axis.
04:11Remember that scaling is based on the anchor point as well.
04:14So with anchor point in the center, the mole will scale to the center. The mole
04:18will rotate from the center.
04:19But if you alter the anchor point like we did for the background, it will rotate
04:24or scale around that anchor point.
04:25So keep that in mind.
04:29You can adjust the Opacity, so I'll change scale X to opacity. And this is
04:34between 0 and 255, so if I give it a value of 100, the mole should be about
04:41halfway transparent. There we go.
04:48And if you want to hide and show an object, you can change its visible property.
04:53So I'll change opacity to visible, and this is just YES or NO, so I'll change
04:57that to NO and you won't see the mole on the screen.
05:06The visible property works great for memory optimization. So if you just want to
05:10show and hide objects, always use visible over opacity. That's because even a 0%
05:17opaque object still has to be drawn, and the visible objects are not drawn and
05:23thus don't take up memory while your app is running.
05:26So just keep that in mind.
05:28Those are the basic properties that we'll be using throughout this course.
05:31So remember, you can set the position, and by default an object's anchor point is in the center.
05:38You can adjust the anchor point using percentages, from 0-1.
05:42You can also adjust rotation, scale--on the X and Y axis--opacity, and visibility,
05:49all using dot syntax.
Collapse this transcript
Handling touches
00:00Nearly every game needs some way to handle touches.
00:05For example, in the mole game that we're making, we'll need to detect if you
00:09tapped a mole when you touch the screen.
00:12Let's take a look at handling touches in cocos2d.
00:15Right inside the if statement of the init method in HelloWorldLayer.m, I'm going
00:20to type self.isTouchEnabled = YES.
00:25This one line of code sets this layer as a delegate of a touch.
00:30So once you do that, you can then respond to the touch events.
00:34So scroll down below the init method, and here we'll handle that touch event by
00:40typing -(void) ccTouchesBegan.
00:49So I want you to just complete that method, TouchesBegan, which is an NSSet of
00:54touches with the event. And here the first thing we're going to do is just log
01:00that a touch occurred. So type CCLOG.
01:01I like to use CCLOG to log things that happen into the Output window because
01:08this code doesn't do anything if you run in Release mode,
01:12so only in Debugging mode does this code run.
01:15So it's like an NS log but just more efficient.
01:18You don't have to worry that if you forget to comment any out that they are
01:23trying to run in the released version of your game.
01:26So in here what I'm going to do is log "touch happened!"
01:32So we'll test this out and take a look at what it looks like in the simulator.
01:40So I can click anywhere, and in the Output window you should see that message.
01:46So I'm going to scroll down to the bottom and you'll see that touch happened! occurs many times.
01:51Now what if we wanted more information about that touch, like where it was?
01:56So right above CCLOG we're going to create a new line of code.
02:00So what I'm going to do is type UITouch, and I'm going to just grab any touch.
02:04So we'll call this touch, and we're going to set it = touches anyObject.
02:11On the next line create a CGPoint, call it location, and I'll set it =
02:20touch locationInView--and this is in brackets--and then some more brackets
02:27after locationInView: touch view.
02:29So we're getting its location, and then we need to convert this point to a GL
02:35point so it will go with our cocos2d coordinates.
02:39So we'll do it on the next line. location =, double brackets CCDirector sharedDirector,
02:47and inner brackets, convertToGL, and pass in location.
02:52Now here we have an X-Y coordinate for the touch which we can access.
02:57So in the CCLOG, I'm going to change touch happened at x: %0.2f--
03:01that will give us a float--and then a comma y:
03:07%0.2f. And then after the closed quotes, I'm going to type location.x and then
03:17location.y. Save and test.
03:26So in the Output window, now I should get the location of the touches that happened.
03:31So touch a few times at the top-right, then at the bottom-left.
03:33We'll quit the simulator, and we'll see what we get in the Output window. There we go.
03:41So now we can access the X-Y coordinates of a touch location all over the screen.
03:46So remember, to implement touch functionality, you can call self.isTouchEnabled,
03:53set it to YES on a layer, and then you just need to implement the
03:58ccTouchesBegan event handler.
Collapse this transcript
Working with tags
00:00Along with handling touches in a game, it's necessary to know if a
00:04certain object was touched.
00:06Let's take a look at how we can detect if the mole was touched.
00:10So one way to do that would be to declare the mole in our header file and have
00:15it as a property used throughout our class. But the shortcut is to use tags.
00:21So when I call self.addChild:mole, I can add in the z position, and note that I
00:26can also add in z the position and a tag.
00:29You can also add a tag after the fact.
00:31So after self.addChild:mole, I could type mole.tag =, and I could set this to 1,
00:39for example--so just any integer will do here.
00:42Now I recommend using some kind of enumerated value if you're going to use this,
00:46so you don't have to remember the number every single time you recall it,
00:50so just keep that in mind. And scroll down to ccTouchesBegan. And right above the
00:56LOG statement, I'm going to create an if statement.
00:59I'm going to see if the mole was touched.
01:01So in if statement I'll type CGRectContainsPoint. And the first thing we need is a rect.
01:08That's a rectangle.
01:09Now the rectangle is going to be the bounding box of the mole. So in here I'll
01:16type some brackets, and I'll type some inner brackets, and in the inner brackets we'll
01:21type self getChildByTag, and the tag is going to be 1. And in the outer brackets
01:28I'm just going to type boundingBox.
01:29So let's get in that point, and then the point I want to check against is the
01:34location of the touch, which we already has saved in our location variable.
01:39So if the rectangle, which is the bounding box of the mole, contains the touch
01:45location, then the mole was touched.
01:48So I'm just going to cut and paste the CCLOG statement into that if statement.
01:55So the only time we should see it is if the mole was touched.
01:59So, let's test this in the simulator and see how it works.
02:07Again, keep in mind that the bounding box of the mole is a little bit bigger
02:10than the mole itself, just because of the way that I designed the file.
02:14So if you want to click away from the mole, just click all the way at the left or
02:18right edge of the stage.
02:19So I'll click a whole bunch of times on the right, a whole bunch of times on the
02:23left, and then I'm going to click twice right on the mole.
02:26I'll close the simulator and then look in the Output window.
02:32I should see that statement only occurring twice in the Output window, and there you have it.
02:38So we have successfully detected if an object was touched.
02:41So using tags, you can access sprites without having to save them as properties.
02:48So that's your call whether you do that or not, but tags are a quick and easy
02:52way to access the sprites.
02:54Then, in the TouchesBegan event, you can check to see if a touch is touching one
02:59of your objects by using the CGRectContainsPoint method.
03:03The bounding box of your sprite can be used for the rectangle, and the location
03:06of the touch can be used for the location.
Collapse this transcript
Accessing accelerometer data
00:00Some games use accelerometer data as a source of input.
00:03Let's look how to implement accelerometer data into your game.
00:07Keep in mind the simulator doesn't get accelerometer data,
00:10so this is just something where you could see and use by testing on your own device.
00:14So in the init method, I'm going to change self.isTouchEnabled to
00:18self.isAccelerometerEnabled, and I'll set it to YES.
00:23And then I'll handle the accelerometer event, which is void, and then it's
00:28accelerometer didAccelerate.
00:30So you should get that with code hinting;
00:33if not, you can copy it from my code on the screen.
00:35And here, all you have to do is set the X or Y position of the mole or any other
00:41object based on the acceleration of the accelerometer.
00:45You can access that through acceleration.x, .y, or .z. So those handle the
00:53acceleration on the different axes of the device.
00:57To make it work for your game, you'll just have to experiment a little bit.
01:00I recommend trying to move around the mole on your device with
01:04acceleration values.
01:05So again, to handle the accelerometer input, set isAccelerometerEnabled to YES
01:12on the layer you want to handle and then handle the accelerometer
01:17didAccelerate event.
01:18You can access all of the accelerometer data through the acceleration
01:22value passed in.
Collapse this transcript
Understanding cocos2d actions
00:00If you look at the top-selling iOS games, you'll see animations everywhere:
00:05character animations, even the menus animate all the time.
00:09Let's take a look at how to do some basic animations using cocos2d actions.
00:15Actions allow you to animate things scaling up, or scaling down, rotating,
00:21moving--basically any property that a sprite has can be animated.
00:26You can even have a delay and then run a function if you want.
00:30So let's take a look at how that works.
00:32I am going to go down into ccTouchesBegan, and I have here a CCSprite called
00:38mole that I used to hold the object with the tag of 1, which is the mole that we
00:44created in the init method.
00:45So let's say we wanted the mole to scale up a little bit every time we clicked it,
00:52but we wanted that to happen in an animation.
00:55So in brackets, in the if statement, type mole runAction, and then in
01:00brackets, type CCScaleBy, and then type a space and then type
01:07actionWithDuration and scale.
01:10Make sure to pick that one.
01:11Now I'll go for the code hinting.
01:13I'll have the time be 0.25, which is a quarter of a second, and I'll have
01:19the scale be 1.1 and then test it out in simulator. And each time you click on the mole,
01:25he should animate bigger and bigger and bigger.
01:29So click on the mole, it scales up a little bit. And notice he is not
01:35just appearing bigger; it's animating.
01:42The mole is pretty huge right there.
01:43So using runAction, you can virtually animate any editable property.
01:49Let's just change the CCScaleBy to a CCMoveBy.
01:55Notice that there's also MoveTo.
01:57So the difference between By and To is that By doesn't care about a starter end location;
02:03it just says, "move an object in this amount" and To says, "move an object to
02:09this specific amount."
02:10So if an object is at position 0, 0 and use MoveBy, you pass in 0 for the X, 100
02:18for the Y, it'll shift up and just set the amount of 100 points.
02:22So let's use CCMoveBy, and we'll call actionWithDuration.
02:25Let's have 1, so it will be 1 second, and then ccp.
02:32So if you wanted to move left or right or up or down, you'd pass that in here.
02:36So it will move in just the amounts that you pass into ccp call.
02:40So if I type in -10, 0, he will only move to the left when I click it.
02:46So let's test that out.
02:55So we'll see him sliding to the left a little bit each time I click.
03:06So you'll also find in there CCFadeTo, CCFadeBy, CCRotateTo, CCRotateBy, and
03:14use them all in the same way:
03:16you run the class method, actionWithDuration, and then you modify another property.
03:21So there is some extra parameter that you pass into modify the rotation or the
03:27scale, what have you.
03:29Let's take a look at running a sequence of actions.
03:32Let's say when you click on the mole you want him to scale up and then scale back down.
03:35So I am going to delete the CCMoveBy, type some brackets, and then type
03:43CCSequence, and type actions.
03:48This is going to be actions separated by commas.
03:52So let me type some brackets.
03:54I am going to push those brackets on the next line and then push nil on the
03:58next line so I can easily run the sequence of actions.
04:01So CCScaleTo actionWithDuration, have this last a quarter of a second. And the
04:11scale will be 1.1, and we'll just copy and paste that line of code onto the next
04:16line and then change 1.1 to 1.0, and that's it.
04:24So we'll test the app, and in the simulator, when we click on the mole, we should
04:28scale up and then back down pretty quick.
04:30So each time you click on him, he scales up. And of course, you can list as
04:43many actions as you want, so if you want the mole to scale up and then scale down
04:48and then call a function or to wait a certain amount of time, it's easy to do.
04:53To wait time, you use CCDelayTime actionWithDuration.
04:59You just pass in how long you want it to wait before the next action. And then
05:03you could also do calling a function by CCCallFunc, and then you just pass in
05:10actionWithTarget and selector.
05:12So that way you can make something happen and then call a function when you are done.
05:17So cocos2d makes it really easy to do these things.
05:20There are definitely more actions than I could show in one movie, and I
05:24intentionally left many of them out so you can experiment what cocos2d
05:28has available to you.
05:29So we are just taking a look at a few of the actions available in cocos2d.
05:33So I encourage you to experiment with the different actions and see what cocos2d
05:38has available to you right out of the box.
Collapse this transcript
Working with sprite sheets
00:00Designing a game for a mobile device could take up a lot of memory really fast,
00:05so as a game developer, you are always concerned with memory optimization.
00:10SpriteSheets help with memory optimization, in that they take a bunch of
00:14different sprite files and condense them down into one file.
00:17And this almost always saves big on memory.
00:22That's because any size that an image is automatically gets scaled up to
00:26the nearest power of 2.
00:28For example, 128 is a power of 2.
00:33If you have an image that's 100 pixels by 100 pixels, then regardless of the
00:38size of the image, they get scale up to the nearest power of 2 in memory.
00:43So it's treated as if it were 128 by 128 pixels, and that takes up more memory.
00:51You can imagine this being a problem if you have a lot of images that you are loading in.
00:56So each time you load an image, you are wasting 28 pixels of space in both the
01:00horizontal and vertical dimensions.
01:02So with the SpriteSheet, the idea is that you don't waste any space because
01:06they are all packed into one power-of-2-safe image.
01:09There are two really big options for creating SpriteSheets.
01:12Of course, there are more out there, so you can research it if you want and pick
01:17anyone that you would like.
01:18But the two that I have personally used are Zwoptex and TexturePacker.
01:24Let's go to TexturePacker first.
01:27TexturePacker is the one that I use for my current commercial games.
01:31The reason is it has a lot of quality integration with cocos2D that compresses
01:35your images down in a format that makes them take up less space on the device.
01:40It also has a few other features that I feel really give it an edge over the competition.
01:45The Zwoptex app is also great because it has an online Flash version that you
01:50can try out for free.
01:52Both apps are relatively inexpensive and will save you a lot of memory and a
01:58lot of time when developing your games.
02:01So while you don't have to buy one for this course, I do recommend it.
02:05Again, I am not advertising for any one over the other, and I don't get paid by
02:10Zwoptex or TexturePacker to say anything about them.
02:12I have used these products in my own commercial games.
02:16So let's click on the Flash version at the Zwoptex site.
02:26So again, this is a free online tool, so if you don't feel like buying one of
02:30these products right now, then just use the Flash version.
02:32You can go to File > Import Images, and then I am going to go to my Desktop, in
02:39exercise files folder,
02:42in Chapter 1. I am going to import a0001 through a0031, and I'll click Open.
02:52These all get opened in this web app here, and I can choose a range.
02:56I can choose any way I want it to arrange.
03:00I'll just choose by name and width. It doesn't matter.
03:03So here I have all my sprites organized.
03:06Now I can mess with the size of the canvas if I wanted to, to optimize this, but
03:10I am not going to do that right now.
03:12And from here, I could save the file by going to File > Export Texture and
03:18File > Export Coordinates.
03:19So what you are going to get from the texture is a PNG file with all of these
03:23images in it, and what you get when you export coordinates is a PLIST file that
03:28contains references to all of the images.
03:29So you are going to need both to do what we are going to do next.
03:33So just have that ready and meet me over in Xcode.
03:37So here I already have my PLIST and my PNG file in my project.
03:41So let's take a look at how to use it in cocos2d.
03:45Right above where I create the mole in my init method, we are going to type
03:49double brackets and then the inner brackets, CCSpriteFrameCache,
03:56sharedSpriteFrameCache, and then the outer brackets, addSpriteFramesWithFile.
04:05And in the file I am going to pass in a string for my PLIST file, which is
04:09called sprites.plist.
04:13You can see that, and I'll pass in the name to my PLIST file, which is moles.plist.
04:17So there you have it.
04:23Go back to HelloWorldLayer.m, type in moles.plist, and now I can reference the
04:32sprites by their frame names, which correspond by default to their file names.
04:38So let's say I want to load mole a0011 and I reference that frame when I load it.
04:46So go back to HelloWorldLayer.m, and then I am going to change CCSprite
04:51spriteWithFile to CCSprite spriteWithSpriteFrameName. And I pass in an NS
04:59string for the name of the sprite, which is a0010.png.
05:05Now, if you want to make sure that this is working, you can use any number, 1 through 31 here.
05:10So I'll just test the app in the simulator, and you should see the mole is on
05:15the screen as he was before.
05:17Now the difference is that this mole is loaded from a SpriteSheet and not a single file.
05:23So to recap, you create your SpriteSheet with a SpriteSheet creator.
05:28Personally, I've used Zwoptex and TexturePacker.
05:32You can load the sprite frames in using a call to the SpriteFrameCache and
05:37using its method, add SpriteFramesWithFile, and there you are going to add the
05:42PLIST file. And then you can create a sprite using your SpriteSheet by the class
05:46method spriteWithSpriteFrameName, and simply pass in the string which will
05:52correspond to the file name of your sprite.
Collapse this transcript
Creating simple frame animations
00:00While properties of a sprite can be animated using actions,
00:04typically character animations are done using a series of still frames.
00:09Let's take a look at how to apply a frame animation in cocos2d.
00:13Right below where we create the mole, I'm going to create an NSMutableArray.
00:19This is going to be called frames, and I'll allocate an init NSMutableArray here.
00:26So the first thing that you are going to need is an array of frames.
00:32Then we will create a for loop.
00:34We will start with an integer called i, set it equal to one, as long as i < 10,
00:40and i++. And here the first thing I am going to do is create an NSString, and I'm
00:47going to get the frame name. So we will call this frameName.
00:51So here I will create an NSString called frameName and set it equal to, in
00:56brackets, NSString stringWithFormat, and I will create an NSString.
01:06I will type "a%04i.png" and after the close quote, a comma and then an i. So as
01:12the loop goes on, it will add frame a0001.png and so forth, up to frame 10.
01:21I want to make sure that i is not just less than 10, but i is less than or equal
01:26to 10. So we want to include that tenth frame.
01:29So on the next line, I am going to type some brackets and then frames, addobject,
01:35and the object is going to be, double brackets, CCSpriteFrameCache sharedSpriteFrameCache
01:43SpriteFrameByName, and the name is going to be FrameName.
01:49And then below the loop, we will create a CCAnimation object.
01:57A CCAnimation is a set of frames.
01:59So we will call this a. I'll set it equal to, in brackets, CCAnimation animationWithFrames and delay.
02:08The frames are going to be frames.
02:10We already created in that NSArray, and the delay is going to be 1.0f/24.0f.
02:16When I created this animation in Flash, I set 24 frames per second as the frame rate.
02:22So just remember the frame rate that you used before, and you can pass it in here.
02:26On the next line, type some brackets and then type mole runAction, and the
02:32action is going to be CCAnimate-- different from a CCAnimation.
02:37Remember, animation is a set of frames, and CCAnimate is an action that runs CCAnimation.
02:43So actionWithAnimation and pick the one that says restoreOriginalFrame.
02:49So the animation's going to be a, and restoreOriginalFrame is going to be NO.
02:54So after the animation plays, it will stay at that last frame.
02:58So let's test this out in the simulator.
03:07So you notice the mole starts out up and then it goes down and the animation
03:11plays, so if you wanted him to start out down, you can change that first frame,
03:16which displays when we create the mole, as a0001.
03:18So let's test that again.
03:22So there's the mole popping up.
03:30Now, let's say you wanted the mole to go down when you hit him.
03:34Just copy all the code that handles the animation,
03:37so from mole runAction all the way up to NSMutableArray frames. Copy that and
03:43then paste it in ccTouchesBegan in the if statement, where you check to see if
03:47the touch collided with the mole.
03:49So paste that in. And then the loop is going to be a little bit different this time;
03:54i is going to run from 11 through 20.
03:58So just change that, i =11 as long as i<= 20, and that's it.
04:05So when you hit the mole, it should go down.
04:12So on the simulator, you'll see the mole animate up, and then you tap the mole and
04:16it will animate down.
04:24So to create a frame animation, create an NSArray of frames and add to it by
04:30iterating through a loop, create a CCAnimation to hold the frames, and then use
04:37the CCAnimate action to run the animation.
Collapse this transcript
Setting a game to display in Portrait mode
00:00Not all iOS games are going to be in landscape mode.
00:04If you come up with a great idea that better suits portrait mode, it's good to
00:08know how to do that with cocos2d.
00:10The first place to go is in GameConfig.h. In here when you see
00:16GAME_AUTOROTATION defined, change kGameAutorotationUIViewController to
00:24kGameAutorotationNone and save the file.
00:30Now I'll go over to AppDelegate.m. Scroll down, toward the middle of the
00:38applicationDidFinishLaunching method,
00:41and in here you can just copy and paste that line of code that sets the
00:44director's device orientation.
00:46So copy that, paste it after that endif line of code, and then test in the
00:53simulator, and you should see now that the game launches in portrait mode.
00:58And there is the Hello World text in portrait mode.
01:01So remember, to adjust auto-rotation, change your settings in GameConfig.h and
01:09then update AppDelegate so that the director's device orientation is portrait.
Collapse this transcript
2. Viewing the Core Classes
Viewing constants and the AppDelegate class
00:00For this game I already have a lot of prewritten code.
00:04Everything is already done, except for the gameplay itself.
00:08That way you can specifically focus on learning cocos2D to make games.
00:14Now both for the sake of those of you who don't have the exercise files and for
00:18the sake of those of you who do, I am going to walk you through all the code
00:23that's already been written.
00:24So first I'm going to go to Constants.h. In Constants.h I have several different
00:30values defined, so you'll see MOLE TYPE C, B, and A. Those are just simple
00:35strings, and they correspond to the different MOLE frame types.
00:39So the green moles are MOLE_TYPE_A. The frames are named A 0001 through A 0030.
00:50MOLE_TYPE_A, for example, refers to the green MOLE.
00:53I'm going to use these later in the code so I can easily refer to the
00:58different types of MOLES.
00:59So the frame for MOLE A would be A 0001.png, for example, and the frame for a
01:07blue MOLE, which is MOLE_TYPE_B, would be B 0001.png, for example.
01:14Then we have a value to store a user default, which is the amount of times the
01:19person has played the game, have a key to access the high score, and the key
01:27that tell us whether the user rated the game.
01:29And we have different values for the skins--
01:33there's moles, and there's jetpack--and these are named like this intentionally.
01:37These are what I named the s SpriteSheet, so there's moles.plist and then
01:42jetpack.plist. And then I have some enumerated values so I can access the
01:47moles using numbers.
01:49That makes it easier to go through a switch case statement and see what type of
01:52mole I am working with.
01:53Let's go over to AppDelegate.h. In this header file, you'll see it's
01:59pretty straightforward.
02:00I only added a few different values here. We have Boolean, hasPlayedbefore,
02:06Whacked3 and Whacked4, a string for the current skin and a whole bunch of
02:11integers for timesPlayed, currentAction, greenMolesWhacked, blueMolesWhacked,
02:20yellowMolesWhacked. And some methods defined.
02:25FinishedWithScore, which is going to run when we finish playing the game,
02:31getHighScore, pause, resume, isGameScene, getCurrentSkin, setCurrentSkin, and
02:38getViewController. So pretty straightforward.
02:41Let's go to AppDelegate.m and see anything that's different here.
02:46I've imported Constants, SimpleAudioEngine, Mainmenu, Main Game class.
02:56Initialize timesPlayed using the UserDefaults key.
03:00Set the current skin to be the MOLE skin. All this is set up in the cocos2D template.
03:08I commented out the line of code that shows DisplayFPS. That shows the frames per
03:13second on the screen. And in the runWithScene call, I'm calling Mainmenu node.
03:22So main menu is not a CCLayer subclass;
03:25it's a CCScene subclass. I'm grabbing an auto release instance with the node class method.
03:33Here in application we'll resign active.
03:36I'll check to see if it's the GameScene, and if so, send a message to the
03:41GameScene to pause the game.
03:44If not, I simply pause the director. And in applicationDidBecomeActive,
03:50if it's not the GameScene, I resume the director. This is because the GameScene
03:55handles its own pausing and resuming.
04:01Scroll down. finishWithScore is empty, getHighScore returns the UserDefault's
04:06value for the high score key. Pause and resume check to see if it's not the
04:13GameScene and if not, then pause and resume the director respectively. The
04:18isGameScene method checks to see if the class of the running scene is the
04:24GameClass and returns yes or no. Then we have simple getters and setters for get-
04:29and setCurrentSkin, simple getter for getViewController, and AlertView delegate
04:35handler, and that's it.
04:37So again, if you don't have access to the exercise files, you can just copy down
04:40my code here and follow along.
Collapse this transcript
Exploring the Game and Mole classes
00:00The main class we're going to be working in to develop this game is the
00:04GameClass; that class controls all of the gameplay.
00:08In Game.h, you'll see that I have game as a subclass of CCScene, and I've adopted
00:14the CCStandardTouchDelegate protocol.
00:17If you don't have CCLayer as your main class then you don't have that easy to
00:21add touch functionality, where you just have the one line of code, and type self
00:25dot is touch enabled to handle touches.
00:28So if you are subclassing the scene, you have to manually set up your scene as a
00:32delegate to handle touches. So then I have two CCArrays. I have some float
00:38values. I have a CCLabelBMFont.
00:41We'll talk about that class in detail later on. Some integers, CGSize s to
00:47handle the size of the screen, a reference to the AppDelegate object,
00:51CCmenuItemSprite, a few strings, a few Boolean values, and some methods here.
01:00Now I'll move to Game.m. So here I'm importing classes that you'll see over and
01:05over again, like Constants.h, Mainmenu.h, SimpleAudioEngine.h. Here I'm
01:11importing the main classes we will be working with in the GameClass.
01:16The init method doesn't create any objects;
01:18it just initializes primitives.
01:22InitializeGame runs a method called startGame, and startGame starts a
01:28selector called tick.
01:30What the schedule method does is it runs a selector at a certain time interval,
01:35and by default that's along with the frame rate of your app. So there is a
01:39method called chooseWhichMoleToMake, which is empty.
01:41The tick method adds on to timeElapsed in the amount of DT, which is the time
01:48between iterations of the selector running. So it's going to be 160th of a
01:53second each time. And if the timeElapsed is greater than the time allowed between
01:57moles, then we run chooseWhichMoleToMake and set timeElapsed to 0.
02:04showMole is empty. getDownMoles returns an array of all the moles that are down.
02:11We'll look at the more class in detail in just a minute in this movie.
02:14getUpMoles returns an array of moles that are up.
02:17CCTouchesBegan is empty, as is didScore, missedMole, gameOver, pauseGame, and
02:26resumeGame. We have getMoles up, which returns the number of upMoles; and
02:33mainmenu, which returns us to the Mainmenu;
02:36playAgain, which replaces the current running instance of games scene with a new
02:42instance of the game scene;
02:44onEnterTransitionDidFinish, which is an event handler that runs once everything
02:49is loaded for the scene to start, and that when we run an initializeGame, which
02:53starts all of the magic.
02:55onExit runs when scene is exiting, the last thing before its de-allocated, and in
03:02dealloc I just have a call to dealloc and showing self just to make sure that I
03:07can see in the output window when scenes are getting released.
03:10I highly recommend this when you're starting out with cocos2D because a lot of
03:14times you'll find that you'll forget to release an object and your scenes won't
03:18be getting released. So each time you change to a new scene, you're adding to
03:22the memory that your application is consuming.
03:24So just keep that in mind. This is a really good way to keep track of
03:28your memory management.
03:29Let's go to Mole.h. So we have some Booleans, some floats, an NSString,
03:36a reference to AppDelegate, and some methods here. And let's go over to Mole.m and
03:43look at them in detail.
03:44Again, note which classes are imported, and in the init method set some basic values.
03:50I'm not creating sprites here. And the reason why I do that is because sometimes
03:56the init method tries to create objects when they're not accessible, and so I
04:01always create objects after onEnterTransitionDidFinish.
04:07So startWithType actually creates a mole. So I'll run stopAllActions, which is
04:14a built-in cocos2D method that stops all actions that are currently running,
04:18sets isUp to YES, sets the amount of time the instance is going to be up based
04:24on the type of mole.
04:26Then it sets didMiss to YES, sets the type property to the type passed in, and
04:32then the scaleX is randomized.
04:34Of course that's just an optional feature, but I feel like it makes the game
04:38look a little bit different while you playing it.
04:39It kind of mixes things up.
04:42So reset sets isUp to NO, and if the person missed the mole then we run the
04:51missedMole method on the parent. And in stopEarly we make the mole go down
04:58without making the parent miss.
05:01So we set didMiss to NO, stopAllActions, and we run self stop, which will make
05:06the mole go down, and we'll do that later on.
05:08getIsUp returns if the mole is up. wasTapped is empty now. and
05:14getAnimationWithFrames and reverseAnimationWithFrames return CCAnimations of sets of frames.
05:20These are basically helper methods that I created so I can quickly create
05:24animation frames without having to write a for loop every single time.
05:29getType returns the type, and that's it.
05:31So as we go throughout the rest of this course, we're going to be adding a lot
05:35to the mole and game classes because these classes control all of the gameplay
05:40and logic for the game we're creating.
Collapse this transcript
Understanding the custom pop-up menu utility
00:00All of the pop-up menus in the game used the PopUp class;
00:04let's take a look at the PopUp class and PopUp.h. It's a subclass of
00:09CCSprite. It has two CCSprites and a CCNode called Container.
00:14A CCNode can be a CCScene, Layer, or Sprite.
00:20So I chose CCNode here because I don't want to have to worry about what data
00:25type is used for the container. And I have a class method called popUpWithTitle,
00:30and then I have some instance methods.
00:33So let's go to our PopUp.m.
00:37Here I'm importing CCSprite+ DisableTouch, which is an extension that I
00:42wrote, which we'll look at in just a minute, and then CCmenuPopup.h.
00:48ANIM_SPEED is defined as .2f.
00:50I have a tag for the background called tBG, set to equal to 1, and when that
00:58class method popUpWithTitle runs, it returns an autoreleased instance using the
01:03initWithTitle method.
01:05initWithTitle is pretty straightforward for the most part.
01:08It creates a window and then a background, and the background is just an empty
01:14sprite that I created as a rectangle that covers the whole screen, using the
01:19setTextureRect method. And since I'm using the CCSprite extension I created, I
01:25run a method called disableTouch. And as we'll look at in just in a minute, that
01:29disables all touches for anything underneath it.
01:33Set the position of the window and the scale, create a text label, set its
01:40opacity and position, create a description label, set its opacity and position.
01:46And I add them as children of the window, add the background as a child of self,
01:54and the window is a child of self.
01:56Then I use an action to fade the background and to animate the pop-up menu to
02:03scale up and scale back to normal size.
02:05The closePopUp menu displays a really quick animation that re-enables touch on
02:12the background and all other elements behind it.
02:15Then the window animates out and runs allDone, which runs the built-in method
02:20remove FromParentAndCleanup, which removes a child from its parent, taking it
02:25out of the display list of objects so it can be released from memory, and
02:30cleanup, which specifies whether you want it to get rid of all of its children.
02:37So let's go over to CCSprite+ DisableTouch.h. It's using the DisableTouch
02:44extension, implements a CCTargetedTouchDelegate protocol, and has
02:50two instance methods.
02:51Let's go to the .m file. And ccTouchBegan returns Yes.
02:57What that does is it captures all of the touches and doesn't let anything
03:03behind it receive touches.
03:06So I do that in the disable- and enableTouch methods.
03:09So you see disableTouch adds this object as a delegate of the touch dispatcher,
03:16with the priority of -1000.
03:19Now negative priority actually gets a higher priority. So all those Touches
03:24refers to whether or not objects below it can be touched.
03:27So I put YES there, and then enableTouch removes it as a delegate, so touches
03:33get enabled below this object.
03:35Remember, this is for the background when the pop-up menu shows up, which is a
03:39semi-transparent black area that covers the whole screen.
03:42Another class used along with the pop-up is the CCmenuPopUp.
03:46Let's go to CCmenu.h. CCmenuPopUp is an extension of CCmenu.
03:52A CCmenu is a collection of menu buttons. So you can use them for a pause
03:57button, for example, in your game.
03:59Something that's just going to capture user interactivity. Not so much like an
04:03animated object like a sprite, but more for interface elements.
04:08And so what you would do is create an array of CCmenu items and then you pass
04:13them into the CCmenu constructor and you create a list of buttons.
04:17We'll look at that in more detail later on.
04:20Let's go to CCmenuPopup.m, and then I have registerWithTouchDispatcher.
04:26I am overriding this method.
04:28I'm setting the priority to -1001. So any buttons placed in the pop-up menu will
04:35still work, and they won't be disabled, because of the priority of the background,
04:39which disables everything behind it.
04:41So in order for them to be registered, they need to have a lower priority.
04:46So in ccTouchBegan, the first thing that I do is check to see if there is an
04:50item that was touched. So if some button was touched then we're going to go on
04:55with a method, and if not, then we're going to return NO.
04:58That's going to stop handling the touch.
05:00So I then have an array of the ancestors, so there's the object's parent and then
05:06the parent's parent, and then the great grandparent.
05:08So then I'll loop through all the objects and ancestors.
05:12I check to see if it's a pop-up, and if so, close the pop-up.
05:17So whenever a button was touched that's in the pop-up menu, the pop-up will
05:21automatically close. And then finally, I'm returning whatever is returned in
05:25supers version of this method.
05:26So using the pop-up menu, you can easily add interactivity in a pop-up
05:32window without having to worry that buttons behind the pop-up window are
05:36going to be touched.
Collapse this transcript
Examining the code in the MainMenu class
00:00Finally, we'll examine the MainMenu class;
00:03in MainMenu.h you'll see that everything is pretty straightforward.
00:06I just have a reference of the delicate and then a playGame method.
00:09In MainMenu.m, I'm importing some of the classes that you've already seen. And
00:14everything here is in the init method.
00:16So I create a size object to hold the size of the screen, tell the audio engine
00:22to stop playing background music, set the delegate, have a string for fileName
00:27based on the CurrentSkin.
00:30Add the SpriteFrames to the cache using that file name. I have a font size, set
00:36the High Score on the screen based on the font size. Put the high score at the top-right.
00:43Add it as a child of the MainMenu, set FontName for CCmenuItemFont to the font
00:48that I had in my project, which is called TOONISH.
00:50Set the font size of CCmenuItemFont. And then here we have a CCmenuItemSprite, so
00:58this is going to be a button. And it's called playbutton. And I'm using the class
01:04method itemFromNormalSprite, selectedSprite target and selector.
01:08So remember, a CCmenu item is something that you put into a CCmenu that runs a
01:14selector when you click it.
01:15So the Sprite returned comes from the Gamebutton class, which is a custom class
01:21which we'll look at in just a minute.
01:23Basically the class creates a button with text, and you could specify whether
01:28it's a big button or a small button using the isBig parameter.
01:32I set selectedSprite to Null, since I don't want the sprite to change when I tap it.
01:37The target is self and the selector is playGame, which just starts the basic game-
01:42play. So then you'll see the leaderboard's button that has the Text Game Center.
01:47It runs a method called showLeaderboard. selectSkinbutton runs selectSkin, the
01:53otherGames button runs otherGames, and the CCmenu is created using those items.
01:58And I tell the menu to alignItems HorizontallyWithPadding.
02:03Position the menu, add the menu as a child of the MainMenu.
02:08That's this class. And then I created another menu just for the play button.
02:12So you see that there. And then for the background, I changed fileName to
02:19title.png, and then we'll have it display as the background.
02:23You'll also notice CCTexture2D setDefaultAlphaPixelFormat.
02:29This enables you to change the quality of your images to improve memory.
02:33So RGB565 has no alpha channel and gives you an optimized quality for the memory used.
02:41So this is really good for backgrounds, but since it doesn't have an alpha
02:45channel, it's not too great for sprites.
02:48So after I create the background, then I set the CCTexture2D back to RGBA4444.
02:55This is 16-bit color with an alpha channel.
02:58Let's go over to Gamebutton.h. So there are two methods: buttonWithText and
03:03buttonText isBig. There are two class methods here and one instance method. If
03:08you go over to Gamebutton.m, you'll see how it all works.
03:12Most of the class methods return auto-released objects.
03:16I just did this to follow the standards of cocos2d. And then the init with text
03:20method is where the label is created, the buttons DisplayFrame is set, based on
03:27whether or not the button isBig. Keep in mind that you can change a sprite's display
03:31frame at any time using the setDisplayFrame method. Then a label is
03:35created with the appropriate text.
03:37I created an extra label that's a shadow, so it's just black--
03:41it's the same text--and I offset it a little bit, and I added it as a child
03:46below the main label.
03:47So that's all of the code, and it has been custom written for this game.
03:50Once you have everything set up and you have an understanding of the basic
03:55foundation of the game, you're ready to start writing the actual gameplay.
Collapse this transcript
3. Building a Basic Mole-Whacking Game
Adding the background and HUD elements
00:01Before we start writing the code for the game, let's take a look at what we
00:03have in the simulator.
00:05So I'm going to test the app, and right now we basically have the main menu.
00:14We see the main menu here. It says High Score:
00:160, and if you click SKINS, you'll see the skins, but they won't do anything if you click them.
00:25GAME CENTER doesn't do anything.
00:27MORE GAMES will try to launch the App Store which isn't installed in the
00:30simulator, so you'll have to test it on a device to see that working. And if you
00:34click the Play button, you simply get a blank screen.
00:37So let's close the simulator and go over to Game.m, and we'll start writing
00:43the code to add the background, the carrots out at the top-right of the
00:47screen, and the Pause button.
00:50So in the initializeGame method, this is where we're going to create all of our art elements.
00:56First, I'll set the delegate.
00:59Set it equal to AppDelegate in parentheses and an asterisk, a set of double brackets,
01:09UIApplication sharedApplication and in the outer brackets, delegate.
01:16Go to the next line, and make sure the director is playing, so we'll call
01:22CCDirector in double brackets, sharedDirector, and in the outer brackets resume.
01:31And on the next line we'll set s equal to, two sets of brackets, inner brackets CCDirector
01:40sharedDirector, outer brackets, winSize.
01:44Create an NSString called fileName.
01:49This is going to represent the sprite sheet PLIST file name, and we're going to
01:52grab this based on the name of the current skin.
01:56So in brackets, NSString stringWithFormat is going to be %@ symbol.plist,
02:06after the quotes a comma, and then brackets, and in the brackets, delegate getCurrentSkin.
02:15So this will be moles.plist or jetpack.plist, for example.
02:18Go down a few lines, and then we'll add this sprite frames using that PLIST file.
02:24So double brackets CCSpriteFrameCache sharedSpriteFrameCache
02:31addSpriteFramesWithFile, and the file is going to be fileName.
02:37Now we'll initialize the carrots array.
02:40So carrots = and double brackets, and we'll just have CCArray alloc and then init
02:55in the outer brackets.
02:56Now just think of a CCArray just like an NSMutableArray; the main difference is
03:01that you can easily grab a random object out of a CCArray, which is going to be
03:05useful for us later on.
03:06Now since we init an object there, we're going to have to release it,
03:09so I want you to scroll down in your code and then find the onExit method. In
03:15there we'll release the carrots.
03:16So carrots release.
03:20Scroll back up to initializeGame, and the next step is to load in the background.
03:26So remember, for optimization, we want to change the default alpha pixel format to
03:32not support alpha, so we don't waste any memory.
03:35So in brackets, CCTexture2D, setDefaultAlphaPixelFormat, and that's going to be
03:41kCCTexture2DPixelFormat_RGB565.
03:42So now we'll create and load in the background and then change the pixel format back.
03:53So CCSprite, we'll call this *bg, and we'll set it equal to, in brackets, CCSprite spriteWithFile
04:09and we're going to get the file from the delegate's current skin again.
04:14So brackets, NSString. We'll type stringWithFormat, and in there it's going to be
04:23%@ symbol _bg.png. After the close quote, a comma, and a space, some more brackets.
04:31In the brackets, delegate getCurrentSkin.
04:36So this will be moles_bg.png or jetpack_bg.png based on the current skin of the game.
04:44So let's set the background's anchorPoint to 0, 0,
04:47so that's ccp. Remember, this is a percentage so that's bottom-left anchor point.
04:55So we don't have to set it's position, because it's going to be a aligned with
04:58the bottom-left of the screen, and it takes up the whole screen.
05:01And then in brackets we'll call self addChild. We'll add bg, and it's z will be -1.
05:07Next I'll copy and paste that line of code where we change the
05:13DefaultAlphaPixelFormat and paste that right underneath self addChild bg, and
05:20change the AlphaPixelFormat to RGBA4444.
05:25Again, this is for memory optimization, and it will give better performance in our game.
05:30Now we'll create a loop to display the carrots on the screen.
05:34So type for. This will be int, i, we'll set it = 0 and as long as i < carrotsLeft,
05:44i++, and we'll create the carrots from the top-right corner of the screen.
05:52So in here CCSprite. We'll call this c, and we'll set it equal to, in brackets,
06:02CCSprite spriteWithSpriteFrameName. That's going to be life.png as an NSString.
06:19We'll set it's anchorPoint to be the top-right, so c.anchorPoint = ccp(1, 1).
06:29I like to set anchor point so that I don't have to do as much calculation
06:32when I'm setting the position of objects, so if that's why you're wondering why I
06:36keep modifying the anchor points,
06:37I like to put something that's at the bottom-left at 0, 0;
06:40if it's at the top-right, I put it at 1, 1;
06:42if it's at the top-left I put it at 0, 1.
06:46So next, we'll set the position so c.position, and we'll set it equal to ccp. And
06:52in parentheses the X value is going to be s.width - i *, so an asterisk, and we
07:04want to do the width of the carrot.
07:07We can get that through its contentSize property.
07:11So c.contentSize--make sure you don't have the underscore--.width--that will give us
07:18the width of the carrot. And then we'll set the Y position of the carrot at s.height.
07:26So that will align the carrots with the right edge of the stage, and each one will
07:31shift in the amount of the carrots' width to the left.
07:35So we'll draw three carrots, starting at the top right corner.
07:37So now we'll add this to the carrots array.
07:40So carrots addObject c. And then on the next line, self addChild:
07:54c, so we'll add that carrot, and the z will be 10.
07:59Finally, we'll add the Pause button to the screen.
08:04So a few lines below the for loop, set pausebutton equal to, and in brackets, type
08:12CCmenuItemSprite and then start to type item. And then what I want you to pick is
08:20itemFromNormalSprite, selectedSprite, target selector.
08:24So the NormalSprite is going to be in brackets, CCSprite
08:29spriteWithSpriteFrameName, and the frame name is going to be pause_button.png.
08:38selectedSprite is going to be NULL, target is going to be self, and for selector,
08:44I'll type at symbol selector, and in the parentheses I'm going to type pauseGame.
08:52On the next line, I'm going to create a CCmenu and put a pausebutton in the menu.
08:56So CCmenu, we'll just call this menu, and we'll set it equal to CCmenu
09:05menuWithItems. We'll pass in the pausebutton and then nil after the comma.
09:12We'll set the position of the Pause button.
09:13So pausebutton.position = ccp and in the parentheses type s.width/2 -
09:27pausebutton.contentSize.width/2.
09:32This will put it at the bottom-right, because a menu by default is at the center of the screen,
09:38so we're basing it off those coordinates.
09:41So then a comma and then in parentheses -s.height/2, after the parentheses +
09:53pausebutton.contentSize.height/2.
09:59Finally, we'll add the Pause menu to the screen by typing "self addChild:menu," and
10:07we'll give it a z position of 100.
10:12Now that we have created the background and the carrots and the Pause button,
10:16let's test the app in simulator.
10:17So you should click Play. You see the background, the carrots, and the Pause button.
10:31So if anything is missing, or you have an error, just go through your code and
10:34make sure that it matches mine perfectly.
10:37So now the background and heads- up display elements are all set up.
Collapse this transcript
Laying out moles in the Main Game class
00:00Now that the background elements of our game are set up, let's take a look at
00:04laying out the moles on the screen.
00:07The first thing we'll do is, in the initialize game method, right under where we
00:11allocate and init the carrots array,
00:14we'll do the same thing for the moles array.
00:18So CCArray alloc init, and then we'll scroll down to onExit at the bottom of our
00:25code and release the moles.
00:30We'll scroll back up to initialize game. So right after where we create the moles array,
00:36we're going to create some variables that we'll use for padding when we create the moles.
00:40So create two float variables, the first one called hPad, short for horizontal
00:46padding, and we'll set that equal to 20. And the next one we'll call vPad, and
00:52we'll set that equal to 25.
00:55Create a for loop, use a integer called i = 1, and as long as i <= 4--this
01:09represents rows--then i++.
01:12Now we'll create a loop inside of that loop for the columns.
01:16So for int. We'll call this j, set it equal to 1 as long as j <= 6, then j++.
01:28So we have a loop running within a loop: that outer one for the rows, the inner
01:36ones for the columns.
01:38So inside of the inner loop, we'll create a Mole by tying Mole, and we'll call it
01:42mole, all lowercase. And we'll set it equal to, in brackets, Mole
01:51spriteWithSpriteFrameName, and we'll pass in the NS string a0001.png.
02:01Next, we'll set the moles position.
02:02To do that, we'll use a horizontal and vertical padding and our iterators.
02:07So mole.position = ccp, and in the parentheses, we'll first type the X value,
02:16which is going to be j * mole.contentSize.width+hPad, and then i *
02:31mole.contentSize.height + vPad.
02:41Next, we'll add this mole into the moles array.
02:44So Moles, addObject, mole, and finally we'll add this moles to the screen by
02:51calling self addChild mole and give it a z position of 1.
02:58So if we test the app now, in the simulator we should see all of the moles
03:03laid out on the screen.
03:11So I'll click Play from the main menu, and there are all the mole holes.
03:17So we successfully laid out all the moles using two for loops.
03:21So if you ever need to lay out objects in a grid, create some padding
03:26variables, and you can use two for loops, one within the other, to lay out the
03:32objects in a grid pattern.
Collapse this transcript
Animating the moles
00:00Now we'll make the moles animate up and down to give them some more life.
00:04Scroll down into the tick method in Game.m. Note that chooseWhichMoleToMake runs each time
00:12it's time to make a mole.
00:14So let's define what chooseWhichMoleToMake does.
00:17The first thing we'll do is set the nextMoleType.
00:19So type nextMoleType equals MOLE, in all caps, _TYPE_A.
00:24And then we'll run a method called showMole, so self showMole.
00:31Now we'll define what showMole does.
00:34showMole is going to grab a random mole and then present it on the screen.
00:39Here we'll create a variable called mole, all lowercase.
00:44It's of the datatype mole, capital M, and we'll set it equal to double
00:48brackets and inner brackets, CCArray, and then a space, arrayWithNSArray, and then
01:03pass in, in brackets, self getDownMoles.
01:09So we're grabbing a random mole that's down.
01:14So in the outmost brackets, type randomObject, and then on the next line
01:22type some brackets, and in the brackets, type mole startWithType and pass in nextMoleType.
01:29Now let's jump over to Mole.m, and we'll define that animation in startWithType.
01:37At the very bottom of that method, create a few new lines of code and then in
01:41brackets, type self runAction, and the action is going to be, in brackets,
01:49CCAnimate actionWithAnimation and then a colon, and in brackets, self
02:00getAnimationWithFrames. The first parameter will be 1 and then to :10.
02:08After the close bracket, type restoreOriginalFrame:NO.
02:17So we'll have the mole animate up, and let's save and test the app.
02:21So I'll click Play, and the moles should be animating up. There they are.
02:37So now we want to do is make them animate down after instanceUpTime has passed.
02:47So on the next line of code type some brackets and type self runAction:
02:55and brackets, CCSequence actions:
03:01I'm going to type some brackets, comma nil, and then create a new line for the
03:10brackets and the comma.
03:11I'll type a CCDelayTime actionWithDuration.
03:20The Duration is going to be the instanceUpTime, and then on the next line some
03:26brackets and a comma, CCCallFunc actionWithTarget:
03:36self, and then selector will be @ selector and in parentheses, stop.
03:43Now let's scroll down and define what stop does.
03:48In stop, we're going to play the opening animation backwards, so the mole goes
03:53back in his hole, and then reset it to mole.
03:57So I'm going to do a scroll back up.
03:59I'm going to copy those two lines of code where we run the action on self.
04:03I'm going to recycle them for stop.
04:06So I'll paste them into the stop method, and I'm going to change the CCCallFunc
04:12selector to reset. And then I'm just going to cut and paste that CCAnimate
04:18action right over the CCDelayTime.
04:26And instead of getAnimationwithFrames, it's going to be
04:29reverseAnimationwithFrames.
04:33That's going to be 10 to 1, instead of 1 to 10.
04:38So the mole should pop up, stay up for a second or so, and then go back down.
04:43So let's save and test again and see what we get.
04:52So I'll click Play. You see the moles go up, and after a little bit, they go back down.
04:58I'll quit the simulator.
05:06So now our game has more life because the moles animate using frame-by-frame animations.
05:13Remember that you can animate using a CC animation of frames that's passed
05:19into a CCAnimate action.
Collapse this transcript
Handling touches in the game
00:01Now that the moles can animate up and down, we'll look at how to handle touches
00:05so that a mole will get hit when you tap it.
00:08The first place to start is the onEnterTransitionDidFinish method.
00:12Remember that Game is a subclass of CCScene and not CCLayer, so it's not
00:19automatically set as a touch-handling delegate.
00:22That means you don't receive touch- handling events until you register the object
00:28with the touch dispatcher.
00:30So let's start by doing that.
00:31At the top of onEnterTransitionDidFinish, type some double brackets, and in inner
00:37brackets, CCTouchDispatcher sharedDispatcher, and in outer brackets,
00:46addStandardDelegate--it's going to be self.
00:48Remember, we set this object as a delegate of the TouchDispatcher in the Game.h
00:54file. And the priority is going to be 0.
00:58On the next line, we are going to set Multiple Touch to be enabled.
01:01Double brackets again. CCDirector sharedDirector.
01:05After the brackets, type openGLView, and then I am going to type one more set of brackets.
01:12After openGLView, I am going to type setMultipleTouchEnabled to YES.
01:17Now let's scroll up to ccTouchesBegan.
01:20Here the first thing we are going to do is check to see if the game is paused,
01:24and if so, we'll return.
01:26So if isPaused and then just a return.
01:28Remember, we don't want to be handling any touches for the game when it's
01:33not really running.
01:34So first, we'll loop through all the touches.
01:36Let's type for, and this time we are going to do a for in loop.
01:41It's going to be for UITouch *touch in, brackets, event allTouches.
01:52Inside of that loop, we're going to write another for in loop to loop through the moles.
01:56So for, and then it's going to be Mole, with a capital M, and the iterator will be mole,
02:03with a lowercase m, in moles--that's the array.
02:08So capital M is the class, lowercase m is the iterator object, and moles is the array.
02:14Now we need to get the Touch location.
02:17CGPoint location, set it equal to, in brackets, touch locationInView:touch.view.
02:31Next we'll convert this location to something we can use in cocos2D.
02:35So location equals, double brackets, CCDirector sharedDirector convertToGL, then pass in the location.
02:46Below that, let's put an if statement that checks to see if the location is
02:50touching the bounding box of the mole.
02:53So inside of the if statement, CGRectContainPoint.
02:56The Rect is going to be the bounding box of the mole, so, in brackets, mole boundingBox. And
03:02the point is going to be the location of the touch, so just location.
03:07In the if statement, we want to skip this mole if the mole is not up.
03:11So type another if statement, and in that inner if statement, type an exclamation
03:19point, some brackets, type mole getIsUp.
03:24So if the mole is down then we don't want to tell it that it was hit.
03:29So if that's the case then we're just going to continue.
03:32So we're going to go into the next iteration of the loop.
03:35Below that inner if statement, I am going to tell the mole that it was tapped. So, in brackets, mole wasTapped.
03:42Now let's just jump over to the mole class and define what happens when the mole gets tapped.
03:46Let's go to Mole.m and find wasTapped.
03:51In here, we're going to only do the code if the mole was up.
03:54So we are double-checking. So if isUp, then in here, we're going to start by
04:01stopping all actions of self, stopAllActions.
04:02It will stop every action that's currently running. And then on the next line, we
04:07will make them all animate down, so self runAction:,
04:11in brackets, CCAnimate actionWithAnimation-- make sure you choose the one that says
04:17restoreOriginalFrame.
04:19Animation is going to be in brackets, self getAnimationwithFrames, 21 to 31,
04:28restoreOriginalFrame is going to be NO, and then on the next line, we'll set isUp
04:33= NO, and that's it.
04:36Now when you tap a mole, it should play the hit animation.
04:39So save and test the app in the simulator.
04:48So I'll click Play at Main menu, and now I can touch all the moles to hit them.
04:52I'll quit the simulator.
04:59So now it's starting to feel like an actual game.
05:03The moles animate up and down and through touch-handling, we can tell if a mole
05:09was touched and if so, it plays a hit animation.
05:13And remember, if you are using a subclass of CCScene as you main class, make
05:19sure it's adopting the CCStandardTouchDelegate protocol if you are going to
05:23support multi-touch and that in onEnterTransitionDidFinish you set the
05:29CCTouchDispatcher sharedDiespatcher to add the object as a standard delegate and
05:35then setMultipleTouchEnabled through the CCDirector, and then you can handle
05:39touches using a ccTouchesBegan event.
Collapse this transcript
Displaying the player's score with bitmap fonts
00:00When you are working with text fields in cocos2d that constantly update, it's a
00:05good idea to use something called a bitmap font.
00:09Think about bitmap font as a strike sheet of a font.
00:13The texture is only loaded once, and it saves a ton of memory when you are
00:18changing the text in a label.
00:20In the HelloWorld cocos2d app, you see a CCLabelTTF created.
00:26Anytime you change the text in that label, a whole new label gets created.
00:31So if you are running something like a timer that shows text, you're going to be
00:35wasting a ton of memory by creating a new text field every single frame.
00:41Again, bitmap fonts will save you memory.
00:44To create a bitmap font, you can use an editor like Hiero.
00:47You'll have to look it up on the Internet, and you can download and install it for free.
00:55To use Hiero, choose a font that you have installed on your computer, choose the
01:00effects, choose the color, any padding between characters,
01:04you can preview the font here, and then you could save the font as a .fnt file.
01:10So you also want to save a .png file of image.
01:15Sometimes when you save that PNG file, it's flipped backwards, or upside down, and
01:20you can just use the Preview app on your computer to adjust it accordingly.
01:24So I am going to jump back in to Xcode, and now we will look at how to use one of these fonts.
01:30So again, you are going to need the .fnt file and the .png file to display the
01:36text field so make sure to import those into your project after you create them.
01:41So right under where we add the sprites and initialize game, I am going to type
01:46int fSize, short for font size, = 24.
01:52On the next line, we'll create the scoreLabel by typing scoreLabel =, and in brackets,
01:58CCLabelBMFont labelWithString-- String is going to be score:0. And the font
02:08file is a string to the FNT file, and I am going to use an NSString with
02:14format to define that.
02:16So brackets there instead of a literal string, and NSString stringWithFormat.
02:25That's going to be %i.fnt", fSize.
02:36On the next line, we'll set the anchor point to 01 because we want the score
02:41label to be at the top left.
02:42So scoreLabel.anchorPoint = ccp(0,1). That will give it a top-left anchor point.
02:53One the next line, we'll set the scorelabel's position.
02:56So scoreLabel.position = ccp, and parentheses will pass in 0, which will hug it
03:05against the left edge of the screen, and then s.height, which will bring it all
03:10the way up to the top edge of the screen.
03:13Then we'll add it to the screen by typing self addChild:
03:16scoreLabel, and the z position is going to be 10.
03:23Now let's scroll down to ccTouchesBegan.
03:28After a mole was tapped, go to the next line, and in brackets, type self didScore.
03:37Scroll down to the didScore method, and here we'll increment score by 1, so
03:42score++. And then on the next line, we'll set the score label string.
03:48So, in brackets, scoreLabel setString, and string is going to be another
03:55NSString with format, so NSStringWithFormat.
04:02That's going to be score: %i. After the close quote, type a comma and then type score.
04:11So it will show score: and then the score at the top of the screen.
04:18Your score will increase each time you hit a mole.
04:20Save and test this in the simulator.
04:22So I'll click the Play button and each time I hit a mole, you should see the score
04:33increase at the top-left of the screen. Nice!
04:38I'll quit the simulator.
04:41So just remember, bitmap fonts are like sprite sheets for fonts, and you
04:45save a ton of memory because you don't have to create a label every time you
04:49change the string.
Collapse this transcript
Handling misses
00:00To increase the intensity of the game, it's important to make a way for you to lose;
00:05you lose the mole game by missing three moles.
00:09So let's a take a look at how to handle that.
00:12Remember, the mole class sends a missed mole message if you don't hit the mole in time.
00:17So we just need to handle missed mole in the game class to decide what happens
00:21when a mole is missed.
00:23So in here the first thing we are going to do is subtract from carrotsLeft.
00:27So carrotsLeft, two minus signs, and then on the next line if, and in brackets, carrots count > 0,
00:36then we are going to remove that carrot.
00:43So self, removeChild, and the child is going to be, in brackets, carrots objectAtIndex, and
00:54then some more brackets, and in the brackets, carrot count, outside of the brackets
01:01-1, so the last index of that array. Then under cleanup, we will put YES.
01:09And then on the next line, we'll remove the last object from the carrots array.
01:15So carrots removeLastObject.
01:19Then we will check to see if carrots left is less than or equal to zero.
01:28If so, we will run gameOver.
01:30Now gameOver doesn't do anything just yet; we are just setting it up for later.
01:35So in brackets, self gameOver and then the else statement below that if
01:39statement, we are going to tell all the moles to stop early.
01:43So for, this is going to be a for in loop, so it's going to be a mole called "m",
01:52in brackets, self getUpMoles.
01:56That's all the moles that are up and in brackets in the for a loop, m stopEarly.
02:03So we'll make all the moles go down if you miss one.
02:06So save and test in the simulator, and you should see that each time you miss a
02:10mole, a carrot disappears and they all go down.
02:13Now you won't see anything when you actually get a gameOver.
02:17We will define that later on.
02:22So I'll click Play. You can hit a mole but if you miss, they all go down.
02:29And notice that the carrots disappear as well.
02:36So now it's feeling more and more like a game.
02:39Whenever you miss the mole, one of the carrots disappears and all the moles go down.
02:45Remember, you can take an object off of the screen by using the
02:48removeChild method.
Collapse this transcript
Detecting double taps
00:00We have already set up the functionality for the green moles which require a single tap.
00:05Now we will look at adding the blue moles which require a double-tap.
00:10Let's start by going to the tick method and at the very bottom, we will type
00:13canShowBlueMoles and set it equal to YES.
00:18Then in chooseWhichMoleToMake, after the equals sign, after nextMoleType, we're going
00:23to type CCRANDOM_0_1.
00:27That's all caps, and that gives us a number between 0 and 1.
00:30Then we will check to see if it's less than .15. That means a 15% chance that
00:37a blue mole will show. And, so two ampersands, canShowBlueMoles and a question
00:44mark after the parentheses. Then type MOLE_TYPE _B, all caps, then a colon after MOLE_TYPE_B.
00:54Now let's scroll down to ccTouchesBegan.
00:57In here we want to detect a double-tap.
00:59So right above mole wasTapped and self didScore, I am going to type bool, type
01:06greenMoleWasWhacked. We will set it equal to, in parentheses, in brackets, mole getType,
01:22put some out brackets around those brackets, is EqualToString:MOLE_TYPE_A;
01:30After the parentheses, just make sure to put a semicolon.
01:33Let's copy and paste that Boolean statement to the next line, change
01:39greenMoleWasWhacked to blueMoleWasWhacked, and then we are going to check to
01:44see if the mole was MOLE_TYPE_B so change the A to B. And then before the end
01:51of the parentheses, type two ampersands, and then we are going to check to see
01:57if it's a double-tap.
01:58To do that, we just use the method tap count of the UI touch to get the
02:03number of taps that occurred.
02:05So, in brackets, touch tapCount, outside the brackets, > 1.
02:13So if its MOLE_TYPE_B, and if the tap count is greater than 1, then a blue mole was whacked.
02:19Now I am going to wrap mole wasTapped and self didScore in an if statement.
02:25So type if and put some parentheses. In there, we'll check to see if a green
02:31or a blueMoleWasWhacked.
02:32So if (greenMoleWasWhacked || blueMoleWasWhacked) then we will tell the mole
02:41that it was tapped and that we scored.
02:44So, we'll just cut and paste mole wasTapped and self didScore inside of that if statement.
02:51Now let's save and test the app.
02:53We should see that 15% of the moles are blue and that you can only knock out a
02:58blue by double-tapping it. So click Play.
03:07So green moles, and they take a single tap still and then blue moles, you tap them once,
03:14they don't do anything.
03:15We tap them twice pretty quick and then go down.
03:26Now we've successfully handled a double-tap.
03:30So remember that you can access the amount of taps by the touches tapCount
03:35method, and that returns an integer that will tell you how many times an
03:39object was tapped.
Collapse this transcript
Detecting simultaneous taps
00:00Now we will add the yellow moles that must be tapped simultaneously. Scroll to
00:05the tick method. After canShowBlueMoles is set to YES, set canShowYellowMoles
00:12equal to YES and scroll up. And to choose which mole to make,
00:17set nextMoleType right below where we set it before, equal to MOLE_TYPE_C.
00:26On the next line, I want to it call to self showMole again.
00:30We are going to create two at a time when we create yellow moles.
00:35Now scroll down to ccTouchesBegan. Right below the if statement where
00:38we are trying to see if it's paused, create an NSMutableArray and call it molesTappedAtOnce.
00:49Now we will just initialize the array using NSMutableArray alloc and init.
00:59Find the if statement that checks to see if the mole is not up. Right before
01:04the close parenthesis, type || for an OR statement.
01:09We also want to continue the loop if the molesTappedAtOnce array already
01:14contains the mole that we are looking at.
01:17So, in brackets, molesTappedAtOnce containsObject:mole).
01:27Below this if statement we are going to create another if statement and check to
01:30see if a yellow mole was tapped.
01:35So in the if statement, in double brackets, in the inner brackets, (mole getType isEqualToString:MOLE_TYPE_C) then we are
01:49going to add this mole to the molesTappedAtOnce array.
01:53So, in brackets, molesTappedAtOnce addObject:mole. Now scroll down and outside of the for loop,
02:04which goes through all the touches, so right above the end of this method, check
02:10to see if molesTappedAtOnce has a count that's greater than 1.
02:14So if statement, and then in brackets (molesTappedAtOnce count > 1). If so, that means that more than 1
02:27mole was tapped at the same time.
02:28So we are going to loop through all those moles using a for in loop, so for
02:35(Mole *m in molesTappedAtOnce) and then in the for loop m wasTapped;
02:48on the next line, self didScore.
02:51Below that if statement, we are going to remove all objects
02:55from molesTappedAtOnce.
03:00At this point, you can save and test to make sure the yellow moles are
03:03appearing in simulator, but you won't be able to hit them because you don't have
03:08fine control over multi-touch in the simulator.
03:11So really, all you can do is a pinch.
03:15So you will need to test it on your own device at this point to make sure that
03:19the yellow moles are working properly.
03:20So there are the yellow moles, and they are appearing two at a time, and they disappear.
03:27So I will quit the simulator and just remember, you can handle multiple
03:32touches at the same time by storing the objects in an array and then after you
03:39loop, where you loop through all the touches, check to see if that array has
03:43a count greater than one. Then you can send the appropriate messages to all the
03:48objects in the array.
Collapse this transcript
Controlling the number of moles on the screen at once
00:00Most games start out relatively easy and get more difficult as they go.
00:06Now we'll add that feature to our game by adding more moles and different types
00:11of moles as the game goes on.
00:14In the init method you'll see molesAtOnce is set to 3, timeBetweenMoles is set
00:19to 0.5, and increaseMolesAtTime is set to 10.0.
00:23We will use these properties together to make the game start out easy with just
00:28green moles, eventually add blue and yellow moles as the game goes on.
00:33So scroll down to the tick method.
00:37In the tick method, we're going to add onto increaseElapsed by the amount of Delta Time.
00:43That's DT.
00:45So type increaseElapsed += dt.
00:49Below the if statement that checks to see if timeElapsed >= timeBetweenMoles, go
00:55to the next line and then create a new if statement that checks to see if
01:01increaseElapsed >= increaseMolesAtTime.
01:07If so, we're going to make the game more difficult.
01:10The first thing we'll do is define how many moles we can have at once on the screen.
01:14So create an integer called maxMolesAtOnce and set it equal to 18.
01:22So that's the max amount of moles that can possibly be on the screen at one time.
01:27Now, an if statement:
01:28if (molesAtOnce < maxMolesAtOnce) then we'll increment molesAtOnce. So molesAtOnce++.
01:41Then we'll go to the next line, create a float called minMoleTime.
01:46This will represent the minimum amount of time between one mole popping up and
01:51another mole popping up.
01:52We'll set this equal to .1f.
01:56Now, in the next line we're going to subtract from the timeBetweenMoles.
02:01So as the game gets more difficult, there's less time between moles popping up.
02:05So timeBetweenMoles -= and in parentheses, we're going to check to see if
02:13timeBetweenMoles > minMoleTime.
02:16Now, if so, I'll put a question mark and type 0.05f.
02:24So we'll subtract from it in a very small amount each time the game gets more
02:29difficult, and put a colon. And if it's already reached the minimum mole time,
02:36we're going to modify it by nothing. So just put a 0.
02:41Go to the next line and then type increaseMolesAtTime += 10.0f.
02:48That will make the game gradually get harder.
02:51So the first time it happens is after 10 seconds, then the next time is after 20
02:55seconds, and the time after that it's after 30 seconds.
02:58Now, below that if statement, we'll create another if statement--remember we're
03:03still in increaseElapsed >= increaseMolesAtTime.
03:08So this if statement is going to check to see if canShowBlueMoles is true.
03:11I am just going to cut and paste canShowYellowMoles = YES, put that right inside
03:18of that if statement,
03:20and below the if statement we just wrote, we'll create an else statement, and
03:23then we'll cut and paste canShowBlueMoles = YES into the else statement.
03:30So the first time this runs, canShowBlueMoles will be NO.
03:34So it'll run the else statement, set it to YES.
03:36When it runs again, canShowBlueMoles will be YES, so canShowYellowMoles will be set to YES.
03:42So let's scroll up to choose which mole to make to control which mole shows.
03:48Remember, this is where we're going to control whether or not a mole gets made,
03:55because each time timeElapsed >= timeBetweenMoles, as stated in the tick method,
04:02we're going to run chooseWhichMoleToMake.
04:03So what we're going to do in here is, if there are too many moles on the screen,
04:08just back out of this method entirely.
04:11So the first thing we want to do in chooseWhichMoleToMake is write an if
04:14statement. And in the if statement, type some brackets and type self getMolesUp.
04:20Remember, that returns an integer of moles that are up.
04:22We're going to check to see if that's greater than or equal to molesAtOnce.
04:25Now, if there are already too many moles on the screen, and we just want to
04:30get out of this method, so we'll do return. And then we have nextMoleType set
04:36to be RANDOM for the blue moles, and we have a check for canShowBlueMoles, so
04:42that's already good.
04:43We just need to modify how we show yellow mole.
04:45So let's go to the next line and type if.
04:48In the if statement we want to see if we have enough space in the moles that can
04:53be on the screen to allow two moles to pop up.
04:57So in brackets, self getMolesUp, and then out of the brackets is < molesAtOnce - 1.
05:07So in other words, we have enough space to put two moles up at once.
05:11And we want to make sure that there's a small chance that this happens, so
05:15CCRANDOM_0_1() < .1. And, so two more ampersands, canShowYellowMoles.
05:28Now, if that's the case, we're just going to cut and paste nextMoleType =
05:32MOLE_TYPE_C and self showMole, and place it right inside that if statement we just wrote.
05:38So if all the appropriate conditions are met, we show a yellow mole or else we
05:43show a blue or a green mole.
05:46So let's play the game in the simulator.
05:48Now, when you play the game, you want to look for seeing only green moles at
05:56first, and after 10 seconds, you should see the blue moles start popping up, and
06:01after 20 seconds from there, you should see the yellow moles popping up.
06:05So I will click to play the game, and at the beginning, we see only green
06:10moles, and then after about 10 seconds, you should start to see blue moles start appearing.
06:17Now, if it doesn't happen at first, just give it some time, because it's random.
06:24So there is the blue moles, and we have the yellow moles too.
06:26I will quit the simulator.
06:31So you see, the game gets harder and harder as you go.
06:34You may have also noticed as you were playing that more and more moles are
06:38appearing on the screen at the same time as time goes on.
06:41So we've successfully created a game that starts out easy and gets more
06:47difficult as time goes on.
Collapse this transcript
Adding sound
00:00Now we will add sound effects and music to the game.
00:03Go to your initializeGame method, and right under where we set the value for s,
00:08we'll set the value of missSound.
00:11This is a string, and it's going to be the name of the sound that happens
00:15when you miss a mole.
00:16So to set it, I'm going to use an NSString stringWithFormat, and the format is
00:24going to be %@_miss.wav", delegate getCurrentSkin.
00:39That way whenever we change the skin, it will either play mole_miss.wav
00:45or jetpack_miss.wav.
00:48So I created the game from the beginning to support this skinning feature.
00:51So let's just copy and paste this line of code to the next line, change
00:56missSound to hitSound, and adjust the string to say _ouch instead of _miss.
01:05Now let's preload all of the effects.
01:07So go down a few lines, double brackets, and in the inner brackets,
01:13type SimpleAudioEngine.
01:14You may have to import this class, if you haven't already. Space, sharedEngine.
01:19In the outer brackets, preloadEffect, and we will pass in missSound.
01:24We can copy and paste this line and preload hitSound.
01:34Paste the line again on the next line, and instead of missSound, we will change
01:39this to a literal string, splat.wav.
01:43We're going to use the splat sound for both skins.
01:47Paste the code one more time and change preloadEffect to preloadBackgroundMusic.
01:55Here we'll type some brackets, and then NSString stringWithFormat.
02:02This is going to be %@_bg.mp3, and then again after the close quote, comma, and
02:11then brackets, delegate getCurrentSkin.
02:14Now, all this does is preload the sound effects so that when they first occur,
02:18there won't be any kind of a delay.
02:20So all the delay will be preloaded before the scene itself loads.
02:26Now let's look at playing the sounds.
02:28The first thing I am going to do is play the background music.
02:32So I am going to copy the line of code that says preloadBackgroundMusic.
02:36I am going to scroll down to startGame. Right above self
02:41schedule:@selector(tick:), I'm going to paste that code and change
02:45preloadBackgroundMusic to playBackgroundMusic.
02:49Right before the last close bracket, I'm going to type a space, and then I'm
02:52going to type loop, and then I'll type YES in all caps.
02:56That way, the background music will loop over and over again as you play the game.
03:01Now let's scroll to ccTouchesBegan, and we'll add in the hit sound effects.
03:11So right under mole wasTapped and self didScore in the if statement that checks
03:16if a green or blue mole was whacked, let's go down a few lines, some double
03:22brackets, inner bracket, SimpleAudioEngine sharedEngine and then playEffect, and
03:29we can choose the one with pitch, pan, and gain.
03:32That way we can control the pitch, panning, and volume of sound.
03:36So the effect is going to be hitSound. The pitch will be 1.
03:42If you want to randomize it, you could put a CC_RANDOM right here.
03:46Pan will be 1, and gain will be .25.
03:55This is a value that goes from 0, which is completely off, and 1, which
04:00is normal, full volume.
04:02So you can adjust this to whatever you want here.
04:04Go to the next line.
04:05I'll do the same thing:
04:09double brackets, inner brackets, access the sharedEngine of SimpleAudioEngine,
04:14and then we'll playEffect. And instead of the one with pitch, pan, and gain,
04:18we're just going to use the one that requires a string.
04:23And the effect will be a literal string, splat.wav. Copy and paste these two
04:30lines of code in the line of code where we detect yellow moles.
04:34Now, I'm not going to put this in the loop.
04:37I don't want two sound effects to happen when you hit two moles at the same
04:40time; I just want one sound effect.
04:42So that's going to go under the for loop, but inside of that if statement that
04:46checks to see if molesTappedAtOnce's count is above 1.
04:51Now let's scroll down to missedMole, and we'll play a sound there as well.
04:56Right under carrotsLeft--, paste the code, delete the line of code that says
05:03splat, change the effect to missSound, change the gain to .2, and that's it
05:13for adding the effects.
05:14What we want to do to preserve memory is to unload the effects when the scene unloads.
05:19We can do that in the onExit method.
05:21So scroll down to there, and under carrots release and moles release, we'll
05:27paste in the code that we copied earlier.
05:31We'll change playEffect to unloadEffect, and we'll do this for hitSound and missSound.
05:37So I'll just copy and paste that and change hitSound to missSound in the pasted code.
05:44And in playEffect:@"splat.wav", I'll unload that effect.
05:48So at this point you should be able to test the app and hear the sound effects and music.
05:55So on the simulator, when you play the game, you should be able to click on a
05:59mole and hear the hit sound;
06:02miss a mole, and when the carrot disappears, hear the miss sound;
06:06and you should hear the splat sound when you hit a mole, and you should hear
06:10the background music.
06:11So I'll click to play the game. (audio playing)
06:17When I hit the mole, you hear the hit sound;
06:19when I miss, you hear the miss sound;
06:21and in the background, you hear the background music.
06:24Now that our game has sound effects and music, it has more life, and it feels
06:32more like a game than ever.
Collapse this transcript
Enabling a pause feature
00:01Have you ever played a game that didn't have a pause feature?
00:04Even a short game, like the game we're making here, can use pause, because you
00:09never know when someone might be competing for the highest score, and they've
00:13been playing for two hours straight, and they don't want the game to end, but
00:17they get a call or some other thing that makes the gameplay stop.
00:22You don't want to throw out all their progress.
00:24So let's take a look at how to pause the game.
00:27So in the pauseGame method in the game class, the first thing I am going to do
00:31is check if the game is paused.
00:35If the game is paused, I am just going to return.
00:38So if(isPaused) and then return.
00:42Next, we will make the Pause menu.
00:44So CCmenuItemSprite. We'll call this first one resumebutton, and we will set it
00:53equal to, in brackets, CCmenuItemSprite, itemFromNormalSprite, selectedSprite,
01:00target selector--make sure you choose that one.
01:02The NormalSprite is going to be in brackets, Gamebutton buttonWithText, and then
01:10pass in the text as a string.
01:12So it will be resume.
01:14This font is all caps, so it doesn't matter if you put capital or lowercase letters.
01:18So I am putting all lowercase for this, and now it's set selectedSprite to NULL,
01:23target is going to be self, and that selector is going to be resumeGame.
01:31Copy and paste this line of code to the next line, change resumebutton to
01:37mainbutton, change the text to main menu, change the selector to mainmenu, with a capital M.
01:50Now, we'll create the menu and add these buttons.
01:54Make sure you use CCmenuPopup.
01:56We'll call this menu, set it equal to, in brackets, CCmenuPopup menuWithItems,
02:06pass in the resumebutton and then the mainbutton and then nil.
02:12On the next line, in brackets, type menu alignItemsHorizontallyWithPadding and pass in 10.
02:21Now, we will create the pop-up menu itself.
02:23Data type is PopUp.
02:25We will call this pop, set it equal to, in brackets, PopUp popUpWithTitle
02:34description and sprite.
02:37Title is going to be "pause" in the middle of hyphens.
02:40The description is just going to be an empty string, and the sprite is going to be the menu.
02:49We'll add the pop-up as a child by calling self addChild.
02:51I will pass in pop, give it a z of 1000 so it's in front of everything.
02:57That we'll hide the pause button, so we can set it to visible property to NO.
03:02We'll make all the moles stop early, so we'll use a for in loop for that. So for
03:10(Mole *m in self getUpMoles, and we'll send the message to m to stop early. So m stopEarly.
03:25On the next line, we will unschedule the tick selector.
03:27So self unschedule:@selector (tick). We will pause the background music.
03:35So, inner brackets, SimpleAudioEngine sharedEngine, and outer brackets, pauseBackgroundMusic,
03:44and set isPaused = YES.
03:47Now in resumeGame, we'll just copy the last several lines from
03:53pausebutton.visible = NO all the way to the bottom of pauseGame.
03:57I will paste them into resumeGame.
04:00I will delete that for loop in resumeGame, change pausebutton.visible to YES,
04:08change self unschedule to self schedule, change audio engine
04:13pauseBackgroundMusic to resumeBackgroundMusic, and set isPaused = NO.
04:18Now, you should be able to test the game in the simulator and be able to pause
04:23and resume the game.
04:28So I will click Play to play the game.
04:30You hear the background music. (audio playing)
04:33I will click Pause. The background music stops; the Pause menu shows up.
04:38I see the Resume and Main menu buttons.
04:40I can click Resume and the game resumes. (audio playing)
04:43I can pause it again.
04:45I can click Main menu and return to the Main menu.
04:48So I'll close the simulator, and now we've successfully added a pause feature.
04:52So manly what we did is we stopped running that tick selector, we told all the
04:58moles to stop, and we set isPaused = YES. And the TouchHandlers, and in some
05:04other methods, we return automatically if isPaused is set to YES.
05:09And that way, the game is completely frozen when we choose to pause it.
Collapse this transcript
Ending the game and saving the high score
00:00Now we'll finish the main part of the game by creating a gameOver screen and
00:06allowing the pLayer to restart from the beginning, and we'll also look at saving
00:10the high score to the device.
00:12We're already calling gameOver when all the carrots are gone,
00:16so all we need to do is define the gameOver method.
00:19I am going to start with copying and pasting all the code in the pauseGame
00:23method that's under the if statement at the beginning.
00:26I'll paste that into the gameOver method, and we'll make a few modifications.
00:32The first thing I'll do is just cut and paste all the code that doesn't have to
00:36do with the menu, to the top of the method.
00:42So before anything else, we're going to stop all of the interactivity in the game.
00:45I am not worried about hiding the pausebutton here, so I am just going to
00:49delete that line of code.
00:51And instead of looping through all the moles that are up, I am going to loop
00:55through all the moles that were created by looping through the moles array.
01:01And for each mole in there, I am going to delete stopEarly and tell it to stopAllActions.
01:08And then I'm going to tell each mole to unscheduleAllSelectors.
01:13Below the for loop, tell delegate that we finishedWithScore, and I'll pass in
01:19the final score, which is in the score property.
01:23I'll change unscheduled:@selector (tick:)
01:25to unscheduleAllSelectors, and I'll change pausebackgroundMusic to
01:29stopBackgroundMusic.
01:32And I'll delete isPaused equals YES.
01:37Now we'll modify the code for the menu.
01:40We still want the Mainmenu button, but we're going to change the resumebutton to
01:44the playAgainbutton.
01:46So I'll change resumebutton's variable name to playAgainbutton.
01:52I'll change the resumeGame selector to playAgain.
01:54That will run the playAgain method, which will reload the game scene.
01:59And finally, I'll change the text for the playAgain button to be play again.
02:05And now, when creating the menu, I'll have to change resumebutton
02:09to playAgainbutton.
02:10And in the PopUp, I'll change the Title to game over from pause.
02:14Now, the high score already displays on the Mainmenu, so we just need to update
02:19the delegate's high score in the finishedWithScore method and make sure that we
02:23save this score to the device.
02:26So let's go over to AppDelegate.m and find finishedWithScore.
02:30I'm going to Command+Click the Method Selector at the top of the screen and
02:36choose finishedWithScore.
02:38Command+clicking that menu allows you to go to your selectors in
02:42alphabetical order.
02:45So here we can check the high score retained by the device in the
02:49getHighScore method.
02:50That grabs the value from the UserDefaults.
02:53So in here let's write an if statement to check to see if score is greater
02:58than the high score.
02:59So if score is greater than, and in brackets, self getHighScore, then we're going
03:06to save the high score to the device.
03:09So in double brackets, NSUserDefaults, standardUserDefaults. In the outer
03:15brackets, setInteger, and the integer is going to be score, forKey, and the key
03:22will be kHighScoreKey. And that's it.
03:26And remember that in the Mainmenu, we have a reference to the High Score in the High Score label.
03:35So we're referencing delegate's High Score and putting it in that label.
03:40Before we test it, we're going to do one more thing in the Game class, and at
03:44the very bottom, in the onExit method, we're going to do something to optimize
03:50memory, and that's where we're going to disconnect the Game class from being a
03:56delegate of the TouchDispatcher.
03:59So double brackets, and in the inner brackets,
04:02CCTouchDispatcher sharedDispatcher;
04:05in the outer brackets, removeAllDelegates. And that will just make sure that
04:12the TouchDispatcher is not holding on to an old instance of the game.
04:15So this will completely finish our main portion of the game, and now we'll
04:20test it in simulator.
04:21So you see High Score is 0 here.
04:29I'll play the game. (audio playing)
04:31We get a High Score of 1, and at the end you'll see the Game Over screen, and
04:36from the Game Over screen, I can return to the Main menu and see that my High
04:40Score is saved as 1.
04:41I'll click to Play.
04:45I can play the game again and get a higher score.
04:47And from the Game Over menu, I am going to click to Play again, and then I can
04:56return to the Main menu, and I'll see that my High Score is now 2, which is the
05:00second highest score that I got when I played the game the second time.
05:04So I'll close the simulator, and now we have successfully finished the basic
05:09gameplay of our game.
05:11So just remember that you can save and display high scores using simple calls
05:15to user defaults.
Collapse this transcript
4. Expanding Your Game's Features and Audience
Adding custom skins
00:00Skins are one feature that adds to the replay value of your game because you
00:05get different art, and it almost feels like you're playing an entirely different
00:09game when you just have a new skin.
00:12Throughout this course, up to this point, we have designed just about
00:15everything to support skins.
00:17You'll remember that in the game class all the sound effects are based on the
00:22current skin--same thing for the background art and the main sprites.
00:27You'll notice in the Art folder, in the Resources folder, that there is
00:32jetpack.plist for the jetpack sprites and there's mole.plist for the moles sprites.
00:38All we have to do is adjust the delegate's current skin property and we have
00:42different art in the game. So let's go to the Main menu to do that.
00:47The skins button in the main menu runs the select skin method. This method shows
00:52the different skin icons and runs the selectors jSkin and moleSkin for the
00:58jetpackSkin and the moleSkin respectively, so let's scroll down, and jSkin and
01:04mSkin will tell the delegate to set the new skin.
01:08So in jSkin, in brackets, delegate setCurrentSkin. It's just going to be
01:16SKIN_JETPACK, and the same thing for mSkin: in brackets, delegate
01:23setCurrentSkin SKIN_MOLE.
01:27So if you test the app in the simulator, you should see that you can click on
01:32the skin's button, change the skin to the alien skin--you'll see that reflected in gameplay.
01:37Now if you're wondering why I called the alien skin jetpack, it's because it's
01:44based on it another game I made called Jetpack Handyman.
01:48So here's the alien. Click the Play button and then we have the alien skin.
01:54So there's green ones, and after a while you'll see blue ones and then yellow ones
02:00come up. So back to the main menu and if I click Skins again, I can click on the
02:07Mole and the game has the moleskin.
02:10So I close the simulator.
02:18So if you want to support skins in your game, it's best if you plan ahead and
02:22you have all the files named accordingly, and then all you have to do is make
02:27simple calls to the delegate to set the current skin to the new skin.
Collapse this transcript
Asking players to rate the game
00:00A good rating in the App Store can make or break your sales.
00:04In order to get your customers to rate your game, you might have to remind them
00:09when they're playing it.
00:10Let's take a look at how to do that.
00:12The AppDelegate class implements the alertView protocol.
00:17In alertView clickedbuttonAtIndex handler, I have it set to return if
00:23the buttonIndex is 0.
00:25If it's not 0 then I open a link to my game, which I copied from my iTunes
00:31Connect page, and then I set the value Yes for the kDidRate key in the user defaults.
00:37So let's look at how to show this alert by going to finishWithScore.
00:43So I'll move to that method.
00:44I'm going to write the code right below this if statement. And here I'll
00:50increase timesPlayed by 1, and I'll the save the amount of times played in user defaults.
00:57So double-brackets, NSUserDefaults standardUserDefaults setInteger timesPlayed
01:05forKey, and the key is going to be kTimesPlayed. And then I'm going to ask the
01:13user to review the game every 10 times they play.
01:16So if (timesPlayed % 10 = 0), that'll mean if timesPlayed divided by 10 has a
01:30remainder of 0--so if it's a multiple of 10--then we're going to ask the
01:34pLayer to rate the game.
01:36We also want to make sure they didn't already rate it.
01:38So && !, and in double brackets, NSUserDefaults standardUserDefaults boolForKey: kDidRate.
01:51So they didn't rate the game, and then they played it a multiple of 10 times.
01:57If so, we want to ask them to rate the game. So we'll create the alertView. It's UIAlertView.
02:02We'll call this alert, set it equal to, in double brackets, UIAlertView.
02:10I'll allocate it and use initWithTitle, and the title is going to be "Like Mole It?"
02:21and then the message will be, "If you like Mole It, please rate it to show your support."
02:33Delegate will be self, cancelbuttonTitle will just be Cancel, otherbuttonTitles
02:41will just have one, will be Rate, and then we'll show the alert.
02:46So, on the next line, in brackets, alert show.
02:51Now, of course we want it to have in every 10 times, but just for testing
02:55purposes, let's change that to 2, timesPlayed % 2, and then once we've test it, we
03:02will change it back to 10, just so we won't have to play the game 10 times in a
03:05row to make sure that the pop-up window shows up.
03:08So I'll click to play the game.
03:12I'm not going to click on any of the moles.
03:14I'm just going to get a gameover.
03:16And that first time a call should have been sent to finishedWithScore and the
03:20delegate, and then timesPlayed should be incremented by 1.
03:24And if I play again, when I get gam over, I should then see the pop-up
03:28window, and there it is!
03:32If you like Mole It, please rate it to show your support.
03:36If you click Rate, it won't work in the simulator.
03:39You'll actually have to use your device, because the App Store is not on the
03:43simulator, so it won't work.
03:44But feel free to test that on your device if you want to, and then click Cancel,
03:49and we'll close the simulator.
03:51So now we've successfully set up the functionality to ask the user to rate the game.
03:56I'll just change that to back to 10, and we're done.
04:00So if you want to ask a player to rate the game, keep track of how many times
04:04that they've played the game, and then every so often you can present an alert
04:10menu that will ask the player to rate the game.
04:12And if they click Rate, just send them your link that you get from iTunes
04:16Connect, and it will launch that app in the App Store, and they will be able
04:20to rate it.
Collapse this transcript
Adding support for the Retina display
00:00If you have a device that supports a high resolution and you're forced to run
00:05low-resolution games on it, they don't look so great.
00:08It's always best to support the retina display, if you can, in your games.
00:13To do that, all you need to do is start out with the art at double resolution.
00:19Save versions at the high resolution and at the low resolutions throughout your
00:24project, and it'll be easy to incorporate retina display features later on.
00:29All you have to do is give the retina display versions an -HD suffix--
00:36jetpack-hd.plist for the HD version of the sprites.
00:41So it applies for all the file types.
00:45So with that, go into AppDelegate and change the setting of the director to
00:51enable retina display by calling director ensableRetinaDisplay and passing in Yes.
00:57This value you returns Yes if retina display supported and No if it's not.
01:03So if you ever need to check if retina display is supported, you can check when
01:08you apply it and save that value for later on.
01:11So now I can test the game in the simulator and see what I get.
01:15You'll notice that it looks exactly the same in the regular simulator, because
01:20the regular simulator runs the standard iPhone resolution.
01:24You can do with a high-res version in the simulator if you'd like by changing
01:29settings in your simulator.
01:31So everything looks fine and normal here on the title screen and if I go to
01:35Hardware > Device and change it to iPhone (Retina), then you can see what it looks
01:41like on retina-display device.
01:42So we'll just open Molelt.
01:47There it is. It fills the whole screen, and it looks just fine at this
01:53higher-resolution display.
01:54Now of course it's better if you actually have a device to test on, but you can
02:00just see what it looks like by watching my screen here.
02:03So if you really want to see it on a device, just plug in a retina display device
02:07into your computer and you can test it that way.
02:10So remember, to support the retina display, you need two things, hyphen HD suffix
02:15on the files that are high definition, and then you need to tell the director to
02:20enable the retina display.
Collapse this transcript
Adding support for the iPad
00:00Let's say you want to make your game universal.
00:03The first step is to go into your project settings.
00:06You can click on your Target, and change the device to Universal.
00:10Now, as far as cocos2d is concerned, there really isn't any difference.
00:15While there is a different aspect ratio and different screen size, that's really
00:20all you have to worry about.
00:22What I usually do is use the HD Sprites for my iPad version, and I make separate
00:29unique backgrounds for the iPad version.
00:31Let's take a look at how to implement some of that.
00:34Go to Mainmenu.m, and then we'll create a variable that checks to see whether
00:40the game is running on an iPad.
00:42So this will be a Boolean right under CGSize s. We'll call this isIPAD, and we'll
00:47set it equal to, double-brackets, in the inner brackets, UIDevice, currentDevice,
00:56in outer brackets, user InterfaceIdiom, after the brackets, two equal signs and
01:04then UIUserInterfaceIdiomPad.
01:09Then we can tell if we're working with an iPad.
01:13So for the file name of the sprites, we'll check to see if it's an iPad and then
01:18load the HD version.
01:21If you want, you can even do this on one line.
01:24After the equal sign, put some parentheses and then put isIPAD, after the
01:29parentheses, a question mark, and space, and a colon, and then just copy the
01:37NSString, stringWithFormat and paste it in between the question mark and the colon.
01:43After the @ symbol in the pasted code, type -hd. So if it's iPhone, we'll use
01:50the normal sprites, and if it's retina, the system will automatically know to
01:54load the HD version.
01:55But if it's iPad, we'll tell it to load the HD versions of the sprites.
02:00Then scroll down, and where we set the title.png for the main screen to load,
02:07actually I have a file called title_IPAD.png in the Assets folder, and that's a
02:13full background for the iPad. It looks like this.
02:18So back to Mainmenu.m and after the equals sign in the fileName line of code,
02:23we'll check to see if it's an iPad.
02:25And if so, we'll load title_IPAD.png, and a colon after that. And if not, we'll
02:35just load regular title.png.
02:37So when you test the App, change the target device to iPad 4.3 simulator, and
02:44you can test the app in the simulator and you should see the iPad version with the iPad art.
02:48So here's the iPad simulator and you see the iPad background and the sprites.
02:57And if you wanted to, you can change the font sizes because they're a little bit small.
03:01So you do that in the same way.
03:04You check to see if it's an iPad.
03:07If so, you put in the custom size for the font, which we already have set in
03:12the F size variable.
03:14So if you'd like, you can do that, but for the rest of the game, you would go
03:18through any time when you're loading some kind of asset, you can load the iPad
03:23version if it's an iPad, and the regular version if it's an iPhone.
03:28All you need to do to support the iPad is change your application settings, and
03:34then you can check to see if it's an iPad with some pre-built Apple code.
03:39Then you can hold whether it's an iPad in a variable and then choose which files
03:44to load based on which device the user is using.
Collapse this transcript
5. Placing Ads in Your Game
Setting up iAds for your app
00:00Before you can put iAds in your game, you need to do some setup in iTunes Connect.
00:05So the first thing you want to do is go to your application in iTunes Connect,
00:10and then you can click Set Up iAd Network.
00:13If this is the first time you've used the iAd Network, you may have to
00:16look through a contract.
00:18You can find that in the Contract section in iTunes Connect.
00:21So if you've done that already, then you can choose to enable iAds.
00:25Now here it's asking if my primary audience is users under 17 years of age.
00:32Now I'm going to click Yes because this is kind of a kids game and though
00:37people may be of all ages that are playing it, there are going to be a lot of
00:40kids, so I'll just click Yes, and I'll click Enable iAds. Then I can click
00:45Save, and Apple asks me if I'm sure that I have a young audience. I'm going to
00:50click Yes and save that.
00:52So if your app is geared towards an older audience, you don't have to target a
00:57young audience like I'm doing here.
00:59So the next step is to go over into Xcode.
01:03Now you want to make sure that you've imported the iAd framework.
01:08You can do that by clicking on your project and going to Build Phases. So in
01:13here, under Link Binary With Libraries, you can add iAd.framework.
01:19So once you have added iAds and you've brought in the framework into Xcode,
01:24you're ready to start writing the code to add iAds into your game.
Collapse this transcript
Understanding iAd delegate methods
00:00To add iAd into our game, I created a helper class called AdViewController.
00:05The AdViewController class imports the iAd framework and adopts the
00:10AdBannerViewDelegate protocol.
00:12It has an AdBannerView and some other properties and methods.
00:17Let's go to AdViewController.m. The init method initializes the delegate object,
00:24viewDidLoad runs super viewDidLoad, grabs the EAGLView from the CCDirector and
00:31adds it as a sub-view of this view.
00:35In our game, the add view is going to act as the main view rather than the EAGLView.
00:41We'll look at how to do that when we actually write the code, later on.
00:44Then I have to check to see if iAdIsAvailable, which is a simple method that
00:49returns if the device is running the appropriate operating system.
00:54Initialize adView set its size and its frame, set this object as a delegate of
01:01the ad view, and then put the adView as a sub-view of this view.
01:07Then there are the delegate methods.
01:09There's bannerViewActionShouldBegin, which says an ad is going to be displayed on
01:14the screen in full screen.
01:16That means that your application should pause.
01:19You also get information about whether it's going to leave your application.
01:24So here's how I handle that.
01:26If the app won't leave then I pause the delegate.
01:30bannerViewAction did finish means the user finished looking at an ad, in which case
01:35I resume the delegate.
01:37bannerViewDidLoadAd means an ad loaded.
01:41If an ad loaded, I run the showBanner method, provided that the delegate tells me
01:46that it's on the game scene.
01:47Then there is a method to handle when the banner fails to load an ad. Then I
01:52set adIsLoaded to NO and hide the banner.
01:56showBanner sets bannerShouldShow to YES.
01:59If the banner is already showing, it returns. Then using core animation it
02:04animates the banner to slide up at the bottom of the screen.
02:08hideBanner does the opposite. getAdHeight returns the height of the ad, and here's
02:13iAdIsAvailable which checks to see if the iAdClass is accessible.
02:18So if you don't have access to the exercise files, copy down these methods as
02:22written and you'll be up to speed to add this into your project.
Collapse this transcript
Implementing iAds in your game
00:00Now we'll implement iAds into our game.
00:03In AppDelegate.h, add an import statement to import the AdViewController class.
00:11Right below NSString currentSkin, let's create an AdViewController called adView, capital V.
00:19Notice there are a few helper methods in here, like getAdHeight, hideBanner, and showBanner.
00:24Go to AppDelegate.m and at the top of your code, in applicationDid-
00:31FinishLaunching, scroll down and after the director sets the GLView, give the value to adView.
00:39So set it equal to AdViewController, allocate and init, and then scroll down,
00:50and where it says viewController setView to glView, we're going to set the
00:54view to adView.view.
00:57Remember, the glView is a child of AdViewController.
01:02Now scroll to the bottom of your code to find the definitions for getAdHeight,
01:07hideBanner, and showBanner.
01:09For get AdHeight, return adView getAdHeight.
01:15For hideBanner, run adView hideBanner.
01:21And for showBanner, run adView showBanner.
01:24Now let's go over to Mainmenu.m. We want the ads to only display while the game is playing.
01:34So after you set the delegate, run the method for the delegate to hideBanner.
01:41Then go to Game.m. In here, after you set the delegate, tell the delegate
01:46to show the banner.
01:49And then when you set the position of the pause button, find that line of code
01:54and right before the close parenthesis,
01:56we're going to add on the height of the ad. So in brackets,
02:00delegate getAdHeight.
02:05Now, if you don't have access to the exercise files, you should be able to
02:08test now and see that everything works fine, but I made one modification to
02:13how the game auto-rotates that we'll have to change real quick to get the
02:17iAds working properly.
02:20If you're using iAds in landscape, it's best to have the UIViewController
02:24handle autorotation.
02:26So in GAME_CONFIG.H, change GAME_AUTOROTATION to
02:30kGameAutoRotationUIViewController. And that's it.
02:35You should be able to test the app now.
02:37And in the simulator, when the game is playing, you should see an iAd.
02:41It's not going to be an actual ad;
02:44it's just going to be a sample ad, because you only see real ads when your game
02:48is in the App Store.
02:51So, no ads on the Main menu.
02:52And if I click Play, and there is the iAd on the screen.
02:57You can see the Pause button is up a little bit, right above the ad.
03:01I can pause and return to the Main menu, and the ad goes down.
03:05So you can use this adViewController helper class in your own apps, and all
03:10you need to do is make calls to showBanner and hideBanner, and you can show
03:14ads within your games.
Collapse this transcript
6. Adding In-App Purchases
Setting up In-App Purchases (IAPs) in iTunes Connect
00:00Another way you can make money off of your games is through in-app purchases.
00:05In-app purchases are often referred to as IAP.
00:08You can add an in-app purchase through iTunes Connect by going to your
00:12application and clicking Manage in-app purchase.
00:15From here you can click Create New to create a new purchase, and you can choose which type.
00:21For the skins, the type is non-consumable, which means they only have to buy it once.
00:27So I will select that, and then I can choose a Reference Name and a Product ID.
00:32The Reference Name will be Mole it Jetpack Skin.
00:38Product ID, I am going to paste in that I copied from the constants.h file.
00:44So then you click Add Language. I will choose English.
00:47I will call this Jetpack Skin.
00:52Display Description will be Jetpack Skin.
00:54I will click Save. For Cleared for Sale, I have Yes, and I will chose Tier 1 for
01:01the Pricing Tier. And you will need to submit a screenshot in order for the
01:05in-app purchase to be reviewed.
01:07So I will click Save, and now you will see my in-app purchase is saved here and note
01:12that it says, "Waiting for Screenshot."
01:14Now you don't have to submit a screenshot in order to do testing, but you do
01:19before it gets approved and you can put it in your app.
01:21Now let's go over to Xcode.
01:23In Xcode make sure you import store kit into your project.
01:29So you can link to that framework, again under Build Phases and Link Binary with
01:34Libraries. So you can add storekit.framework and once you've done that then
01:39you're ready to start working with in-app purchases in your game.
Collapse this transcript
Viewing Store Kit delegate methods
00:00To more easily handling in-app purchases for this game, I created a helper
00:05class called Store.
00:07In the Store class, I've imported Foundation, StoreKit, and cocos2d.
00:12You will see that it's an subclass of NSObject and implements
00:15SKProductsRequestDelegate and SKPaymentTransactionObserver, as well as
00:22SKRequestDelegate and UIAlertViewDelegate.
00:26And there are a few properties and methods.
00:28Let's go to Store.m. We will start at the top.
00:33The init method adds this object as an observer of transactions.
00:38The makepurchase method begins making the purchase, and that's done after the
00:46initial in-app purchase is created by calling the requestProductData method.
00:51The first thing in that method is that a check is made to see if the person
00:57using the device can make payments.
01:00If so, I have a CCLOG that says, "presenting store."
01:05Now, this is not going to work in a simulator, so you'll need to test this
01:08on your own device.
01:09And if it's working, you'll see "presenting store" in the output window.
01:13If the person can't make payments, I show an alert.
01:16I also run a method called showAlert, which shows a simple spinner on the screen
01:22and tells the user that we're waiting for data from Apple.
01:26I set the currentpurchase property, create the ProductsRequest, set the
01:31delegate, and start the request.
01:34Once Apple has been contacted, you get a call back in the ProductsRequest,
01:38didReceiveResponse method.
01:40You can get a lot of information about the products in this method.
01:45First you have an array in response.products.
01:48You can grab the first object in the array or all of them and get information in
01:54the way that's presented here.
01:55So you can get things like the price, you can get the description of
02:00the product, and all other things that you can find in the
02:03documentation for storeKit.
02:05Then I run self makepurchase.
02:08When a transaction gets updated, you get the notification called paymentQueue
02:11updatedTransactions.
02:14Here you can loop through the transactions and use a switch case statement to
02:18check which transaction occurred.
02:20So you can see that if the object was purchased, the transaction failed, or the
02:25transaction state was restored.
02:27So for complete transaction, hide the alert, record the transaction and run a method
02:33called provideContent based on the identifier for the product.
02:37And then I run the finishTransaction method on the SKPaymentQueue.
02:42restoreTransaction enables you to restore a transaction that happened earlier.
02:47failedTransaction happens when a transaction fails, so you can tell the user
02:51that the payment did not go through.
02:53recordTransaction enables you to record any information you'd like about a transaction.
02:59And in provideContent, I confirm that the object was purchased with UserDefaults,
03:04so we save the value to the device. And I check to see if the purchase was the
03:09IAP_SKIN, and if so, I setCurrentSkin to SKIN_JETPACK.
03:15IAP SKIN is a constant that holds the string of the productID.
03:21When the alertView clicks a button, then I run self makepurchase.
03:25I have hideAlert that hides the main alert spinner,
03:30showAlert that show the main alert spinner. And that's it.
03:35So again, if you don't have access to the exercise files, just create a class
03:38called Store and copy down these methods as they're written here, and you'll be
03:43up to speed to implementing in- app purchases in your own game.
Collapse this transcript
Implementing IAPs in your game
00:00To implement in-app purchases, we'll start in the AppDelegate class.
00:04In AppDelegate.h, import Store.h. Now we'll create a property for store.
00:13We'll just call it store, with a lowercase s, and then we'll create a method in
00:17here, and we'll name that method buySkin.
00:22Let's go to AppDelegate.m at the very bottom of the code, right above dealloc.
00:29Let's define buySkin.
00:31And here I'm simply going to make a call to the store to request product data.
00:38And now we'll initiate the in-app purchase.
00:41Now let's initialize the store inside of applicationDidFinishLaunching.
00:46Right under where I set currentSkin, I'll initialize store by typing store =,
00:53and in double brackets, Store alloc init.
00:59Now since we allocated memory for the store, we should release it in the dealloc method.
01:05It's right below window release.
01:07We'll do the same thing for store. Lowercase s, release.
01:12Then we'll go to Mainmenu.m, scroll down to the jSkin method where we set the
01:19JETPACK skin, and first we'll check to see if the user bought the skin.
01:24So if, in double brackets, NSUserDefaults, standardUserDefaults, in the outer
01:32brackets, boolForKey, and the key is going to the IAP_SKIN.
01:38Then we'll cut and paste delegate setCurrentSkin:SKIN_JETPACK, and then an
01:46else statement, and we'll make a call to delegate to buy the skin, and that's
01:53all there is to it.
01:54So we can test this in the simulator, and while you won't be able to make the
01:57in-app purchase in the simulator, you can see what happens if in-app purchases
02:02are disabled on the device.
02:04So let's click SKINS, click on the alien, and then you see a message that says
02:11"In-app Purchases Disabled."
02:12So you can see what happens when in- app purchases are disabled on a device.
02:18Again, in order to test this, you're going to need to install this application
02:23on your device from Xcode.
02:25You'll also need to set up a test user account through iTunes Connect, and you
02:31can use that account information when testing the in-app purchase.
02:34So once you have your store helper class set up, all you need to do is make a
02:39call to its requestProductData method and you can initiate an in-app purchase.
Collapse this transcript
7. Adding a Game Center Leaderboard
Setting up leaderboards in iTunes Connect
00:00Adding Game Center features can increase engagement of the users of your game,
00:07as well as improve the amount of gameplay available.
00:10So let's take a look at how to add Game Center leaderboards into your game.
00:15In iTunes Connect, go to your game, and click Manage Game Center.
00:20Here you can choose to enable Game Center, and then you can choose to set up a leaderboard.
00:26If you're unfamiliar with the leaderboard, a leaderboard is a ranking of scores.
00:31So each person that plays the game when connected to Game Center
00:34submits their high score to this leaderboard, and you can see where you rank
00:39among other players in the world.
00:41So let's quick Add Leaderboard to create a leaderboard.
00:44I'm going to choose Single Leaderboard.
00:47And then here I have a Reference Name, so I'll call this Mole It High Scores.
00:52The leaderboard ID is going to be pasted in from my code, which is the same as
00:58my high score key, which is com.wedgekasegames.moleit.highscore.
01:03Score Format Type is going to be Integer, and Sort Order is going to be High to Low.
01:08And if you want information about that, you can hover over the question mark;
01:11it explains which scores get displayed first.
01:15So we want high scores at the top of the leaderboard.
01:19Now I'm going to click Add Language, and I'll choose to add English.
01:23I'll call this High Scores--this is what the user will see when they look at the high scores.
01:29For Score Format, I'm going to choose Integer, and here you can add a suffix,
01:34like pt for point or pts for the plural point.
01:38That's actually optional.
01:40You can also add an optional image.
01:42I'm going to skip those right now, and I'm going to click Save.
01:45So now I'll click save one more time to save the leaderboard, and that's all you
01:50need to do in iTunes Connect.
01:52So I'll minimize Safari and go into Xcode.
01:56Now what you do is import the Game Kit Framework into your game.
02:01Just like any other framework, you will have to click on your project, go to
02:04Build Phases, and click on Link Binary with Libraries and click the plus button
02:11to add the Game Kit framework.
02:13So once you've set up your leaderboard in iTunes Connect and you've added
02:17the frameworks into your project, you're ready to start using Game Center in
02:20your games.
Collapse this transcript
Viewing Game Kit delegate methods
00:00To make using Game Center features easier, I created a helper class called GKWizard.
00:06In GKWizard.h you'll see that I imported the GameKit framework, and then I have
00:11some simple properties and methods.
00:13In GKWizard.m, you'll notice that I imported cocos2d.h and Constants.h. I then
00:20set the highScore property based on UserDefaults value.
00:23Then I run a method called authenticateLocalPLayer.
00:27That logs the pLayer into Game Center.
00:29Let's scroll down to that method first.
00:33The first thing we do is check to see if Game Center is available.
00:36We check to see that by checking the value returned from isGameCenterAvailable.
00:42That method checks to see if the user has the frameworks and the current
00:47operating system installed on their device.
00:50Moving on, in authenticateLocalPLayer, if the pLayer doesn't have Game Center,
00:54they see an alert message; and if they do have Game Center, they get logged in,
00:59and then isLoggedinToGC set to YES.
01:02I have a method to return the highScore.
01:05And then to report a score to a leaderboard, simply run
01:08reportScore forLeaderboard.
01:11Here you just pass in a score and the string with the leaderboard ID, which
01:16is the same ID that the leaderboard has in iTunes Connect.
01:20Here we return if Game Center is not available.
01:24Then create a score object called scoreReporter, initing with the
01:28Leaderboard category. Set the value.
01:32If the saved value of the score is less than the score passed in, and then run
01:37reportScoreWithCompletionHandler.
01:40Here we can handle the error if there is an error reporting the score.
01:44So to add Game Center support, you need to log the player into Game Center,
01:48and if you want to report a score to a leaderboard, then you do it using a
01:51GKScore object.
Collapse this transcript
Implementing a Game Center leaderboard
00:00Now we'll look at implementing the Game Center features into our game.
00:04In AppDelegate.h you'll see that I've imported GKWizard.h and created a property
00:10that's of GKWizard type called wiz.
00:13I've also adopted the GKLeaderboardViewControllerDelegate protocol.
00:17This is what we'll use to present the leaderboard to the players if they ever
00:21want to see it from the Main menu.
00:23You'll also notice that I added a method called ShowLeaderboard.
00:27Now let's go to AppDelegate.m. In application didfinishLaunching, I initialized
00:34the GKWizard object, and you'll see at the bottom of the code that I released it.
00:42And then in the finishedWithScore method if the user got a high score, I called the
00:49GK Wizard's reportScore forLeaderboard method and passed in the score and the
00:55HighScoreKey for the leaderboard.
00:57Remember, that's the constant that is the same as the user default stored value
01:02and the ID for the leaderboard in iTunes Connect.
01:06Let's scroll down to the bottom of the code and look at how to show a leaderboard.
01:11In the ShowLeaderboard method type GKLeaderboardViewController--we'll call this
01:17lb--and in triple brackets, the innermost bracket will say
01:23GKLeaderboardViewController alloc.
01:26The next brackets out will say init, and the third set of brackets is autorelease.
01:31On the next line we'll set its delegate by calling lb.leaderboardDelegate.
01:37I'll set it equal to self.
01:39Finally, we'll present the LeaderboardViewController by calling viewController--
01:44that's our main viewController-- presentModalViewControllerAnimated.
01:48The ModalViewController will be lb, Animated will be YES.
01:53So with self as the delegate of the leaderboard, once the user sees the
01:58leaderboard and clicks the Done button, then the delegate method
02:01leaderboardViewControllerDidFinish will run. And in that method we tell our
02:05viewController to dismiss the leaderboardViewController.
02:09Now we just have to go to the Main menu and when the user clicks the Game Center
02:13button, we want the leaderboard to show.
02:16So we go to Mainmenu.m, find the showLeaderboard method, and in that method, call
02:22delegate showLeaderboard.
02:26Remember, showLeaderboard is connected to the Game Center button on the Main
02:29menu. So let's test the app in the simulator.
02:33Remember, to test Game Center features, you're going to need a Game
02:36Center sandbox account.
02:38The easiest way to create your sandbox account is to go to the Game Center app
02:43on your phone, log out of Game Center if you're already logged in, and then
02:47relaunch your main app.
02:50So you'll see that I'm already logged in to Game Center, but if you're not logged
02:54in to the Game Center sandbox, you might be asked to create a new account or to
02:58log in using an existing account.
03:00The sandbox account is just for development and testing.
03:04It's a whole different set of scores than what people see when they actually buy the game.
03:09So in here I can click Game Center and I can see the leaderboard.
03:13Right now, there aren't any scores.
03:15You'll notice the High Scores text field at the top is saying the name of the leaderboard.
03:20I'll just have to rotate the hardware.
03:23Now what I want to do is beat my high score of 2, which shouldn't be too hard,
03:29and see that that score gets submitted to the leaderboard.
03:32So I'll play, and what I'm looking for is to get a high score of 3, and I'm going
03:38to lose. After the game is over, I should be able to go to the main menu,
03:46click on Game Center, and see that my score is updated on the leaderboard.
03:51So with Game Center functionality, you can increase the engagement of users by
03:55having them compete with other pLayers worldwide--and to implement it in your
04:00own games, simply used the GKWizard helper class.
Collapse this transcript
8. Going Forward and Getting Help
Using the cocos2d forums
00:00The best place to go for information about cocos2d is the source;
00:05that's cocos2d-iphone.org. On the main web site, you can go to Documentation
00:12and read what's official as to what works the best in how to optimize your
00:17games and from the documentation,
00:19you can get the official standpoint on what works the best in cocos2d.
00:23So you can learn how to improve the performance of your games, whether it
00:27be graphics or audio or any other features that your game has.
00:32Also from the main web site, you can access the forums.
00:36The forums are a great place to find any information to answer questions you may have.
00:41Most of the time, if you do a web search for problem with cocos2d, you will be
00:45brought straight into these forums,
00:47so I highly recommend looking at them and checking them first whenever you
00:50run into a problem.
00:52If you make a good amount of money on the game from cocos2d, you might want to
00:57donate to help the cause.
00:57cocos2d is developed by one main developer, and he puts a lot of its time into
01:04building this awesome platform for developing iOS games.
01:08So you can show your appreciation by that.
01:10Keep in mind it's not required, but it's just something that you could always do to help out.
01:14cocos2d-iPhone.org is the best and fastest way to get information about cocos2d.
Collapse this transcript
Exploring additional iOS game development resources
00:00If you're interested in learning a lot more about iOS game development using
00:05cocos2d, or game development in general, here are a few resources that you can use.
00:09One book that I have is call Learn iPhone and iPad cocos2d Game Development.
00:14This book assumes that you're a programmer and quickly explains the basics of
00:18cocos2d and how to optimize your code.
00:21It comes from the perspective of an iOS application developer,
00:26so I thought that book was very useful in creating apps.
00:29Next are something called LevelSVG.
00:31LevelSVG is a game that you can download for free in the App Store that has
00:37several different mini-games.
00:39It's created by the creator of cocos2d, and by purchasing it online, you actually
00:44get access to all of the source code.
00:46It's a great way to get a quick introduction to how cocos2d works with physics
00:52and how to make complex games like platform games and games that use multiple
00:57physics objects together, like cars, and it's a clean way to see how cocos2d code
01:03should be organized and optimized.
01:07If you're interested in using other development tools, you look at the Corona
01:11SDK, which you can use to create cross-platform applications.
01:15So you can create one app that runs on Android, iOS, and Windows 7.
01:23Another cross-platform development tool that works well with 3D games is called Unity 3D.
01:30This is an integrated development environment that allows you to use
01:34JavaScript to create games.
01:36Since it has a visual interface, it's easy to lay out elements on the screen.
01:41So those are resources that you can use if you want to build up your power with
01:46cocos2d or explore other options for creating iOS games.
Collapse this transcript
Conclusion
Goodbye
00:00Well, that's it for this course.
00:02I hope you had a good time learning about how to make iOS games using cocos2d.
00:06You were able to see how you can create a game using the basic cocos2d elements
00:11like CCScenes, CCLayers, CCSprites.
00:16You saw the intricacies of handling double-taps, single-taps, and simultaneous
00:22taps on the screen. And you saw how to implement extra features into your game
00:27like in-app purchases, iAds, and Game Center features.
00:31I hope you had a good time and that you end up making quality games using the
00:35material you learned in this course.
00:37If you do, let me know by sending me a link on Twitter at asktodd.
00:41I'll see you next time.
Collapse this transcript


Suggested courses to watch next:

Objective-C Essential Training (6h 35m)
Simon Allardice

iPhone SDK Essential Training (2009) (6h 52m)
Simon Allardice



Are you sure you want to delete this bookmark?

cancel

Bookmark this Tutorial

Name

Description

{0} characters left

Tags

Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading
cancel

bookmark this course

{0} characters left Separate tags with a space. Use quotes around multi-word tags. Suggested Tags:
loading

Error:

go to playlists »

Create new playlist

name:
description:
save cancel

You must be a lynda.com member to watch this video.

Every course in the lynda.com library contains free videos that let you assess the quality of our tutorials before you subscribe—just click on the blue links to watch them. Become a member to access all 104,141 instructional videos.

get started learn more

If you are already an active lynda.com member, please log in to access the lynda.com library.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Get access to all lynda.com videos

You are currently signed into your admin account, which doesn't let you view lynda.com videos. For full access to the lynda.com library, log in through iplogin.lynda.com, or sign in through your organization's portal. You may also request a user account by calling 1 1 (888) 335-9632 or emailing us at cs@lynda.com.

Access to lynda.com videos

Your organization has a limited access membership to the lynda.com library that allows access to only a specific, limited selection of courses.

You don't have access to this video.

You're logged in as an account administrator, but your membership is not active.

Contact a Training Solutions Advisor at 1 (888) 335-9632.

How to access this video.

If this course is one of your five classes, then your class currently isn't in session.

If you want to watch this video and it is not part of your class, upgrade your membership for unlimited access to the full library of 2,025 courses anytime, anywhere.

learn more upgrade

You can always watch the free content included in every course.

Questions? Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com.

You don't have access to this video.

You're logged in as an account administrator, but your membership is no longer active. You can still access reports and account information.

To reactivate your account, contact a Training Solutions Advisor at 1 1 (888) 335-9632.

Need help accessing this video?

You can't access this video from your master administrator account.

Call Customer Service at 1 1 (888) 335-9632 or email cs@lynda.com for help accessing this video.

preview image of new course page

Try our new course pages

Explore our redesigned course pages, and tell us about your experience.

If you want to switch back to the old view, change your site preferences from the my account menu.

Try the new pages No, thanks

site feedback

Thanks for signing up.

We’ll send you a confirmation email shortly.


By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

Keep up with news, tips, and latest courses with emails from lynda.com.

By signing up, you’ll receive about four emails per month, including

We’ll only use your email address to send you these mailings.

Here’s our privacy policy with more details about how we handle your information.

   
submit Lightbox submit clicked