navigate site menu

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

Building and Monetizing Game Apps for Android

Building and Monetizing Game Apps for Android

with Todd Perkins

 


Discover how to build an Android game and distribute it in the Google Play app store, using Cocos2d-x and the Eclipse Platform. Plus, author Todd Perkins shows how to monetize your game further with income from Google Mobile ads. The course demonstrates how to install and set up your coding environment; build the game's core scenes, layers, and sprites; handle touch and accelerometer data; create classes based on a detailed game flow chart; and manage misses, wins, and scores. Last, you'll prepare your game to support Google ads and in-app purchases.
Topics include:
  • Installing and downloading Cocos2d-x
  • Positioning sprites and adjusting their properties
  • Creating simple frame animations
  • Designing for multiple screen sizes
  • Adding buttons
  • Incorporating audio
  • Creating the core classes and constants
  • Adding the game layers and background
  • Displaying challenges at timed intervals
  • Displaying the player's score
  • Enabling a pause feature
  • Enabling ads and in-game purchases for Google Play and the Amazon Appstore for Android

show more

author
Todd Perkins
subject
Developer, Mobile Apps, Games
software
Android , Cocos2d
level
Intermediate
duration
2h 55m
released
Mar 22, 2013

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:00(music playing)
00:03Hi! I am Todd Perkins.
00:06Welcome to Building and Monetizing Games Apps for Android.
00:11Throughout this course you'll see how you can build an Android Game from scratch.
00:16We'll start the course by discussing how to install and setup Eclipse to use Cocos2d-X.
00:22Then we'll cover how Cocos2d-x works to create individual game elements, so you
00:29can become familiar with the gaming engine.
00:31Then we will create the Game classes, then we will have an overview of some
00:36prewritten code, and write all of the game played code from scratch.
00:41We'll look at how to monetize your game by adding things like Ads, and In-App Purchases.
00:47And finally, will discuss where you can go after this course to better improve
00:52your game development skills.
00:54Now we can move forward with Building and Monetizing Game Apps for Android.
Collapse this transcript
Using the exercise files
00:00If you have access to the Exercise Files for this course, you can use the same
00:04files that I used when developing the course.
00:07In the Exercise Files folder you will see a folder called assets, which contains
00:11all the assets used throughout the course, and then folders broken up into
00:15Chapters that correspond to the table of contents for the course.
00:19Some Chapters don't have any Exercise Files. You'll see that when you see a
00:24plain text file named, there are no Exercise Files for this chapter.
00:28Most chapters are broken up into folders. Each folder is connected to a movie
00:33and has a start and a final state, that way you can see the starting code and
00:38the finish code to check it against your own.
00:40The start and final folders have subfolders called the Classes.
00:44You can use these Classes to override the Classes in Eclipse.
00:48Finally, some chapters, like Chapter 5, do not make any modifications to
00:54the Exercise Files.
00:55For those chapters I included all of the files that I modified, and you can just
01:00drop them in with the project, as I'll show you in those movies.
01:03Let's look at how to use the assets and Classes folders.
01:07I'm going to open up Eclipse.
01:09To import the assets into Eclipse, select all the files in the assets folder, and
01:14click and drag them into the assets folder in Eclipse.
01:18Note that you can also copy these files into the assets folder in your project
01:22files on your hard drive as well.
01:24You will then be then asked if you want to copy your link to files.
01:28Choose Copy and click OK and then hit Yes To All to override all the files in there.
01:33Those files will then be imported into your project.
01:35I'll just hit Cancel.
01:37For the Classes you can do the same thing.
01:39So for Chapter 4 for example, you grab all the Classes in there, select them
01:45All, drag them right on to Classes. Then I'll be asked if I want to Copy or Link to files.
01:51Again choose Copy, hit Yes To All to override all the files.
01:54Just make sure to backup your files before doing that.
01:58The Classes folder can be found inside of your Android project folder.
02:01Also remember that when you import new classes, you'll need to update the
02:05android.mk file. That can be found in the Jni folder in your project.
02:10This folder needs references to all of the classes that you use in your project.
02:14So don't forget to add those as you go through the course.
02:17If you don't have access to the Exercise Files, don't worry, you could
02:20still follow along.
02:21Throughout the course, I'll show you what files you need and you can setup the
02:26assets in the same way to create your own game.
02:29Knowing how these Exercise Files are setup will help save a lot of time when
02:33developing the app throughout this course.
Collapse this transcript
What you should know before starting this course
00:00Due to the advanced nature of this course, you should come in already knowing a few things.
00:06You should have experience with the C ++ Language, because that's what we are
00:10going to be using; and you should have experience with Java and the Android
00:14platform in general.
00:15Of course, any other program experience will help, but it's not necessary.
00:20Remember, the more prepared you are for this course, the more you'll get out
00:24of it.
Collapse this transcript
Viewing the finished game
00:00Here's the finished game on a device.
00:03At the title screen you'll notice a Play button and you'll see there is a High
00:07Score area at the top left.
00:09If you play the game, you can tap on the moles and they play a little animation
00:15when they come up, and you tap them, and when they go down.
00:19Notice the score at the top left of the screen goes up as you are playing the game.
00:25If you miss a mole, you'll see that the carrot disappears.
00:28Once all the carrots disappear, you get a game over where you can choose to
00:31REPLAY the GAME, or to start from the beginning, go to the MAIN Menu.
00:35If you go to the MAIN Menu you will see that your HIGH score is saved, this
00:39value is saved to the device's memory and will be retained if you leave the
00:43device and come back later.
00:45You can pause the game as well using the Pause button, and Exit to the Main
00:49Menu from the Paused screen.
00:51Throughout this course we will look at how to build all of these elements to
00:54make the basic game play, and we will also look at how to monetize the game
00:58using Ads and In App Purchases.
Collapse this transcript
1. Installing Cocos2d-x
Understanding and downloading Cocos2d-x
00:00The Game Engine I have chosen to do Android Games is called Cocos2d-X.
00:06Cocos2d-X is a Cross- Platform version of Cocos2d iPhone.
00:11You can use the same code base for your iOS app, your Android app, a Windows
00:17app, and a MacOS app.
00:19Cocos2d-X uses the same method calls as Cocos2d, so it's basically, exactly the
00:25same, except it's written in C++.
00:27As such, you'll need to make some changes to Eclipse to support C++ and you'll
00:33need to some other things to allow Android to support C++.
00:37So to download and install Cocos2d-X, go to cocos2d-X.org and then click on the Download link.
00:47The version of Cocos2d-X that I'm using for this course is 2.0.1. Likely when
00:53you're watching this course, there will be a newer version of Cocos2d, but I
00:57highly recommend using this version for this course.
01:02All the code is not guaranteed to work if you're using a later version of
01:06Cocos2d, because things may be deprecated and you just open yourself up to
01:10problems in that way.
01:11To find older versions of Cocos2d, just look at the link at the bottom of my
01:15screen this says More historical versions.
01:18You can search then by the date; the date that 2.0.1 was released was in June 2012.
01:25If you choose to use a different version of Cocos2d, just know that you'll need
01:30to find your own solutions if you run into any problems, because it's likely
01:34that some steps along the way will be different from mine.
01:37So, you'll need to look up differences in your version of Cocos2d.
01:42For that reason I highly recommend using 2.0.1.
01:48Once you've made your own game using Cocos2d-X, you might feel more comfortable
01:53using a newer version and solving those problems on your own.
01:56So when you click to download that you'll see that it shows up in a folder on your computer.
02:02Now I've just copied all the files into my Android folder, which is inside of
02:07my documents folder.
02:08So now that we have downloaded Cocos2d-X, we're ready to start creating
02:13a Cocos2d-X project.
Collapse this transcript
Downloading the Android NDK
00:00Using C++ and Android requires something called the Android NDK, which stands for
00:07Native Development Kit.
00:08So here you'll find the downloads of the NDK, so you can click the appropriate
00:13download for your platform.
00:15Note that you can get the old version of NDK by right clicking the link for the
00:20current version of the NDK and copying and pasting that link into your browser
00:26window, and changing the version number to like. So if it's r8b or e, change it
00:33to r8b in the link and that should take you to the appropriate file.
00:37If you're working with a future version of the NDK, some features that are shown
00:42in this course might not be supported.
00:44So now let's go the System and Software Requirements Section of this document.
00:48I'm just going to click link, near the top of the page.
00:51Now most of this is pretty straightforward. Yyou're going to need the Android
00:55SDK already installed.
00:57I'm not going to cover that in this course, because it's been covered
01:00extensively in multiple other Online Training Library courses.
01:03And you'll need the Requirement Development Tools on Windows;
01:07you'll need Cygwin version 1.7; so you can click this link, and go over to
01:15Cygwin.com and download it and install it there.
01:18So this will enable you to run the Shell commands that you'll need to create
01:23your Android cocos2d-x project.
01:25So once you've got the Android NDK downloaded and downloaded and installed
01:30Cigwin if you're on Windows, just confirm that it's in the appropriate place.
01:35Mine is in my Android folder, which is in my Documents directory, so I've that
01:38Android NDK, r8b folder right here. And it has all the necessary files inside of it.
01:45So now we have NDK setup and ready to use.
Collapse this transcript
Creating a Cocos2d-x project template for Eclipse
00:01Unfortunately creating a Cocos2d-X project for Android is not as easy as just
00:06going to File>New Cocos2d-X project.
00:09You actually need to create the project in your file system, and then import the
00:13project into Eclipse.
00:15And by the way, if you're missing Eclipse or the Android SDK inside of Eclipse,
00:21you'll need to make sure to download and install those based on the instructions
00:25in the Android Essential Training Course.
00:27So to do that, start with the cocos2d-x folder, and that's where I have cocos2d-x
00:34installed on my hard drive.
00:36And there are two files in there, create-android-project.bat and
00:39create-android-project.sh. Bat is what you're going to use on Windows and sh is
00:44what you are going to use on Mac.
00:46I'll show the Mac version first, and then we'll look at the Windows version
00:50in just a few seconds.
00:51So I'm going to open this file with TextEdit, and I'll right-click it to open up
00:55that menu. And then I'm going to need to change these two variables
00:58NDK_ROOT_LOCAL and ANDROID_SDK_ROOT_LOCAL.
01:00I'm changing NDK_ROOT_LOCAL to /User/ ldc/Documents/android/android-ndk-r8b.
01:03Now I am going to make the change to Android_SDK_Root_Local change it to
01:18/User/ldc/Documents/android/android- sdk-macosx. I can just check that path
01:30against what's in my Documents folder, android-sdk-macosx, and then I can save
01:36this file and close it.
01:38Now let's go back to that cccos2d-x folder and open up
01:42create-android-project.bat if you're on Windows. And I'm going to right click
01:47and open it with Other and I'm going to choose TextEdit.
01:51Now in here you're going to do the same thing that you did on the Mac side of
01:55things, and just modify the appropriate files, so there are three variables here
01:59though, instead of two.
02:00So if you look in this section here, you're going to need to tell the path to
02:04the bin folder inside of the Cygwin folder where you installed Cygwin. And then
02:09you're going to need to set the path that where you installed the Android SDK
02:13and the tools folder inside of it, and then set the NDKROOT.
02:17So this is where you installed the Android NDK.
02:20If you're on Windows, you can just double click this bat file here.
02:23If you're on a Mac you'll need to open up a Terminal window, change the
02:27directory to this directory and run the Shell script.
02:30So let's open up Terminal now. I'm going to press Command+Space and open up
02:34Terminal, and in Terminal I'm going to change the directory to my cocos2d-x
02:38directory. So I'm going to type cd space, and then I'm just going to drag in the
02:44cocos2d-x folder, and press Return to change the directory.
02:48And now I'm going to run that script, so it's ./create-android-project.sh, and
02:58you can see that I am just running this file right here, and then if I press
03:02Enter, it's going to ask me a few questions, so Input the package path.
03:06And this is your reverse domain structure.
03:08So I'm going to type com.
03:10You can type your domain name here, I'm going to type toddperkins.moleitx, and
03:16then you should see a list of supported Android versions.
03:19So it's going to ask you to input an id, so there's 1 which is Android-10, which
03:25is Android 2.3.3. And you may get a few more depending on how many versions of
03:31Android you have installed with SDK.
03:33So I'm just going to type in 1, and then press Enter, because that applies to Android-10.
03:39Now that might not be the same number that you need to type in, so you might
03:43need to look at your list of Android SDKs and find Android-10, it might be 2
03:49or 3 or 4, but just make sure that the number that type in is associated with Android-10.
03:55And then I need to create a project name and I'm going to call this moleitx, I'm
03:59going to press Enter. And if everything worked okay, then you're going to see a
04:04Created file Created directory.
04:05If something goes wrong, you are going to see messages like file does not exist.
04:09So if that happens, just make sure that you follow all these steps correctly.
04:13Now what I want to do is look inside the cocos2d-x folder, and I should see a moleitx folder.
04:19Now the way that these folders get created is inside of your cocos2d-x
04:25installation folder.
04:26So if you're following the tutorials in this course, I'm going to show how to do
04:30it assuming you're creating all the files using this default way.
04:35So if you look in the moleitx folder, you'll see all the Classes, so the basic
04:38HelloWorld classes, and the project. android folder and the Resources folder.
04:44So we successfully created this project template and we're one step away from
04:48being able to import it into Eclipse.
Collapse this transcript
Finishing the project template
00:00The last step in creating our project template is to go into the moleitx folder
00:05that we created, go into project.android or proj.andriod. We're going to run the
00:12build_native script.
00:14Now to run this script, you're going to need to use Cygwin on Windows or
00:18Terminal on the Mac.
00:20So open up the appropriate app and in Terminal, I'm going to change the directory.
00:24You're going to need to do the exact same thing in Cygwin.
00:27So I would use the cd command and a space and change the directory to the
00:31appropriate directory; and then once you're in the appropriate directory, you're
00:34going to run that build_native script.
00:36To do that type ./build_native.sh. Now this should take a minute or two and it
00:44will just run through creating all the appropriate files, and once that's done,
00:48you'll be able to import this project into Eclipse and run a cocos2d-x project.
00:56So the script is complete and everything is setup as far as the file system is
00:59concerned, and this project is ready to be imported in Eclipse.
Collapse this transcript
Preparing Eclipse to use C++
00:00Since Cocos2d-X uses C++;
00:03we will need to add that to Eclipse.
00:06My version of Eclipse is actually Eclipse Classic and did not come with C++
00:10functionality out-of-the-box.
00:12However, I did add it and I'll show you how that works.
00:15I am going to go to Help>Install New Software, and then in the drop-down menu at
00:19top, choose the appropriate version for your Eclipse Release, mine is juno. And
00:24you can wait for a minute for this area here in the middle of the screen to
00:28populate and this process is probably actually very familiar to you if you have
00:31installed the Android Platform. And then scroll down to Programming Languages.
00:36So what I done here is I've checked all of these ones that are grayed out,
00:41except for auto tool support for CDT.
00:43So don't check that one, but check the rest of the ones that are grayed out,
00:47and then install them.
00:49And then you can click next, and make sure you read the agreement and agree to
00:53it before you click to Install and then you can have all the C++ libraries that
00:58you need to create your Cocos2d app for Andriod.
01:02Once you have C++ connected to Eclipse, you are ready to bring in your Android
01:07project and start building your games.
Collapse this transcript
Importing the project into Eclipse
00:00We're going to import the project into Eclipse as an existing Android project.
00:05So we go to File>New and choose Other, and under Android, choose Android Project
00:11from Existing Code and click Next.
00:13For the Root Directory hit Browse, and then we are going to find the
00:17project.androiddirectory.
00:18So open up that Cocos2d-X folder where you created the moleitx folder and
00:23in there just double-click on project.android and click Open, and then click Finish.
00:27So, now we have created the project.
00:29The next step is to convert it into a hibrid C++ project, so right-click, and
00:35choose New> Convert to a C/C ++ Project (Add C/C++ Nature).
00:42You can also go to File>New and do the same thing, or you can go to Other and
00:48then choose that option.
00:50Okay, so I am choosing Convert to C/C++ project, and I have a project checked
00:55here, we got C++ here.
00:58And then I'm going to get a Makefile project on the left side and choose
01:02Other Toolchain on the right side and click Finish.
01:05Now we have made this a hybrid project and we have to modify a few of the settings.
01:10So, I am going to right-click my project, and I'm going to choose Properties.
01:14The first place I am going to ago is under C/C++ Build. I'm going to uncheck Use
01:20Default Build Command, and I'm going to type bash space ${workspace_loc:/} name
01:32of my project which is com.toddperkins.moleitx.moleitx}/ and then
01:45build_native.sh space NDK_DEBUG goes - 1 and a space V=1, hit Apply.
01:58Next I am going to go to Code Analysis, under C/C++ General;
02:02I am going to choose Use project settings.
02:04And I'm going to actually hide all of these errors and warnings, because
02:08Eclipse tends to give you inaccurate errors and warnings that stop your app from running.
02:14And so we are just going to let log cat handle all of our errors and warnings
02:18and not worry about what Eclipse has to say about them.
02:21Click Apply and then hit on over to Path and Symbols. In the Includes section,
02:26hit Add and we are going to include two sets of files, we're going to go to where all
02:31my android files are stored.
02:33And in the android-ndk, under platforms, android-9 arch-arm user include, I am
02:42going click Open, hit OK and we are also going to include the Cocoas2d files.
02:48So, we'll hit Add again, then File system, and then android, under
02:52cocos2d_x, I'm going to go to cocos2d_x and find the Include folder, choose
02:59that one and hit Open, hit OK.
03:01And next we'll go to Source Location, that's the tab inside of Paths and Symbols.
03:06We are going to hit Link Folder.
03:08I am going to link to the Classes folder.
03:10So, check the boxes that says Link to folder and File system, and hit Browse,
03:14and go to your Projects Classes folder.
03:16So, I am going to open up moleitx and just double-click the classes folder and
03:21click Open, hit OK and then Apply.
03:24And it says I need to rebuild my projects, so I am going to hit Yes, hit OK.
03:29And at this point your app should actually run on a device, there are a few extra
03:35changes you'll have to make to run it in the simulator.
03:37But we'll take a look at that in another movie.
03:40So, at this point, if you can test this app on a device and get the HelloWorld
03:44Cocoas2d app launching, then you're in business.
Collapse this transcript
Adding GLES 2.0 support to your emulator
00:00There are three things that you need to do in order to get your app running in
00:04the Android Emulator.
00:06This all stems because Cocos2d uses OpenGl ES 2.0 and that's not supported by
00:13default in the Android Emulator.
00:15So step one is to tell the Emulator to support it, step two is to tell the
00:20Manifest that your application requires it, and step three is to add something
00:26to your code to resolve a potential bug.
00:29So, first let's open up the Android Virtual Device Manager.
00:33I am going to select my 4.1 device and click Edit.
00:36And here you can see I have a Hardware feature called GPU emulation; you can add
00:41that by clicking New. Make sure you set the value to yes, and then edit your
00:45current AVD, or create a new one.
00:48I am going to Cancel out of these menus, and then I'm going to open up
00:51AndroidManifest.xml.
00:52In here in the Manifest Extra section, I am going to click Add, and then choose
00:57Uses Features and click OK.
00:59Now I need to say that I require OpenGl ES Version 2.0.
01:03Here I'm going to write the hexadecimal value in GL es version field.
01:07At 0X00020000, for Required choose true, Save the file, and close it.
01:17Then open up moleitx.java, you'll find that inside the source folder. Scroll
01:23down to the detect OpenGl ES 2.0 method.
01:26This method is bugged, because sometimes info.req.GLEsVersion returns
01:32an incorrect value.
01:33So, to cover for that, we will add an or condition to this Return value, and in
01:40there we will type BUILD.FINGERPRINT. startsWith and in the parentheses () passed
01:45in the string "generic," and before I save the file, I am going to click on the
01:51error and then just double-click to Import the Build Class. And the error should
01:54go away and I'll save the file.
01:56Now before I test this in the emulator, I want to show you something.
02:00I am going to click onCreate on the right side of the screen to go to that method.
02:04And then I'm going to scroll down where it says mGLView setTextField. We can go
02:11down a few lines and I am going to paste some code that I have already written.
02:15Just check to see if BUILD.FINGERPRINT. starts with ("generic") just like we just wrote.
02:19What that does again is make sure that we are in the emulator.
02:23So, it is in the emulator, we're going to run this method.
02:27mGLViewsetEGLConfigChooser, passing in 8, 8, 8, 8, 16, 0.
02:33Now the reason why I am showing this code is because on the forums for
02:39Cocos2d-X, some people found this to work to get their apps to run in the emulator.
02:45However, when I run this code on my computer, it crashes the emulator.
02:51So, it didn't work for me, but it may work for you.
02:55So, it just depends on your case.
02:57So, I'm showing you this code in case you still have problems getting the code
03:01to run in the emulator.
03:03But I'm going to undo that change, and then click the Run button to test it
03:08out in the emulator.
03:09After awhile the app should launch in the emulator, keep in mind it might take a while.
03:14The Android Emulator is infamous for being pretty slow.
03:17So, here I have the app, it says Hello World, it's running in the Android
03:21Emulator. I have it in landscape mode, which you can do by pressing Ctrl+F11 and there it is.
03:28So, I'll just make sure that if you want to test this in Emulator, you have to
03:32account for the Cocos2d debug that gives you inaccurate information about the
03:36OpenGl ES Version, declare it in your Manifest and set your Emulator to
03:42support GPU emulation.
Collapse this transcript
Fixing additional compiler issues
00:00It is possible that after you've done all of these steps that you still can't
00:05run your Android application.
00:08If you're having problems, here are two more things to try.
00:11You can go in the Project Properties menu, click on Java Compiler, and then you
00:16can Enable project specific settings and make sure that your Compiler compliance
00:20level is set to 1.6.
00:23You can also go, if you're on Windows to C/C++ Build, Build Variables and click Add.
00:30If you already see one called path, then add the path to the Cygwin bin folder there.
00:39If you don't see path, click Add to add a new variable called it PATH, in all caps.
00:45You can change the Type to a Directory, click Browse, and then browse to
00:50where you installed Cygwin. And then click on the bin folder, and choose the bin folder.
00:57You'll need that to run the bash command when you compile your app.
01:01So if you are having those problems, try these solutions and they should
01:06help out.
Collapse this transcript
2. An Introduction to Cocos2d-x
Understanding scenes, layers, and sprites
00:00To create a Game with Cocos2d, you'll have to have a good understanding of how
00:04scenes, layers, and sprites work's together.
00:07You'll also need to know how to organize your projects and how to use the various
00:12tools that are built in the Cocos2d to make creating a game easier for you.
00:16Throughout this chapter we are going to explore all of those things, that way
00:20when we start creating a game you'll have an idea of all the concepts and then
00:25you'll just see how they work together to create Game.
00:27The first thing we need to look at is scenes, layers, and sprites. These objects
00:33are the fundamental building blocks of Cocos2d.
00:35Think of a scene as a state of your game. There is only one scene running at a
00:41time, and a scene is controlled by the director.
00:45The classes in Cocos2d have the prefix CC.
00:48So, for example you might have one CCScene that's the MainMenu, and you might
00:53have another CCScene that represents your Game.
00:57Again only one may be running at a time.
01:00Within a scene you have objects called Layers.
01:03A layer is a visual object that can group other visual objects.
01:09Visual Objects are called sprites.
01:12In a slide here you see the green outline around the blueMole that represents a CCSprite.
01:17In the layer, there are three different Sprites. As you move your Layer around, the
01:23moles move around as well.
01:25When you're working with a game, all of your visual elements are going to be
01:29organized in layers on the scene.
01:31You're not going to be sub-classing CCScene, but rather you'll be sub-classing
01:36CCLayer and putting all your visual elements in there and organizing them
01:41similar to organizing layers in Photoshop.
01:44So for example you may have one layer that has all of your game play, and
01:48other layer that's in front of that layer its has your heads-up display that
01:52includes things like the score, maybe a pause button, the number of lives a
01:56character has left, etc,.
01:59So, again a scene is a state of your application and only one may be running at a time.
02:04Scenes are organized into layers, which can be placed in front of or in back
02:09of each other just like Photoshop, and layers contain individual graphic
02:13elements called sprites.
Collapse this transcript
Using scenes, layers, and sprites
00:00Let's walk through our Cocos2d HelloWorld project and see how scenes, layers,
00:05and sprites, work together in co.
00:07If you don't have access to the Exercise Files, you can just use the
00:10default HelloWorld project.
00:12So, I have the AppDelegate and HelloWorldScene class files open right now.
00:17In AppDelegate I am going to scroll down to applicationDidFinishLaunching; here
00:21we have a reference to the Director.
00:23Remember, the Director controls which scene is playing and only one scene can
00:29be playing at once.
00:30The Director is a singleton instance that you can access through the
00:34SharedDirector method of the CCDirector class.
00:38Through the Director you can control whether to display the frames per second
00:42using setDisplayStats, you can control the frames per second that your
00:47application runs at using setAnimationInterval.
00:50So, here we have (1.0 / 60), which is 60 frames a second.
00:54And then here we have a reference to a Scene.
00:58The Scene is coming from the value returned from HelloWorld::scene method.
01:04Then the Director is told to runWithScene and the Scene values passed in.
01:08So, that's what starts the process of running the Cocos2d app. We use
01:14runWithScene and the scene starts.
01:16So, the scene is a static method in a HelloWorldclass.
01:20Let's go to the HelloWorldscene.cpp.
01:23In the Scene method we create a blank scene using CCScenes::create() method,
01:30than we create an instance of a HelloWorld class using its create method.
01:36Think of create method almost like new HelloWorld or new CCScene; we are creating
01:41an instance of the object.
01:42And then we use the scenes->addChild() method to add the layer to the screen.
01:46Add child works like add child works in Flash; this is how you get visual
01:52objects onto the screen.
01:54Once an object is set as a child object, if you move the parent object, the
01:59child object moves along with it.
02:01So we are putting the layer inside of the scene and then we return the scene.
02:07So again that's scene is just a generic CCScene and thing that's custom is the Layer,
02:12which is the HelloWorld Layer. It's going to store all of our visual objects.
02:16When the create() method runs, the init () method is called as well; that's
02:20part of what the create method does is it initializes the instance using its init () method.
02:26In the init () method we are running the super init through CCLayer and then we have
02:31some objects created.
02:32CCMenuItemImage, which is a button with an image file, CCMenu which organizes a
02:38set of buttons and puts them on the screen. And keep in mind these visual objects
02:43like the Menu item are subclasses of sprites.
02:46So then we use addChild to put the Menu with the button on the screen
02:52scrolling down to CCLabelTTF*, that's a TrueType font label running it's
02:58create () method passing in value of " Hello World" which is a string that will
03:02display in the text field.
03:04The font used in the font size, the CCSize holds a width and height values. We
03:10can get the width and height of the screen using the Directors getWindSize
03:14method. The position of the label is set, and the label is added to the screen
03:20by calling the Layers addChild method.
03:22The numberthat's passed in as a second parameter represents the Z positioning of the object.
03:28So a higher value means closer to the front, a lower value means closer to the back.
03:32And we have a Sprite using it's create () method and passing again the value of
03:37an image in our assets.
03:39We can create a sprite based on the image, set it's position, and again add it to
03:43the screen with is the Z-index of 0.
03:47So we have our Scene that is the state of the application, the Layer where all
03:51the visual others are organized, and the visual objects or sprites or
03:55subclasses of sprites.
Collapse this transcript
Positioning sprites
00:00Positioning a sprite is all about understanding the x, y coordinates of the
00:04screen and of the sprite itself.
00:06The x, y coordinates of a screen begin at the bottom left, and increas as they go
00:10up and right, so the origin at the bottom left here 00.
00:17And if you were to look at a screen that's 480 pixels wide by 320 pixels high,
00:21it would look like this.
00:22So, 0,320 for the top left, 480,320 for the top right, and 480,0 for the bottom right.
00:28So, let's take a sprite for example.
00:31Let's say we wanted to position sprite on the screen.
00:34A sprite actually has a centered x, y origin or anchor point.
00:39Of course this can be changed by adjusting the sprite anchor point, but the
00:43default position is in the center.
00:45So, if you don't position the sprite it will show up at the bottom left of
00:48the screen like this.
00:50You can place it in any of the corners by using the same values as the corners have.
00:55So, just remember now the x, y origin of the screen is at the bottom left and
01:00the x, y position of the sprite is based on its center.
Collapse this transcript
Adjusting basic sprite properties
00:00The main graphic elements you are going to be working with in Cocos2d are Sprites.
00:04So, it's important to take some time to understand how a sprite works.
00:08Also I have some assets imported to my project.
00:11And if you don't have access to Exercise Files, you can just use the HelloWorld
00:15files that are built in with the project.
00:17So I've made some basic changes to the HelloWorld app.
00:21The first ones are in AppDelegant.cpp, I just changed the setDisplayStats value
00:27to (false) instead of true, so we don't see the frame around the screen.
00:31And let's go to HelloWorldScene.cpp and I have deleted most of the code inside
00:37of the init () method except for the size variable; we are going to use it.
00:41Now what we are going to do is create a Sprite and place it at the center of the screen.
00:46So CCSprite is going to call this *bg for background, we are going to use that
00:52create method () create the object, and remember that we pass in the string of
00:58the file that we want to load in, and my file is called moles_bg.png. Of course
01:04if you have a different file then you type that name in there.
01:07On the next line we're going to set the position of the background,
01:10so bg->setPosition. And the value that we pass in is a point, which is in x,
01:16y-coordinate and the shortcut to create in x, y-coordinate in Cocos2d is ccp;
01:21that's all lower case.
01:23And the first value passed in is x-coordinate;
01:25the second value is the y-coordinate.
01:27Remember if we want to put this object in the center of the screen, it's going to
01:31be half the width and half the height of the screen respectively.
01:35So, we pass in (size.width,size.height ) and then remember before we can see it
01:42we need to add it as a child. Not only will you not see an object if you add it as a
01:48child, but the object will actually get removed from memory.
01:51Now the way the Cocos2d memory works is that objects that are added as children
01:56are saved and once an object is released from being a child of another object,
02:01it's automatically released from memory the next time garbage collection occurs.
02:06So keep in mind that you don't want to forget to addChild.
02:11So, this->addChild, and remember we don't just pass in the child name, we
02:17also pass in z-position.
02:18We are going to pass in -1, I want this to be behind everything else.
02:23Now keep in mind that if I put a layer behind this HelloWorld layer, just
02:27because I'm passing a value of -1 it's all relative to that layer.
02:31So a layer behind another layer sprites will not overlap. All the objects in
02:37the back layer will be behind the front layer no matter what their z-positions are.
02:41So at this point this is would put the background at the top right of the
02:45stage, because we're using size.width and size.height.
02:48So I am going to divide them by 2 and that will put the object right at the
02:53center of the stage and so we can save and test that in the Emulator.
02:56And when you test it in the Emulator it should look like this.
03:00So we just have the object right in middle of the screen.
03:03Now let's say we want to change the scale of it to fill the hole size of the
03:08screen, that's actually knows sprite property that you'd want to edit.
03:10Now what we are going to do is grab the float of the x-ratio and the y-ratio and then
03:15we're going to apply the scale in that way.
03:18Because unfortunately with Cocos2d you can't just say, set the object to this
03:22size, it doesn't work right.
03:24So we are going to need to just use a scale which is based on a percentage of
03:29the size of our objects.
03:30So, right below where we create a background, I'm going to scroll down a little
03:35bit and I'm going to create two float values, rX and rY.
03:40rX is going to be the x-ratio of the size of the screen to the size of the background.
03:46And so what we do is we take the size of the screen, size.width and we
03:52divide that by the size of the background; to get the size of the background do
03:56(background) bg->getContentSize().width.
03:59So that's our ratio horizontally, I'm just going to copy and paste this and change
04:05rX to rY, and change size. with to size.height, and then
04:11bg->getContentSize().height.
04:14Okay, so I have my ratio and now I just scale it.
04:17So what we do is on the next line we go to bg->setScaleX(rX) and then we pass
04:25in the horizontal value and the same thing Y setScaleY(rY).
04:32Right, I'll run the app in the Emulator and here it is. So this is a way that we
04:38can handle different screen sizes on Android, we can pick an art size, or two
04:43art sizes - maybe one high-resolution, one low resolution one - and scale the art
04:48depending on the size of the screen.
04:50So we can easily get it to match the screen size so the art looks pretty close
04:55to the same on devices with a variety of screen sizes.
04:59So, back to the code, there are many other methods that you look at, I recommend
05:03looking at the documentation for Cocos2d- X and just seeing what other properties
05:07that you can modify in the same way.
05:10So, far we have looked at the position of a sprite with set position, the
05:14size of a sprite with getContentSize, and scale with getScale and X scale Y.
05:18If you take way to X or the Y and those methods, you can scale the whole object uniformly.
05:24So, I recommend again looking at documentation and just seeing which properties
05:28you may want to modify as you are working with sprites.
Collapse this transcript
Handling touches
00:00The control schemes on most touchscreen games are based on touch.
00:05So obviously it's important to understand how to handle touches in your games.
00:10Let's go to HelloWorldScene.h and we will create a void method, and this is going
00:16to be called CCTouchesBegan.
00:17What we're doing is we're overriding the superclass method here.
00:23ccTouchesBegan and it's going to receive two parameters, the first one is a
00:30cocos2d ::CCSet, call this *pTouches; and the second is a cocos2d::CCEvent, call this *pEvent.
00:40And then I am just going to copy and paste this definition into the class files.
00:48So, I am going to save, go over HelloWorldScene.ccp.
00:52And here at the bottom of the init() method, I'm going to add one line of code
00:57that's going to be this-> setTouchEnabled, then pass in a value of (true).
01:03Once you set the TouchEnabled, the ccTouchesBegan event will automatically be
01:08fired off as soon as a Touch Begins.
01:10Note that there is also a ccTouches ended, moved, and canceled, which you can learn
01:16about more in the documentation.
01:18So, outside of init() method I'm going to paste the code that I copied, and right
01:22before ccTouchesBegan I am going to add HelloWorld.
01:25Now the first thing we need to do is just capture a single *touch. Since we're
01:29only worried about one touch for now,
01:33I'm going to grab any object out of the CCSet.
01:36So CCTouch, we'll call this touch, we will set it equal to typecast in ccTouch
01:43of pTouches any object.
01:46And next we're going to create a ccPoint, we'll call this Location, set it
01:51=touch->locationInView. That's going to return in x-y-coordinate, but it's not
01:58align with a Cocos2d-X Y coordinate so we are going to need to convert it to a GL location.
02:02Let's go to the next line inside Location=ccDirector sharedDirector
02:09convertToGL() and then pass in the Location.
02:14So, now we have the Location of our touch.
02:17Now what we will do to just show that it's working properly is we'll create
02:21sprite at that Location.
02:23So, each time we tab the screen we'll just drop a mole there.
02:26So, ccSprites just call it *sprite set it =ccSprite::create passing the
02:32string moles_icon.png.
02:35Of course if you don't have that file just, let's pass in the name of a file
02:40that is in your project; sprites-> setPosition and positions is going to be
02:44Location and then finally we need to add it as a child of the layer.
02:50So, this->addChild and remember we have the two parameters, the first one is the
02:56Child, Sprite, the second one is the Z-position which is 1.
03:00Keep in mind if you continue to add objects at the same z position, they don't
03:04overwrite each other; the newer ones go in front of the older ones.
03:08So let's save this and test it out in Emulator and see what we get.
03:13So, here's the app running in the emulator and of course we see that blank
03:17background with nothing on it in.
03:18And if I click on the screen I should see moles popping up where I click.
03:22So there we go our Touches are working just as they should.
03:25So remember if you want to support Touches you are going to have to set the
03:29TouchEnabled property to (true) using this-> setTouchEnabled, then you're
03:33going to have to implement the ccTouchesBegan() method or any of the other
03:37touch handling methods.
03:39You can grab the location using a TouchesLocationInView () method and
03:43converting that to a GL point by using the Director is convertToGL() method.
03:50After that you can handle the Touch information however you like.
Collapse this transcript
Accessing accelerometer data
00:00Another popular control scheme for Android devices is Accelerometer control.
00:05To add Accelerometer control to your app, go inside of your layer subclass and
00:10then implement the super class method called didAccelerate.
00:14It's going to receive an object in the cocos2d namespace and that's called
00:19CCAcceleration, and we'll name that parameter *pAccelerationValue.
00:22I'm just going to save this file, and then I'm going to copy this code and paste
00:28it right into our class.
00:30So far it's pretty close to what we've looked at before with the touches, and
00:35we're going to implement a super class method, and we're also going to
00:41setAccelerometerEnabled in init.
00:44You also notice that I have an existing Sprite that I created in header file,
00:48so I have the CCSprite here called mole and in the class file I've initialized
00:54it, and just set it to be in the middle of the screen. Below that I am going to
00:58type this->setAccelerometerEnabled. We're going to set that true and scroll
01:06down to didAccelerate.
01:08And now this pAccelerationValue parameter has the values that we need.
01:12There are two general ways that people look at acceleration in games, so let's
01:16say you have an object that you want to tilt, and it's going to move across the
01:20screen based on how much you tilt it, so once you've tiled it all the way to
01:25the left, then the object should be all the way to the left of the screen, once
01:29you tilt it all the way to right the object should be all the way to the right of the screen.
01:34So let's look at how to do that first. The first thing we need to do for that is
01:39to grab the percentage that the device has been tilted, the values in
01:42pAccelerationValue range from -1 to +1, so to get the percent, we're going to
01:46need to manipulate that a little bit.
01:47Let's first create a CCSize variable called s and we'll set that to be the size
01:52of the screen; so CCDirector, sharedDirector, and then getWinSize.
01:57Okay on the next live we'll create a float called percentsX and we're going to
02:03set it equal to, in parentheses ( pAccelerationValue->x), and we're going to add 1 to
02:12it. Remember I said it's from -1 to +1, so this will make it from 0 to 2, and
02:17after the parenthesis, we'll just divide that number by the total range which is to 2.
02:22(pAccelerationValue->x +1)/2; so we have the percent that the device is tilted
02:25here. Let's just copy and paste this line to the next line, change X to Y in each
02:31instance, and then we'll apply that to the position of the mole. So we'll go
02:35down a few lines, and then run mole-> setPosition, then we're going to pass in
02:39the ccp and that's going to be percentsX times * s.width, and then percentY
02:48times * s.height. This will put the mole, just like I was saying earlier, at the
02:53position on the screen that's directly coming from acceleration value. You tilt
02:58the device all the way to the left, the mole will be all the way to the left of
03:02the screen; tilt it all the way to right and mole will be all the way to the
03:07right of the screen, all the way front, back, and so on.
03:10Keep in mind there is also acceleration Z, if you want to grab that data for anything.
03:14At this point I would show you this app running in the Android Emulator, but
03:18acceleration is not supported in the Emulator.
03:20So if you want to test it, you actually have to test it on a device, and just
03:24make sure before you test it that you add that HelloWorld namespace to the
03:28method, just like that. So you can save and you can test that on the device and
03:33it should work just like I've stated.
03:34So, I mentioned that there's another method that the people use for
03:37accelerometer control and that is grabbing the accelatationValue and
03:41manipulating the object based on the value.
03:44So when you tilt to the left, the object will slide to the left at a speed based
03:50on the tilt of the device.
03:52A steeper tilt means faster movement, but it doesn't correspond to the exact
03:58position of the Sprite, it's actually relative to where it is currently.
04:03Think of it like a labyrinth game. You tilt the labyrinth a little bit and the
04:07ball doesn't automatically go all the way to the end of labyrinth if you tilt it
04:11all the way to the side; rather you tilt it and the ball moves at the speed
04:16relative to the angle of the labyrinth.
04:18So we're going to do that here. I'm going to comment out this line of code
04:22where we set the position of the mole, and then we're going to grab the current
04:26position of the mole and hold it in a variable.So CCPoint, I'm going to call
04:30this P, and we'll set it equal to the position of the mole, so mole->getPostion,
04:34and then we're going to go to the next line and we'll set the position of the
04:39mole. So mole->setPosition, and we're going to use a new method this I called
04:45ccpAdd capital A. And now this actually adds one point to another point, so
04:52it's an easy way to manipulate the position of an object on the screen, which is nice.
04:57So the first value is a ccPoint so I'll pass in p and then a comma and then a
05:03second value is a ccPoint as well. So for this one I'm going to type ccp and in
05:08the parenthesis I'll pass in the accelerationX value, so pAccelerationValue->x
05:14and then for the Y value I'll do the same this, pAccelerationValue->y.
05:23At this point you should be able to test it on a device and the speed at which
05:27the mole moves will depend on the tilt of your device.
05:30If it's going too slow, you can just multiply the x and y values by 10 for
05:35example, or whatever value you want, to adjust the speed.
05:39Those are the main two ways you'll handle acceleration in your games. Either you
05:43make it exactly correspond to the position of the device or you have an object
05:47move based on the tilt of your device.
05:50Remember that when you're implementing it, to implement the didAccelerate method
05:54and to setAccelerometerEnable to true, and then you can grab the accelerometer
05:59values using the pAcceleration value parameter and its x, y and z members.
Collapse this transcript
Understanding Cocos2d actions
00:01Cocos2d Actions enabled you to run commands over a period of time or in a sequence.
00:07For example, you could animate just about any property inside a Sprite.
00:12You can animate its position, rotation, scale, opacity and others.
00:17Let's look at how Actions work.
00:19At the bottom of ccTouchesBegan, I'm going to run an action on the mole, so
00:23mole->runAction, and then inside the parentheses, it's going to be CCMoveTo
00:29static method create.
00:31And here I just pass in a time and a position;
00:35now the time is in seconds, so if I want it to be 1 second, pass in a 1, and then location.
00:41So I have the mole move to wherever I click.
00:45Now let's look at that in the Emulator.
00:47And here it is, in the Emulator. You'll notice that if I click anywhere that the
00:51mole moves to that point.
00:53Let's say I wanted something to happen when I actually click on the mole; to do
00:58that I can create an if statement.
00:59What you want to check in the if statement, is to see if the bounding box of the
01:04mole contains the location that was touched.
01:06So to do that, let's type CCRect, that's the namespace, and method is
01:10CCRRectContainsPoint. And the first thing passed in is the rectangle which is
01:15the bounding box of the Sprite, so mole boundingBox, that's a rectangle with z
01:22width a height and xy coordinates. And second parameter is the point that
01:28represents the location you're testing against.
01:30So pass in location and if that's inside of the mole's bounding box, then
01:35we'll run the Action.
01:36So let's just cut and paste this MoveTo action inside the if statement and
01:41we'll change move to CCScaleTo.
01:43You'll see that it works in exactly the same way; you creat it with a create
01:49method, and then you pass in the scale value.
01:52So let's say I wanted it to be 10% bigger than the default size, we'll just pass
01:57in that 1.1 in there and I can test this after I save it; so I'll just Save, and
02:04then go and open up the Emulator.
02:07So here's the app running in the Emulator, I should be able to click outside of
02:11the mole, and see nothing happens. And then if I click right one the mole, then
02:15it scales up just a little bit.
02:16So that's the basic idea of Actions. They generally modify some type of property
02:21on an object over a period of time.
02:23There are many different Actions in Cocos2D, many more than we can list in one
02:28movie for that matter.
02:29So I recommend going into the documentation and looking at the Actions that are
02:33available just to get an idea of what you have to work with.
Collapse this transcript
Working with sprite sheets
00:00Up to this point all the graphics that we've used are individual files. The
00:05problem with that is many platforms bloat up individual files to the nearest
00:10power of 2, so 2, 4, 64, 128 etcetera.
00:16So that creates all of this empty space and wasted memory.
00:19Enter SpriteSheets.
00:20SpriteSheets enable you to pack your Sprite images into one big file that
00:26confines itself to the powers of 2 and eliminates those memory problems.
00:31I'm at codeandweb.com/texturepacker now; if you want to learn more about
00:37SpriteSheets, just click this SpriteSheet movie link, and there is an animated
00:40video that shows how SpriteSheets work that's quite informative.
00:44So TexturePacker is actually the one that I use personally for my games, just
00:48because you get a lot of excellent features for a relatively low price.
00:53Another one I used to use is called zwoptex, which you can find at
00:56zwopple.com/zwoptex.
00:58Zwoptex also has a free Flash version, if you click the download link at the bottom.
01:04That version includes an HTML file that will load in a Flash movie that enables
01:09you to bring in some Sprite.
01:11Now of course this is a very water down version of the full SpriteSheet creator.
01:16But if you want to do something for free this is your best bet for now. You can
01:21go to File>Import Images, select the Sprites you want to import; once you've
01:25imported them, you can arrange them, so that they're spaced out. And then you
01:29can choose File>Export Texture and File Export Coordinates, and bring both of
01:33those files into your Eclipse project.
01:35Now the features in Zwoptex and TexturePacker are a little bit different, but
01:39they're generally the same and I'll leave their respective documentations and
01:44instruction manuals for how to use them specifically.
01:47But basically it's the same situation; we're going to import Sprites and you're
01:51going to export a texture and coordinates.
01:54And you're going to need to bring those into Eclipse.
01:57Your texture file should be .png file or in TexturePacker it could be a .pvr.ccz.
02:04And your coordinates will be a .plist file which is a Raw text XML file that
02:09contains the coordinates for all of the images.
02:11So let's go over to Eclipse and look at how a SpriteSheet works.
02:15Of course now assuming that you do have a SpriteSheet ready, and all we need
02:20to do is go to our HelloWorldScene and we're going to need to add the Sprites
02:24from the SpriteSheet.
02:25So right above where we created the mole, I'm going to type
02:28CCSpriteFrameCache:: SharedSpriteFrameCache->addSpriteFramesWithFile.
02:36And in the addSpriteframesWithFile method I'm going to pass in the
02:39string moles.plist.
02:42Now obviously if you have a different plist file, you're going to pass in the
02:46name right there, and then I'm going to change the create method to
02:50createWithSpriteFrameName, now this is on the line of code where we're
02:55instantiating the mole.
02:56Now I'm going to change this frame name to c0011.png.Now this is the name of
03:05one of the Sprite files that I loaded in when I crated the SpriteSheet.
03:09And when you Export it you could open up that plist file in a TextEditor or
03:14Xcode if you have it, and you could look at the names of the different Sprites.
03:17But they're going to be exactly the same as the files that you imported into
03:22your SpriteSheet creator,
03:24unless of course you change the setting inside of the SpriteSheet creator app.
03:28So I have c0011.png and I'm going to put it right in the middle of the screen and we
03:35should see a mole graphic when we test it in the Emulator.
03:38I am going to Save this file and tab over to the Emulator, and there it is.
03:42Now I'll go back to Eclipse. So when you unload Sprites, you're going to need to
03:47create the SpriteSheet in the SpriteSheet trading app, whether that's the Flash
03:51version of Zwoptex or another app that you decide to purchase.
03:55You can add the Sprites to your project, you can add your SpriteFrames to the
04:00sharedSpriteFrameCache using CCSpriteFrameCache::sharedSpriteFrameCache,
04:06addSpriteFramesWithFile and passing in the name of the plist file. And then you
04:11can create a Sprite using a SpriteFrame with createWithSpriteFrameName and
04:16passing in an appropriate name for a SpriteFrame.
04:19Now remember, using SpriteSheets will save on memory and thus enable you to add
04:24more artwork to your applications and allow them to run more smoothly.
Collapse this transcript
Creating simple frame animations
00:00We've already looked at doing an animation by modifying Sprite's properties with
00:05an Action, but if you want to create an animation of frames, you'll have to go a
00:11slightly different route.
00:13You can grab these animation frames using an animation program like Flash or
00:18AfterEffects, or you can take still images from a program like Photoshop.
00:23Once you have the Animation frames, make sure they're in your SpriteSheet and
00:27loaded into your app.
00:28In the touchesBegan method, the first thing I do is stop all currently running
00:32actions using stopAllActions method.
00:35That way we don't get any conflicts, when we run the animate action.
00:39So here I'm going to create a CCArray, that's below stopAllActions.
00:43We'll call this frames, and we'll set it equal to CCArray::create.
00:48The CCArray class is an array that holds any type of data, so it's very easy to
00:53work with when you're making a Cocos2D game.
00:56You can create one using the create method, and you can add objects to it, using
01:00the addObject method.
01:01Now we'll create a for loop. In the for loop we'll run a loop from 1 to 11, so I
01:09have for integer i<=1 as long as i is less then or equal to 11, i++.
01:15All of my animation frames are stored in order, and they're numbered from 1 to 11.
01:20So they're b0001, b0002 all the way up to b0011.png.
01:29So we'll use a string to grab a string name for each frame, we'll hold that in a CCString object.
01:36Just like CCArray, CCString is an easy way to create and manipulate strings.
01:42We'll call this frame and we'll it set equal to CCString::createWithFormat, and
01:48then we'll pass in the string, "b%04d.png". After the string we'll pass in i, so
01:57that will give us the appropriate name for each frame.
02:02And now we need to put the frame inside of the frames array.
02:06Now to create our animation frames, we need to pass in CCSpriteFrames and not CCStrings.
02:13So we'll do that by doing frames-> addObject, and then we'll pass in
02:19CCSpriteFrameCache:: sharedSpriteFrameCache, ->SpriteFrameByName, in the
02:26parentheses pass in the frame, and we are going to need to convert this to a
02:31CString by running its method getCString.
02:33Outside of the loop we'll run the moles instance method runAction,
02:40it's mole->runAction.
02:42Now we're going to pass in one object, that's a CCAnimatedObject, so we'll run
02:46its create method, standard for Cocos2D.
02:49And in the create method we're going to pass in a CCAnimation, which is a series
02:56of frames held in a CCArray and the speed at which the animation should play.
03:00So CCAnimation, we'll call its create method, then we'll pass in the frames, and
03:06then .15 for the speed. Now this is in seconds and normally you do this a little
03:11faster, but I'm keeping it sort of slow, because I'm showing this movie in the
03:16Emulator and I want to make sure that you can see it in this movie.
03:19So we'll tab over to the Android Emulator and you'll see the animation here,
03:23if I just click anywhere on the screen, so there is the mole coming up from the bottom.
03:27So if you want to create your own frame by frame animations, you need to
03:31CCArray, put each frame inside of the array and then run the CCAnimate Action
03:37passing in a CCAnimation object with the frames and the speed at which you want
03:42the animation to play.
Collapse this transcript
Setting a game to display in portrait mode
00:00Now the app we're building in this course is actually a landscape app, so
00:04everything we have looked at so far has been in landscape mode.
00:08But what if you wanted to do Cocos2D in portrait mode?
00:10Well actually all you have to do is go to AndroidManifest and find the main
00:15activity for your app and just change the screen orientation from landscape to
00:19portrait and that is literally all you have to do.
00:22So just change it to the portrait, and if you save the file and you check it out
00:27in the Emulator, you'll see that everything is scaled accordingly so that
00:30background element is recognizing that the app actually is a portrait app and
00:34not a landscape app.
00:35So it's incredibly easy, just like you do for any of your other apps, just
00:40change the screen orientation from landscape to portrait and everything in
00:43Cocos2D is going to work perfectly, meaning the width and height of the screen
00:48are going to adjust because it's in portrait mode.
00:51So, that's all you have to do to work in portrait mode.
Collapse this transcript
Designing for multiple screens
00:00On Android you have to design for multiple screen sizes.
00:04We've already looked at that just a little bit in scaling our background, but
00:08for a whole game the process is just a little bit different than that.
00:12Here in the init method right under where I create size, what I'm going to do
00:16here is to decide to use either my high resolution artwork or my low resolution
00:20artwork, because of course, you have a higher resolution devices and lower
00:24resolution devices, and you don't want to use the high resolution art on every
00:28single device, because it might not perform that well.
00:31So, here we'll create a CCString and we're going to call this *file and we'll
00:36set it equal a conditional statement to check to see if size.width > 480.
00:44Now of course, this is just an arbitrary number, you can take any number you
00:48want for your high resolution artwork.
00:50But I'm choosing 480 her. And ideally you would put this method in maybe a
00:55Utility class so you can constantly just check to see if you should use your
00:59high resolution art.
01:01So after the parentheses I'll put a question mark (?)
01:03and we'll do CCString::create and then we'll use the high resolution version,
01:08which is just a double resolution version of the same image.
01:11So, it's going to be "moles_bg-hd.png".
01:17-hd setting comes from the iPhone graphics in Cocos2D, which get picked
01:22automatically when you're on a high resolution device.
01:25So I'm just using the same naming convention here, so I can use the same files.
01:29If the screen is not a high resolution, then we're going to provide the
01:33low resolution graphic.
01:35So CCString::create and then we'll pass in that low resolution graphic which
01:41is just moles_bg.png.
01:44And now in the create method on the next line, when we create the background
01:48Sprite, we'll pass in that file and we'll use an instance method getCString and
01:55we'll grab the CString for that.
01:57And that's really all you have to do.
01:59If you test it in the Simulator right now, you're going to see a high
02:03resolution background image.
02:05So, what we'll do now is do the same thing for a SpriteSheet and I'm going to
02:10copy this whole line of code starting right after the * and then we'll paste it
02:15down right above where we add the SpriteSheet. And I'm just going to change the
02:19files to moles-hd.plist and moles.plist respectively, same thing in
02:27addSpriteFramesWithFile.
02:30We'll do file, instance method getCString.
02:34And now if we save and check this out in the Emulator, here's what we get.
02:38It's maybe hard to tell on your screen right now, but this is a double
02:42resolution background and Sprite graphic.
02:44Note that I've also scaled up the mole.
02:48If you look at the setScale here, I've scaled that up based on the ratio of the
02:53X size of the screen.
02:54Of course, you could scale it up however you want and I recommend saving the
02:59scale value somewhere so that you know the ratio that you should scale
03:03everything up or down as appropriate.
03:06And that's how you design for multiple screens.
03:08You just have different sets of artwork, one for lower resolution screens, one
03:12for higher resolution screens and you scale your artwork based on the
03:15relationship of your art size, to your screen size.
Collapse this transcript
Running Java code from C++
00:00Let's say you wanted to add In-App Purchase or a Link to a Web Browser App on
00:05the device or you do anything else that runs Java code.
00:09In order to do that you're going to use something called Jni.
00:12You can use that to run Java code from C++ and vice versa.
00:17Right now, we're going to look at running Java code from C++.
00:20I am going to start by saying I intentionally chose to use prewritten code in
00:25this movie because most of it is semi- copied from somewhere else or something
00:30that you already know how to do for being an Android developer.
00:33The first step is to link to the jni files just like you link to the Classes folder.
00:38Remember in the C++ settings in the Project Properties Window, you'll see paths
00:44and symbols and there's a source location.
00:47So just like we added classes there, add the jni folder.
00:51And the path to the jni files, I can show you in the Android.mk file.
00:58So, let's go in here; I am going to double-click the tab to expand the view and
01:02the path is cocos2dx/platform/android/jni.
01:03You want to link to that folder included in your local C includes, and then I
01:14want you to create two new files called JniURL.h and JniURL.cpp and to add them
01:20to the Local Source files in Android.mk.
01:23Now before we define what goes in those files, let's go over to
01:26Cocos2dxActivity.java.
01:27If you want to know where this file is, you can find it in your Source Folder.
01:33So expand the Source Folder and then open up the org.cocos2dx.lib package and
01:40it's right in there.
01:41So open that up and in here just add a few lines of code.
01:45Right after the property declarations, declare private static Activity called me,
01:50and set it equal to null.
01:52And this is because we're running a static method to open the URL.
01:56And we want to save this instance, because there is only one instance of this
02:01Cocos2dActivity, and be able to call on it in our static method. So in onCreate
02:06set the value of me to this.
02:08So, the static method openURL is very simple.
02:12Create a new Intent, set the data to parse the url and then we run start Activity.
02:18So that's standard on Android there.
02:20Now let's go over to JniURL.h and here we declare external "C" and what that
02:27does is it enables us to run a method without referencing an instance of a
02:32class or class itself.
02:34So we have this method called openURLJNI where you pass in string and then from
02:39anywhere we want we can just open up a URL in the web browser.
02:43Let's go over to JniURL.cpp.
02:46So now we're importing some classes.
02:49One of them in particular is JniHelper.h and that has some helper methods, so we
02:55can easily run these Jni commands.
02:57So this method is defined with a JniMethodInfo and we check to see if the method
03:03exists for the JniHelper::getStaticMethodInfo.
03:07Then we pass in that JniMethodInfo object and then a string to the class
03:14where the method resides.
03:15This is the fully qualified name including the whole package separated by
03:20slashes instead of dots.
03:21Then next is the method name which is openURL and the next is the data that
03:26the method receives.
03:27So, this is the Java qualified name to that class, so the String.
03:31And then there is a jstring right here and that represents a Java string so this
03:36is a C++ data type, represents a Java string. And I set it equal to a
03:42NewStringUTF passing in the url received as a parameter.
03:46Then I run CallStaticVoidMethod, passing in the classID, methodID and the argument.
03:53So, that's going to run openURL in Cocos2dxActivity.
03:57Now the last step is to go to HelloWorldScene.cpp and then we're going to import
04:01that JniURL object and in the click handler, I passed in openURLJNI and a
04:09website address. And when you click on the screen, it should open.
04:13Also notice that I've commented out this line of code, showMessageBoxJNI and
04:18there's two parameters, a title for the MessageBox and the value in the field.
04:22You can use that method if you include MessageJni;
04:24I got it from the MessageJni class, as well as some help from the Coco2dx forums.
04:31So if you want to show alert box, that's how you do it, right now we'll test the
04:35app and take a look at clicking on the screen and how that opens up a URL.
04:39And now I'll test this in the Emulator, and if I click on the screen, you'll see
04:43that it exits out of this app and into the web browser and it goes to the
04:48website that I passed in as a string, back to the code.
04:52So, there are a lot of steps using Jni, but if you use it, you can run Java
04:57commands quickly and easily from your C++ code.
05:01If you're looking for more information on how Jni works, take a look at
05:05these linked files.
05:06Just open them up and look at how these files run Java commands from C++ and vice versa.
05:12By being able to run Java commands from C++, you have much more power in your
05:17applications and you can tap into native Android calls.
Collapse this transcript
Running C++ code from Java
00:00Since it's important to know how to communicate from C++ to Java, you should also
00:06know how to communicate from Java to C++.
00:09This will become significant later on in this course when we do In-App Purchases.
00:13The In-App Purchasing APIs are all done through Java.
00:16So you need some way to be able to communicate to C++ if they've
00:20completed successfully.
00:21Here, we'll look at a simple example of how to communicate from Java to C++.
00:26I've created a file called JniExample.cpp.
00:31Ofcourse, you'll need to add this to your Android.mk file; and here I didn't
00:36create a header file, it's just a CPP file.
00:39And I declared this method that returns a jstring.
00:41jstring is a C++ data type that corresponds to a Java string.
00:46We're going to call this method from Java.
00:49Note the name Java_org_cocos2dx_ lib_Cocos2dxActivity_nativeExample.
00:59This long method name is intentional and is necessary to run this code.
01:05Start the method name out with Java with capital J _ and then the fully
01:10qualified class name separated by underscores instead of dots and then an
01:16underscore and then the method that you're going to define.
01:19It needs to receive the JNI Environment and a jobject.
01:24You can also receive additional parameters, but remember that they are not C++ data types.
01:30They're the C++ Java data type, so they're going to be jint, jbool, jstring etcetera.
01:36You can look that up in the JNI documentation.
01:39So here what I'm doing is I'm returning a new UTF String.
01:43This is how I create a jstring.
01:45I call on the environment, NewStringUTF and I pass in the string.
01:49So if I see this string through a Java call, then I successfully ran C++ from Java.
01:56Let's go to Cocos2dxActivity.java.
02:00When you define one of these methods that you want to run from Java, you define
02:04it as a Java method using the keyword native.
02:08So this is going to return a string and the method is called, nativeExample.
02:12I'm not defining what the method does here.
02:15I'm just calling it out, so that's important.
02:17And then I just updated showMessageBox.
02:20I've commented this line and I've replaced it.
02:23And so for the title, it shows the title that's passed in and for the message,
02:26it runs nativeExample.
02:27So, it should get that C++ example.
02:31And the way that we show that MessageBox is the same as we've looked at before
02:35with calling a Java method from C++.
02:38So I've imported MessageJni.h, then I'm just calling showMessageBoxJNI, then I
02:44pass in first the message, which is you shouldn't see this.
02:48So when you run this in the Emulator, "You shouldn't see that text" and then the
02:52title, so Java->C++ and so, remember this message should get replaced by that
02:57code coming from C++, it's being called from Java.
03:01So, I'm going to open this up in the Emulator and I'll click the button on the
03:06screen and you should see that pop up showing up.
03:08So, there is the MessageBox; the title is Java->C++ and then Hello from C++ text
03:14tells us that Java is running C++ code and grabbing data from it.
03:19So by being able to call Java code from C++ and C++ from Java, we can
03:24successfully incorporate all of the APIs that are either Java only or C++ only.
Collapse this transcript
Using buttons
00:00We've already looked at touching on the screen and detecting whether that touch
00:04is in the bounds of the Sprite.
00:06But there is actually an easier way to create objects with simple
00:09interactivity like buttons.
00:11To do that we are going to go in our HelloWorldScene class and here I've created
00:17a mole as the SpriteFrame.
00:19If you have Exercise Files you can use any SpriteFrame here, just name the object mole.
00:25Make sure it's a variable that's declared in your header. And then also in my
00:29header I declared about that call buttonHandler and I just set the mole's
00:32visible property to the opposite of what it is, so running this method will show
00:37and hide the visibility of the mole.
00:40Under where we add the mole to the screen, I am going to create
00:44a CCMenuItemsSprite.
00:47The away that a button works is that you have something that's a subclass of
00:51a CCMenuItem. That goes inside of a CCMenu which you add to the screen using
00:58addChild, and a menu is basically a list of buttons and a CCMenuItem is an individual button.
01:05So CCMenuItemsSprite is a button made from the Sprite.
01:10So we'll call this btn and we'll set it (=) CCMenuItemsSprite::create.
01:15And here we pass in the normal Sprite, selected Sprite, the target and then the selector.
01:21So for the normal Sprite we'll just create a Sprite in line here.
01:25So CCSprite createWithSpriteFrameName and then we'll pass in the SpriteFrameName
01:32which is button_small.png.
01:35The next parameter is the selected Sprite, so if you wanted to change the Sprite
01:40when you touch the button, you could pass in the Sprite here or you can just put
01:44in NULL like I'm going to do to keep the Sprite the same when you touch it.
01:48Next is the Target which is going to be this;
01:50that's the instance that's going to run the method that we pass in for the last
01:55parameter and for the method or selector, type menu_selector and then in
02:01parenthesis we pass in the selector, which is HelloWorld::buttonHandler.
02:06Make sure you don't have the parentheses because you don't want to run the method;
02:09we're passing the method in as an argument.
02:12So on the next line we're going to create a CCMenu.
02:15Remember a menu is what displays the buttons.
02:18We'll call this menu and we'll set it equal to (=) CCMenu create, then we
02:22passed in the buttons and we use a null terminator to say work done passing in
02:28the button values, so btn and NULL.
02:30And then finally on the next line we just added as a child.
02:33So this addChild and we'll pass in that menu and the Z position which could be 1,
02:38and then we'll save and test. And we should see that when we test the app, you
02:43can click on the button and the mole shows and it's hidden, it's toggled each
02:49time you press the button.
02:50So we don't have to worry about capturing the coordinates of the touch, we just
02:55pass in a Sprite into the menu and it accepts coordinates and runs the
02:59appropriate selector.
03:01So there is the button and the mole Sprite down at the bottom, and so as I click
03:05you can see that the mole's visibility is toggled.
03:09So creating a button for simple interactivity like this is very easy, just
03:14create a CCMenuItem subclass, you can look them up in the cocos2d documentation,
03:21run the create method, pass in the Sprite, the selected Sprite, the target,
03:26selector, and then add it to a CCMenu, then you just run any method you want
03:32whenever you tap on the Sprite.
Collapse this transcript
Playing audio
00:01Cocos2D makes adding sound to your games a simple process with a class
00:05called SimpleAudioEngine.
00:07To use SimpleAudioEngine, include it in the class where you want to play a sound effect.
00:12So I'll include SimpleAudioEngine.h and then specify that you're using the
00:17namespace CocosDenshion. Then you can run an effect by using SimpleAudioEngine
00:23shared singleton instance shared engine, and run the method play affect, play
00:29background music, etc.
00:32Before you play in effect, you want to preload.
00:35If you don't preload it, then it will load into memory at the time that you want
00:40the effect to play, and there will always be a delay.
00:44So in the init method we're going to preload a sound effect.
00:48So just SimpleAudioEngine:: sharedEngine()->preloadEffect and the effect is
00:54going to be splat.wav.
00:55I am just going to copy and paste this into the buttonHandler and buttonHandler
01:02is going to run when we click the button on the screen and just change
01:05preloadEffect to playEffect in the pasted code.
01:09And that's all you need to do to play an effect. It's very simple and it only
01:13requires a line or two of code to use.
01:16So remember that if you want more information you can always look it up in the documentation.
01:20I am going to Save and we will test this in the Emulator.
01:24Now I'll tab over to the Emulator so you can see, and if I click on the button
01:28you'll be able to hear that sound effect.
01:30(music playing)
01:33So to recap, if you want to use SimpleAudioEngine, includ the class, use the
01:37CocosDenshion namespace and run the easy methods preloadEffect and playEffect to
01:44addEffects your game anywhere you like.
Collapse this transcript
3. Creating the Core Classes
Viewing a flowchart of the game's core classes
00:00Before we start building the code of the game, I'd like to discuss how the
00:04classes are going to be set up.
00:06Now this is just referring to the main game, so aside for the main menu, we have
00:11the game class and this is how it's organized.
00:14There is a CCScene, now it's created by the game layer, and the CCScene has four children.
00:21The four children are the GameOver Layer, the Pause Layer, the HUD Layer and the Game Layer.
00:26Now they are stacked similarly to how they are here.
00:29Game Layer is at the bottom, the HUD Layer is above that, and the Pause and
00:33GameOver Layers are in front of the HUD Layer.
00:36That means the pop ups in the Pause and GameOver Layers will display over the
00:40rest of the game elements.
00:42Each of those layers has its own children.
00:44The game has Moles and it has the Background, those are Sprites.
00:49The Mole class is a subclass of CCSprite.
00:52The HUD Layer has the score label at the top left and the Carrots is at the top
00:57right, representing lives.
00:59The score label is an instance of CCLabel TTF, that's the text field.
01:04And the Carrots are CCSprites.
01:06The Pause Layer contains the Pause Button at the bottom right of the screen
01:11and the Popup menu.
01:12The GameOver Layer just contains the Popup menu.
01:15So this chart is simply for your reference to have a better idea of how the
01:19classes are set up and how the visual objects in those classes are connected
01:24to each other.
Collapse this transcript
Creating constants and editing the AppDelegate and Main classes
00:00One of the more difficult decisions I had to make regarding this course was how
00:04much code to have prewritten versus how much code to write inside of the movies.
00:10Normally I don't like to use prewritten code, but this course is an exception
00:16because it's so advanced.
00:17It assumes that you already are familiar with working with Android, App
00:21development, Java, C++ and programming in general.
00:26Since you're very likely an advanced programmer and understand how a code works,
00:32I don't want to waste time showing the mundane things like creating a menu or
00:37creating a certain utility that we've already covered in the previous chapter.
00:42Rather, the handwritten code will all be relative to the game play.
00:47So other utilities I'm going to have prewritten, and that's what this chapter is all about.
00:52I'm going to walk you through the prewritten code that I have and you can see
00:56what it takes to build the foundation of your game.
00:59So, let's go to Constants.h. I always have a file called Constants.h when I make a game.
01:05It just has any kind of constant values I'm going to be using over and over
01:09again like strings or enumerated values that I can use for tags.
01:13A tag in Cocos2D is an integer that you can apply to just about any object
01:19and reference it later.
01:20We'll look at more about how that works later on, but just know that I have
01:24these set up in Constants.h.
01:26In the AppDelegate file, I made a few very small changes.
01:31If you scroll down to applicationDidFinishLaunching, you'll see that I edited
01:36the setDisplayStats, change it to false in the Hello World project, and then I
01:41set CCTexture2D, PVRImagesHavePremultipliedAlpha to true.
01:46Now what that does is I'm using a Sprite sheet that's from TexturePacker and the
01:50file is a PVR.ccc file.
01:53If you use that particular type of file, then you need to use this line of code
01:58in your AppDelegate, so that it works.
02:00And that just make Cocos2D compatible with that type of file.
02:04And then finally the main scene that I'm running is the MainMenu instead of
02:09the Hello World scene.
02:10Finally, let's go to main.cpp and inside of that main native init method, I've
02:18added these four lines of code.
02:20I've mentioned earlier that this app is a port of an iOS app that I've made.
02:24In iOS, you have a retina display device and a standard display device you develop for.
02:29The retina display device is twice the resolution of the standard display.
02:33So, I'm using the same artwork here.
02:35I just want to choose whether to use the standard display or the retina display.
02:39So artScale checks to see if the height of the screen is greater than 400.
02:45If it is, then I'm going to use the retina display scale which is twice the size
02:50of a normal scale, and if not, I'll use 1 for the normal scale.
02:55On the next line I have a float that represents scale.
02:58And this is going to decide, the scale that I'm going to modify all of our objects at.
03:03So, I'm going to apply this scale to basically every visual object in the game
03:09and we get the value by taking the height casting it as a float and then I
03:14divide it by also cast it as a float, 320, which is the original standard height
03:21of the art size times the artScale.
03:24So, that's either going to be 1 or 2.
03:26So basically, I'm just taking the height of the screen compared to the height of
03:31my artwork and that's going to tell me the ratio at which I should scale all of
03:34the artwork in the game.
03:36And then I run a static method called setScale and that's from my Utils class.
03:41We're going to talk about the Utils class in depth later on, but just know for
03:45now this is just a setter method.
03:46I have a value called scale and it just sets that value to the value that I pass in here.
03:51So basically, I'm just saving that scale value so I can apply it later.
03:55Same with setArtScaleFactor, this is either going to be 1 or 2.
03:58I'm just saving the value for use later.
04:01So, there's my constants header file and some changes that I've made to the
04:05classes that come in the Hello World project.
Collapse this transcript
Building the GameButton class
00:00The GameButton class is a pretty simple class that's a subclass of CCSprite.
00:05I use the GameButton for all of the menu buttons.
00:09So, that's the button graphic that's green with the text inside that has a shadow.
00:14So let's look at how that works.
00:16In the header file, you'll see it is just a subclass of CCSprite and I have
00:21two public methods.
00:22Let's go into GameButton.cpp and check them out.
00:27First, we'll look at buttonWithText and that's a static method and it returns a GameButton.
00:32Here we receive some text and a Boolean whether it's big.
00:37We create the new GameButton, we run initWithText, passing in the values and
00:42then we run autorelease.
00:44Autorelease means it will automatically get removed from memory, if you just
00:48remove it as a child that is of the parent object.
00:51And we'll scroll up and look at initWithText.
00:55In initWithText, we run the constructor for CCSprite and then we set the
01:00btnFrame; now if it's a big button,
01:02we use CCString::create that creates a string, which is passed in button_big.png.
01:09If not, we pass in, button_small.png.
01:11The integer fSize represents font size and that's 18 times the ArtScaleFactor,
01:17so that's either going to be 18 or 36.
01:20Then we run this->setDisplayFrame.
01:23DisplayFrame is the SpriteFrame that the object currently show, so you can
01:28actually manually change the frame that the Sprite shows at any time.
01:32And of course, you could use this over time if you wanted to it manually
01:35create an animation.
01:37So, this->setDisplayFrame, then we grab the spriteFrameByName from the
01:41FrameCache and we use btnFrame->getCString to get the CString from that CCString object.
01:49Now CCString is just a utility to quickly and easily create a formatted string.
01:54So that's generally what I use when I work with a string in Cocos2Dx.
01:58And I create a text label using the create method passing in the text, which is
02:03the title that we want to be in the label.
02:06Then I have CCString:: createWithFormat to grab FONT_MAIN.ttf.
02:11So, FONT_MAIN is from Constants.h. The file is going to be Toonish.
02:15That way if I change the font I want to use, it's going to use this constant value.
02:20So it's very easy to change the font, I don't have to go through my code over
02:25and over again to find every instance that I use that font name.
02:28So, I'll use getCString again to get the CString.
02:30And then I passed in the size of the font so it's fSize+isBig*fSize.
02:38So that gives us our button.
02:40And then we have label->setPosition and we set it to be the center of this object.
02:45This object would be the button.
02:47If we create that label, we put it on top.
02:50This labelShadow here creates another text label with the same text, the same
02:55font and everything, but I offset the position just a little bit to create the shadow.
02:59And then I set the Color to black and then I turn down the Opacity a little bit,
03:04so that creates the shadow.
03:05And then for this, I set the scale based on a scale from Utils.
03:10Remember I said earlier that it was just a getter and setter method.
03:12So this is just grabbing the value that's set in main.cpp, scales the
03:17button appropriately.
03:18So, that's how the GameButton class works.
03:20Just remember, if you ever want to add a shadow to an object, you just create
03:25essentially a copy of that object or another object with the same properties,
03:30offset it a little bit, change its Color to black and then set the Opacity to
03:34something between 0 and 255.
Collapse this transcript
Constructing the custom pop-up menu utility
00:00The Popup class is another subclass of CCSprite.
00:03It has one property called menu and it has a few methods defined.
00:08The addButtonWithText method receives some text, a target object and a selector
00:13to run when the object is clicked.
00:15Let's go over to Popup.cpp.
00:17Here we'll start in popupWithTitle, create a new Popup, run initWithTitle,
00:22autorelease, and return pop just like the Button object.
00:26In intiWithTitle, we run the Sprite init and then we create an object called m.
00:31This is the Sprite that is the menu graphic.
00:33So we put that right in the middle of the screen and then we give a title using
00:38CCLabelTTF to create a TrueType font title label and we put it on the screen,
00:44set the font name and the font size as we've looked at before.
00:49And then I set its position using setPosition.
00:52I use some math to place it near the top of the menu, add it to the screen using
00:59addChild and then run setVisible to false.
01:03So we hide all of these objects.
01:05That's the menu and the title.
01:07And then we'll scroll down to addButtonWithText.
01:11So we create a MenuItemSprite that puts in a GameButton, which passes in false,
01:18so a small game button.
01:19NULL for the selected object, the target that's passed in and then the same
01:23selector that's passed in.
01:24And then if a menu doesn't exist already, we create the menu using the Button
01:28and add it as a child.
01:29If the many already exists, we run addChild and then run
01:33alignItemsHorizontallyWithPadding.
01:35That way it keeps all the menu buttons aligned properly.
01:38And finally, we'll look at the show method and the show method enables you to
01:43choose to show or hide the popup.
01:45If you show the popup, the game pauses and if you hide the popup, the game resumes.
01:51So we grab the Game layer from Utils.
01:53Again, we'll look at that in just a minute.
01:55And then we have if (shouldShow), we run pauseSchedulerAndActions on the game
02:01and that's not a method that I created that's built into the Cocos2D and it
02:05enables you to pause any selector that's run on a scheduler.
02:09So that it runs repeatedly over time and pauses all the actions as well.
02:14So it's a quick and easy method to basically pause the whole game.
02:17So then there is its counterpart resumeSchedulerAndActions.
02:20And then I loop through all the children in the game and appropriately pause or
02:25resume their scheduler and actions.
02:28And then I set the Visible property of the Popup to shoudShow so, it
02:33either shows or hides.
02:34And then pause or resume the background music as appropriate.
02:38So the Popup menu is a useful class that pauses or resumes the game when you
02:43show it, and you can add buttons and a title to quickly and easily show a menu
02:49to select various options in your game.
Collapse this transcript
Setting up the code in the MainMenu class
00:00The MainMenu is a subclass of CCLayer and you could see that it's pretty similar
00:06to the HelloWorld default class.
00:08I just have one property called S and then the init, a playGame and mainMenu
00:14methods, the same Scene static method and then the LAYER_CREATE_FUNCTION
00:17passing in (MainMenu).
00:18Let's go over to MainMenu.cpp and in here in the Scene menu just as you expect,
00:25I create a blank CCScene and then I create an instance of MainMenu and add that
00:30as a child to the scene and return the scene.
00:33The init () method initializes CCLayer.
00:37Then I set the value S to be the size of the screen.
00:40And then the rest of this code here preloads the appropriate audio and art files.
00:45Now I'm choosing to load either ("moles -hd.plist") or regular ("moles.plist").
00:51Those are the large SpriteFrames for high-resolution screens and the standard
00:56SpriteFrames respectively; that's all based on if the ArtScaleFactor(>1).
01:01I do the same thing for the title screen, I either load in ("title-hd.png") or
01:06("title.png") and then I load in that background, setPosition to be the center
01:11of the screen, scaleSprite using Utils scaleSprite.
01:15We'll look at that in another movie.
01:17And then I add this as a child with this (-1) as the z-position so that it's all
01:22the way in the back.
01:23And then I create a playButton using the GameButton class to create the Sprite,
01:29and then I run MainMenu:: playGame as the selector.
01:33MainMenu playGame as the selector.
01:35MainMenu::playGame runs the Director's replaceScene method and passes in the
01:38game scene. I create CCMenu, put it on the screen.
01:43And then I have a method called MainMenu, which I can run if I ever want to
01:46change the game to the MainMenu without having to write this whole line of code.
01:50The MainMenu class is pretty simple and pretty straightforward, we just have
01:55all of our assets preloaded, we drop in the background and the play button, and that's it.
02:00So, the MainMenu class is pretty simple, we preload all the appropriate
02:04assets, we display the background, and we have the play button play the game
02:09when you tap it.
Collapse this transcript
Making the Utils class
00:00Utils class just holds a whole lot of static methods that enable us to easily
00:06run commands we're going to run repeatedly from various classes in the game.
00:10So, here's the list, now let's go over to Utils.cpp and take a look at what
00:15all these methods do.
00:16Now see I have a static float and int, the float for scale and int
00:22for artScaleFactor.
00:23If you scroll down to the bottom, you'll see that setScale and getScale are just
00:28simple getters and setters, and same thing for set and get artScaleFactor.
00:32We have also looked at scaleSprite; this is for background objects, it scales
00:38the backgrounds to the entire size of the screen.
00:41Now I chose to do this because I don't really care if the background is not
00:46exactly the right aspect ratio, but I really want my Sprites to be the
00:51right aspect ratio.
00:52So, for backgrounds, I just stretch them to fit the screen and it's never going
00:57to be off by that much so I'm not really concerned about it; but for regular
01:02Sprites I use setScale and getScale to set their values.
01:06They're going to be the same aspect ratio that I created them at and the
01:10backgrounds might change a little bit, because of scaleSprite.
01:12I have a method called getAnimationWithFrames; we just passed in with start frame
01:17and the end frame. And I created a CCArray, and a loop.
01:23And in the loop I created a CCString and it's formatted, so it's a, and then a
01:28four digit integer.png, and then the integer comes from i.
01:32So, the loop just goes from the start frame to the end frame, and then I used
01:37addObject method to add the frames to the Array using CCstrings getCString
01:43method and then I create an animation that runs at 24 frames per second, and
01:49then I create an animate object, which is an action, and I'd simply return
01:55the animated action.
01:56I have a method called S, that returns the screen size, layerWithTag grabs the
02:01currently RunningScene using the Directors getRunningScene method.
02:06If that Tag=TAG__GAME_SCENE that's a value that's set in our constants file,
02:14then I'm going to use getChildByTag to grab the appropriate CCLayer and return it.
02:19And if we don't find that layer, I'll return Null.
02:22And then we have hudLayer and gameLayer, they just run layerWithTag, but for the
02:27hudLayer and the gameLayer respectively.
02:29So, the Utils class is actually pretty simple, but you'll see throughout the
02:33rest of this course that it's very useful for running commands from all kinds
02:37of classes, because these are all static methods and they are very easy to work with.
02:41So once you have this class ready and you understand it, you are ready to start
02:46writing the code for your game.
Collapse this transcript
4. Building the Basic Mole-Whacking Game
Adding the game layers and the background
00:00We'll start building the gamePlay of our Game in the Game_header file.
00:04Remember, if you have Exercise Files, you can find out how to setup your project
00:08to match mine in the Exercise Files movie at the beginning of this course.
00:12If you don't have Exercise Files, just make sure you have the same class as I
00:16do, and that you're referencing them in your android.mk file.
00:19And as we go along and you see that I'm using a certain Sprite with a certain
00:23name you can just add that Sprite to your project.
00:26Here in my class declaration you can see that I've declared a few properties,
00:30and some methods down here.
00:32Let's go over to Game.cpp, make sure you import the appropriate classes, and use
00:38the appropriate namespaces.
00:40And then scroll down to the bottom and we are going to start in onExit().
00:43I am going to release moles, so moles ->release. And this is just going to be
00:48something that is going to be necessary later on, because we're going to call
00:52a method called retain on moles; we will need to release it when the scene
00:56changes back to the MainMenu.
00:58And then we are going to call the super onExit method, so CCLayer::onExit, and
01:03then in Game onEnterTransitionDidFinish this is the code that runs when a scene
01:09transitions to another scene.
01:11So, let's say you have a scene fade into another scene, basically this means
01:15that your whole scene is loaded and ready to go.
01:18This is the best place to initialize if you have a lot of objects to create.
01:23If you do it in init, you might find that the game starts and your objects are
01:27not really created yet.
01:29So, I highly recommend initializing objects, meaning creating artwork and
01:34everything in onEnterTransitionDidFinish.
01:37So, the first thing we'll do is type this->setTouchEnabled() and we will pass
01:42in (true). And then we're going to initialize the game on running this, initializeGame().
01:48And then let's scroll up to the very top and in the Scene method we're going to do the
01:53same thing that we have done for the scene and the Game.
01:56Notice that we're running setTag after the createscene, to setTag of the scene.
02:03That's how you associate that Tag integer with a cocos2d object.
02:07You can run setTag and you can also create an object and pass in a Tag as a third
02:12parameter into the addChild () method.
02:14So, we'll do that for the Hud layer, call this H, set it =HUD::create() addChild
02:20to the scene, give it z of 1, and TAG is going to be (TAG_HUD).
02:26If you are wondering why I picked a weird name like HUD, it stands for Heads
02:30Up Display, which is game talk for a layer of objects that are user interface elements.
02:36Like the score, and the lives, and pause button, everything.
02:41So, now Pause button we'll call it *p, and we'll do the same thing, we'll set it
02:46=Pause::create() addChild C of 1, the TAG is going to be TAG_PAUSE and finally
02:53we'll do the same thing for GameOver.
02:55Pretty GameOver object called *go, set it =GameOver::creates addChild C of 1
03:03TAG is (TAG_GAMEOVER), remember these values are coming from constants.h. And
03:08then we'll scroll down to initializeGame, and here we're just going to create the background.
03:13And to create the background will first need to grab the appropriate file.
03:17So, create a CCString and we'll call this File, and then we're going to put a
03:22conditional statement in this line and check to see the size of the art.
03:26We're going to getartScaleFactor, we are going to check to see if it's (>1), if
03:30so, we're going to show the high- resolution artwork, otherwise we will show the
03:34low resolution artwork.
03:35To create a ccstring shorthand, you can use the Command ccs, we just pass in the
03:40string in the parentheses (moles_bg-hd.png):
03:48or and a same thing, ccs, and then the string is going to be
03:52just "moles_bg.png").
03:56On the next line we'll create the Sprite, so CCSprite, will call it *bg, so
04:00it =CCSprite::create, and then we need to pass in the string of the
04:05appropriate filename.
04:07So, we use file->getCString()).
04:09Now we'll set the position to the center of the screen.
04:11So, bg->setPosition and we will pass in ccp.
04:15For the width we'll grab (Utils::s), it's going to get the screen size, as so
04:21.width/2, and the same thing for height (Utils::s() method, you get the size of
04:26the screen .height/2.Now we'll scale the background (bg), now usually you want
04:31to scale an object before you place it on the screen.
04:34But position is centered to the middle of the screen and its registration point
04:39is in the middle of the screen as well.
04:41So, scaling it down doesn't matter whether you do it before or after setting the
04:44position in this case.
04:45So, we are going to set the scale by typing Utils and we'll run the method
04:49scalesScripte, we will pass in the background (bg), and remember that we want to
04:54stretch the background to match the same size as the screen.
04:58And then we are going to add it as a Child of the main game layer.
05:02If we'll run addChild, pass in (bg), we give it a Z of 0 and that's it. So
05:09save and test this in the Emulator and what you should get is after you click
05:13the MainMenu button to play the game, you should just get the background on the screen.
05:18And if you get the background in the emulator, you're in business.
05:21Great, that was a lot of code just to get this graphic on there, but we're just
05:25laying the scaffolding for the app right now.
05:27So, we have the background on the screen, we have all of the appropriate layers
05:31added, and we have the things that happen when the scene is entered and the
05:35scene is exited as well.
05:36Now with the setup, we're ready to start laying out some of the assets in
05:40the game.
Collapse this transcript
Laying out moles in the Game class
00:00To lay out the Moles, we'll first define what happens when you initialize a mole.
00:05Remember that the mole is a subclass of CCSprite and I have some precreated
00:10properties and methods.
00:11The only ones that I've defined thus far are the getter and setter methods, so
00:16for the Mole it's only getIsUp.
00:18Let's go into the Moles init method right under where we run the super init
00:22method to initialize Sprite.
00:24And in here we'll set upTime equal to 2 .0f and we'll set isUp equal to false,
00:30and then we'll set the display frame of the mole, so this->setDisplayFrame.
00:35The DisplayFrame is the Sprite frame that will show for that that particular Sprite.
00:41So we'll set the DisplayFrame to
00:43CCSpriteFrameCache:: sharedSpriteFrameCache->spriteFrameByName, and the name is
00:50going to be the string a0001.png; save the file and go over to game.cpp.
00:57In the initializeGame method, at the top we're going to initialize the moles
01:02array; we'll set it equal to a CCArray create.
01:05This will create an auto released CCArray; that means it will be deleted from
01:11memory if we don't choose to retain it.
01:14So let's delete those extra parentheses and go to the next line, and make sure
01:17to retain the moles array.
01:19So remember if you ever called retain on the object in cocos2d, make sure you
01:23also call an accompanying release like we did in onExit in this case.
01:28Go down a couple of lines, and then we're going to create a Mole.
01:31So we'll create mole called Mole set it equal to type cast it
01:36Mole, Mole::create.
01:38Now we're creating the mole just so we can get its size data, and then we're
01:42going to delete it afterwards.
01:43So we'll create a float called hPad and we're going to set this equal to
01:49Utils::s. It give us the size of the screen .width/2 minus in parentheses
01:55mole->getContentSize.width times Utils getScale and after parentheses we're
02:04going to multiply that by 3.5f.
02:08That number comes from the first position of the first mole, so we're taking the
02:14middle of the screen;
02:15we're shifting it to the left by 3.5 moles, relative to their scale.
02:20Let's go to the next line and we'll do the same thing for vertical padding.
02:24So we'll call this vPad and we'll set it equal to Utils::s.height/2 minus mole,
02:32getContentSize.height times Utils:: getScale, we'll multiply that by 2.1.
02:43Now we don't actually want this to be in the center of the screen, I just made
02:47it shifted up and that's where that .1 comes in.
02:49Now go to the next line and just call delete and delete the mole.
02:53Now we'll create a nested for loop to create the moles.
02:56So in the outer loop create an integer called i, set it equal to 1.
02:59I'll run this as long as i is less than or equal to 4; and of course, i++, and
03:06the same thing for the inner loop except for we'll use j for the iterator. So
03:12integer called j equals 1, as long as j is less then or equal to 6, then j++.
03:19We're going to have a total of 24 moles.
03:23Now in the loop, create a Mole, we'll call it mole and we'll set it equal to
03:27again a typecasted mole, run Mole:: create, and on the next line we'll set the
03:33scale of the mole, so mole->setScale and we will pass in Utils::getScale, and
03:40then on the next line we're going to set the position of the mole.
03:43So mole->setPosition pass in a ccp, remember that short for a CCPoint, and we
03:49passed in an XY coordinates.
03:50So the x-coordinate is going to be j times mole->getContentSize.width times
03:59Utils::getScale+hPad.
04:02Now we'll do the same thing for the y position.
04:06So it's going to be i times mole->getContentSize.height times
04:12Utils::getScale+vPad, and then on the next line we're going to add the mole to
04:19the moles array, so moles->addObject, pass in mole, and then finally we'll have
04:27the gameLayer, add the mole as a child, so this->addChild mole z of 1.
04:34So now you should be able to save and test this in the Emulator and once you
04:38click the Play button from the Main menu, you should see your screen look like
04:42this and all the moles are laid out and centered on the screen.
Collapse this transcript
Animating the moles
00:00To animate the Moles we'll begin at the start method in the Mole class.
00:04So in here the first thing we're going to do is to stop all actions.
00:10So, stopAllActions, and then we'll set isUp equal to true, set didMiss equal
00:14to true, and then we'll run an action, so this->runAction. And this is going
00:19to be a CCSequence.
00:20A sequence is a series of actions that run in order.
00:24So CCSequence::create, and then it's a NULL terminated series of actions.
00:30So we just end the last one with NULL, and then I'm going to break this up by
00:35lines, so I have CCDelayTime::create then we pass in the amount of time that we
00:40want to delay. And the amount of time that we want to delay is uptime, which
00:45we've set at the top to 2.0f, so CCDelayTime::create, pass in upTime.
00:51Now after that point that person playing the game has missed this particular
00:55Mole after its been up long enough, and so then we want to stop the mole from
00:59animating, and basically this will count as a miss, which we'll fully handle a
01:03little bit later on.
01:04Next method is going to call a function, so CCCallFunc. This is another
01:09action that calls a method, so pass in create, and then we need to pass in
01:14the target and the selector.
01:16Target is this, that's the object that has the method that we want to call, and
01:20then we pass in the method that we want to call.
01:22So pass in callfunc_selector and in the parenthesis for that, pass in Mole::stop.
01:29Make sure to not include the parentheses, because the argument is actually a
01:32method itself and not running the method, and then I'm just going to copy and
01:37paste this block of code that runs the sequence, and in the pasted code I'm
01:41going to change CCDelay time to Utils ::getAnimationWithFrames and the first
01:48argument will be 1 and the second will be 10, so we'll play the first animation
01:53that's going to be the Mole coming up.
01:55So if you don't have Exercise Files, you'll need a 10 frame animation here or
01:59you can just have a 2 frame animation,
02:01however you want to do it. Just pass the starting and ending numbers in here.
02:05Make sure that you've named frames in sequences well, so a0001, a0002 etc.
02:12And then the method that we want to call this time, in the pasted code is
02:16Mole::startLoopAnimation.
02:19So we have the mole shoot up and then he starts the loop animation, and if after
02:24the upTime has expired, then the animation stops.
02:27Let's go to startLoopAnimation and we'll define what happens there.
02:31First thing I want to do is check to see if the Mole is not up; if so, we're
02:35going to return, so if not, isUp return.
02:38Then we're going to create a CCRepeatForever.
02:42A CCRepeatForever is another action that as you might guess runs forever.
02:46We'll call this repeat and we'll set it equal to CCRepeatForever::create, and
02:50then we're going to pass in a CCSequence.
02:54Now we're actually going to typecast it as a sequence first. That's just because
02:59of how CCRepeatForever works, it maybe a bug with cocos2d, but you have to
03:05typecast it as a sequence for it to work.
03:07So we'll typecast it as a CCSequence, and pass in CCSequence::create, use the
03:13NULL terminator here.
03:14So this sequence again is going to run over and over and over again forever.
03:19So Utils::getAnimationWithFrames, we pass in the start and finish frames which
03:25are 11 and 20, separate them with a comma, and then I'm just going to copy and
03:31paste that one of code. And after the close parentheses, I'm going to run
03:35reverse, and that's actually going to give me a frame 20 through 11 animation.
03:41So we'll reverse that animation, very useful, so we can repeat this animation
03:46back and forth and that will go forever, and before we run it we're going to set
03:50a tag on it. So repeat->setTag, and then we pass in tag that we defined at the
03:57top which is TAG_REPEAT_ANIM.
03:59And we're going to copy that, pass it in there, that way we can reference it later if
04:05we need to stop it specifically.
04:06So this so this->runAction, and then we pass in repeat.
04:11And if you do want to stop one action in particular, you can
04:14run stopActionByTag.
04:16So we'll go into stop now to find what happens when the Mole stops.
04:20First thing we're going to do is run this->stopAllActions.
04:23Now in the next line I'm just going to copy and paste the block of code from
04:28start, where we run the Utils:: getAnimation and in the CallFunc, because this is
04:33going to be pretty close to the same thing.
04:35So the animation is going to frames 1 through 10 reversed, so we'll just run a
04:40reverse on that 1 through 10 animation.
04:42And the method we want to run is reset;
04:44we'll just change startLoopAnimation to reset.
04:47And finally we'll define reset. Here we'll set isUp to false, check to see if
04:53the person playing didMiss the Mole, and if so, we'll run Utils
04:57hudLayer()->missedMole.
05:00We'll define what that does later on;
05:02we're just telling it to run that method now.
05:04So save this file and jump over game.cpp, and then we're going to run the start
05:10method on a Mole and should see that the mole goes up and then goes back down at
05:14the end after the time has passed.
05:16So after the Moles are created in the for loop, we'll create a Mole object
05:20called m and we'll set it equal to typecasted Mole, and it's going to be
05:25moles->RandomObject.
05:26In the next line we'll run m->start.
05:29So you can save this file and test it in the emulator and you should see that
05:33one random mole animates up.
Collapse this transcript
Displaying moles at a specified time interval
00:00Now that we have setup the mole animation what we'll do is have the moles
00:04randomly pop up as time goes on.
00:06To do that scroll up to the init () method and then we are going to define
00:10some property values.
00:12And the first one is going to be molesAtOnce.
00:15This is going to control how many moles will show on the screen at one time; we
00:19will start that out at 3, and then will set timeBetweenMoles=0.5F, and then we'll
00:26set increaseMolesAtTime=10.0F.
00:31So let's scroll down to initialize game and then what we are going to do is
00:36something called schedule () a selector. And when you schedule_selector it by
00:39default runs a method along with the frame rate of your app.
00:44So, if your app is running at 60 frames a second, it will run this method at
00:4860 times per second.
00:50So it enables you to control things over a period of time.
00:53So to do that type this-> schedule. and then we're going to pass in
00:58(schedule_selector) and in parentheses pass in (Game::tick). Remember not use
01:04the parentheses () for tick as you are passing in the function not running the function.
01:10So, go down to tick and in tick what we're going to in do is we're going to
01:14add values based on the amount of time that has passed, which is received
01:19through this (float dt).
01:21So, here timeElapsed += dt;
01:25and then on same time we will go to increaseElapsed += dt; totalTime += dt.
01:33And now what we want to do is check to see if() we should show another mole.
01:37Basically we are just checking to see if enough time is passed, and we're
01:40checking the amount of moles on the screen.
01:42So, in the if statement, the first that you are going to type this
01:46timeElapsed greater than(>) or equal (=) to timeBetweenMoles && this->getMoles
01:54then we pass in (true) because we want to see how many moles are up and we get the
01:59count of that array.
02:00Remember getMoles returns an array of either moles that are up, or moles that
02:04are down, depending on the value you pass in.
02:06So, true means moles that are up and false means moles that are down. We'll
02:10define exactly how that works in just a minute and we want to check this to see
02:14if the count is less than (<) molesAtOnce.
02:17And if so, we want to show a mole, so inside of the if ()
02:20statement this->showMole().
02:22And on the next line timeElapsed=0. So as this method continues to run over and
02:29over again, timeElapsed will increase and as it's greater than (>)or equal(=) to
02:34timeBetweenMoles and if we can create a mole, we run showMole, we reset
02:38timeElapsed and so on;this method continues to run over and over again.
02:43Let's scroll on the showMole, we'll define that, then we'll defined getMoles.
02:47So in showMole, we are just going to grab a random mole.
02:50Now we want to make sure that this mole is down.
02:53So, we'll create a variable called Mole, let's type *mole and we'll set it
02:58=typecasted (Mole *), this->getMoles pass in (false); we want to get a mole
03:04that's down, because we're going to make a mole pop up.
03:06Remember that's an array, and the advantage of CCArray is that it has a method called
03:10randomObject, so you can easily grab a randomObject out of your arrays;
03:15So a randomObject that will give us a mole that's down. And then the next thing
03:19we need to do is have it start.
03:21So moles->start and then will define getMoles.
03:25So, inside of getMoles create a CCArray and will call this *ary,
03:29set it=CCArray::create.
03:32So, we'll create the Array and then we're going to loop through all the moles,
03:36and if a mole matches is up then we will put them in the array.
03:40So, for(int i=0, i is <1 moles->count()i++).
03:45So we're going to grab a Mole, we'll call it *mole that's going to be moles
03:50object index i, and you will need to typecast it to a (Mole *).
03:54So, you just type that in, moles-> objectAtIndex pass in (i) and then we want to
04:01see if() the mole is up.
04:02So, if() (mole and then we run getIsUp () == isUp), now this can apply whether
04:09the moles up or down based on what we pass into this method.
04:12Then we are going to add it to the array.
04:14So, ary aaObject and pass in the mole. And then instead of returning NULL, we
04:19will just return the array, and that's it.
04:22You should now be able to save and test, and see that in the Android Emulator,
04:27when you click play, those moles randomly pop up everywhere on the screen.
04:32So now you can see our game is progressing to be more and more like a real
04:36game. All we need now is interactive element.
Collapse this transcript
Handling touches in the game
00:00Now we add interactivity to our game and CCTouchesBegan. Here is the plan, we're
00:05going to grab the touch information, including the location information, loop
00:09through all of the moles and see if they touch touched one of the moles.
00:13If so, we're going to send a message to the Mole that it was tapped and
00:17handle it from there.
00:18So, inside CCTouchesBegan in the game class, reference to CCTouch, we'll call it
00:23*touch, and we're going to set it = typecasted (CCTouch *), that's going to
00:28pTouches any object.
00:31Now a pTouches is a CCSet, which is similar to an array, it's a set of objects
00:37and so there are multiple touches inside of pTouches.
00:40This method is also called CCTouchesBegan implying that multiple touches
00:44could happen at one time.
00:46You can use this to handle multi-touch, but on Android I've seen it work very
00:51sporadically. It worked fine for me on iOS where I like to just loop through the
00:56CCSet, but on Android, multi touches will only work once in a while.
01:00So I chose not to use it in this case.
01:04If you find a very effective way to handle multi-touch on android with
01:08Cocos2d-X, let me know on Twitter.
01:10Let's go to the next line and your CCpoint, this is going to be the location, and
01:15we are going to set it =touch-> locationInView. And then we are going to set
01:19location again, and this is going to be
01:23CCDirector::sharedDirector()-> convertToGL and then just pass in a (location).
01:30Now this is going to be very familiar, since we already handled Touches in
01:33the exact same way.
01:35So now what we are going to do is loop through all of the moles, and to see if
01:40this location overlaps any of the bounding boxes of the moles, and if so, we
01:45will just tell that mole that it was tapped.
01:47So, I create a for Loop, standard here, (int i=0) we are going to loop through
01:52the count of the moles.
01:54So, as long as (i) <moles->counts i++ and then inside of the loop we're going to
02:01reference a mole based on the index of the mole inside of the Moles array.
02:06So, we are going to have to typecast it, because it returns CCObject for each
02:11object in the array.
02:12So, it's going to be moles-> objectAtIndex pass in (i )and so there' is our mole.
02:19Now we want to see if the mole is up, so we're going to see if the mole is not
02:25up, and if it's not up, we are just going to continue to the next mole.
02:29So, mole->getIsUp, so I continue instead of that if () statement. And now we are
02:33going to create another if() statement.
02:35So we know now that the mole IsUp and we want to check to see if the touch is
02:39inside of the mole's bounding box and you may remember how we do that before.
02:43So, we just do (CCRect:: CCRectContainsPoint and we passed in the rectangle, which
02:49is going to be the bounding box of the (mole).
02:51So, (mole->boundingBox) and the next parameter is the location.
02:54And then in here we just tell the mole that it was tapped and then we don't
02:58need to go through any other moles since we already have one, so we'll just
03:02break out of the loop.
03:03And now I am interested to find what happens on the mole side when it's tapped.
03:07So save and jump over to Mole.cpp and we will handle that there, scroll down in
03:13the Mole class to what is tapped, should be empty.
03:16And in here what we going to do is just stop all the molesActions(), and then
03:21we'll run the animated actions have the mole animate down.
03:25So this run action we want to pass in (Utils::getAnimationWithFrames), when we
03:33pass in 21 and 31 that's the mole hit animation so it's going to turn red.
03:39And then finally, we are going to set isUp = false, so the mole is no longer
03:43counted as up, once it's been tapped.
03:45So, let's save the file and just test it out in the emulator.
03:49So now hit play, and you'll see that Moles pop up and then I can tap them and
03:56they play a little animation and go down, excellent!
04:00So, as expected, when you tap on the Mole, the Mole animation plays and the Mole
04:04goes back down and has the opportunity come back up again, and now our game
04:08finally feels like a game.
Collapse this transcript
Displaying the player's score
00:00Now that we can handle tapping the moles, we will look at giving the player a
00:04point each time the player taps on a mole.
00:07So go into ccTouchesBegan and inside of the CCRectContainsPoint if statement
00:13right under mole->wasTapped let's tell the game that the players scored.
00:17We will do that by communicating to the hudLayer.
00:19Utils::hudLayer()->didScore.
00:23Save the file and go over to HUD.h. Here are the properties and methods for the HUD class.
00:29Let's go into HUD.cpp and you will see that it's pretty much blank.
00:33In the init method, we will set score to 0 and we will create a float called
00:37padding and set it equal to 10, and that we will define the score label.
00:41scoreLabel = CCLabelTTF::create and we will start by passing in the string 0,
00:48it's what's going to be inside of the text field.
00:50Next parameter is going to be a string, so CCString and we will run it's
00:56createWithFormat method, and first we will pass in %s and then .ttf.
01:02And we are going to grab that font after the Comma (,) by using our
01:08constant value FONT_MAIN.
01:11After that close parentheses, we will run getCString and then a comma after that
01:16and the last parameter is the size of the text field.
01:20So it's going to be 24*Utils::getArtScaleFactor.
01:21Go to the next line; here we are going to set the anchor point, that's the XY origin.
01:32scoreLabel->setAnchorPoint and this is based on a percentage, so if you want to
01:39have it be in the center it's 0.5, 0.5.
01:43So there is the X origin and the Y origin that we pass in as the ccp.
01:48What we wanted to do is stick at the top left of the screen, so we are going to
01:52use a top left XY origin.
01:54So X origin of 0 which represents the left edge of the object and a Y origin of
02:00one, which represents the top edge.
02:02Now we do this because we have less math to calculate if we give it a
02:07registration point that's appropriate for its position.
02:11Let's go down to the next line and set the scale.
02:14So scoreLabel->setScale and then we pass in Utils::getScale.
02:19On the next line we are going to set its position.
02:23So scoreLabel->setPosition and the position is going to be ccp of course, and
02:30the X position is going to be padding.
02:32Remember we have that left edge of the stage as a registration point, so it's
02:36going to be 10 points from the left edge of the screen and then for its Y
02:40position, we are going to get the height of the screen, so
02:43Utils::s().height-padding.
02:44So it will be 10 points from the top of the screen.
02:51Now we want to add it as a child of the hud, so this->addChild, pass in
02:56scoreLabel and then the Z position which we will set at 1, and then scroll down
03:03to didScore; remember this is going to run once the mole was tapped as we
03:06defined in the game class.
03:08So we are just going to increment score by 1 and then set the text to the scoreLabel.
03:13So scoreLabel->setString and then we are going to pass in the string which is
03:19going to be a formatted CCString.
03:21So CCString::createWithFormat and that's going to be just the number of the score.
03:26So %d and then after the close quotes of the string, score after a comma and
03:34then we are going to run getCString and that's it, just pass in the score of the
03:38string, it's going to increment every time we tap a mole, so hit Save and test
03:42this out in the Emulator.
03:43So now I will run the app in the Emulator and when I hit Play you will see
03:49the moles moving up and down as they should and when I click on them, you
03:53will see the score going up.
03:54Now I will go back into the code, and now we have a system to calculate the
03:59player's progress as they play through the game.
Collapse this transcript
Handling misses
00:00Let's handle what happens when the player misses a mole and it goes down
00:04before the player taps it.
00:06We will start in Mole.cpp in the reset method.
00:10Remember that we already set to see if the person missed the mole, and if so we
00:15run the missedMole method in the hudLayer.
00:19So let's go to the HUD now and missedMole doesn't have anything in it yet.
00:23What we are going to do is create a system that has three different lives, so
00:29each time the player misses a mole they lose a life. And once they miss all the
00:33moles and they get game over.
00:34We need to create the lives which are going to be a carrot graphic inside of the init method.
00:39Under where you create the padding variable, set the value of carrots = CCArray::create.
00:46Now on the next line retain it, so carrots->retain.
00:51Remember that in cocos2d objects automatically get released from memory if they
00:57are not used for an amount of time.
00:58So for things like CCArray, you need to call retain if you are going to
01:02reference it throughout your code.
01:04So we will do the release at the bottom of the code in the onExit event handler.
01:08So here we will run carrots-> release and then we will call this a super
01:13method, so CCLayer::onExit.
01:15Scroll up to the init method and here we are going to use a for loop to
01:20create the carrots.
01:21So standard int i= 0 and we are going to run this as long as there are carrots left.
01:28So we are going to set our carrotsLeft variable right above the for loop. I'm
01:32going to set that equal to 3.
01:34So we'll run a loop as long as carrots are left.
01:37So as long as i < carrotsLeft and then i++. We are going to create them at the
01:42top right of the screen so we'll create a CCSprite in the loop.
01:46Call it c, set it equal to CCSprite ::createWithSpriteFrameName, pass in
01:53the string life.png.
01:55Go to the next line, we're going to setAnchorPoint to the top right, so
02:00that's going to be a ccp with one for the x anchor point and one for the y anchor point.
02:07And then we are going to set the scale, so c->setScale, pass in Utils::getScale.
02:13Next line, set the position.
02:15We are going to use the loop to set them and create them from the top right
02:19corner, moving outward to the left.
02:21So setPosition, it's going to be another ccp.
02:23We will start with Utils::s().width- padding-i * size of the carrot times a scale.
02:34So in parentheses c->getContentSize(). width*c->getScale, and then after the x
02:45value we will do the y value.
02:46So a Comma(,) and then we will type in Utils::s().height - padding.
02:53So the little carrot graphics will start at the top right, and just build out to
02:57the left as they go.
02:58Go to the next line and we will run carrots, that's our CCArray, addObject(),
03:05pass in c. We are going to store them in an array, then we are going to add them
03:10to the hudLayer using addChild.
03:11So this->addChild on the next line, pass in c and a z value of 1.
03:19Scroll down and now we are going to the missedMole method.
03:22The first thing we will do is decrement carrotsLeft--;
03:25then on next line we want to see if we still have carrots in the carrots array.
03:33So if statement, that's going to be carrots ->count()>0, then we will remove the child.
03:40So this->removeChild and in the parentheses we are going to pass in a typecasted CCNode.
03:48It's basically a generic cocos2d visual object.
03:56It's going to be carrots->objectAtIndex, and it's going to be the last object.
04:00So it's going to be carrots->count()-1.
04:02So this will destroy the carrots from the left going to the right.
04:06After the closed parentheses for objectAtIndex, we are going to pass in true,
04:10and second parameter is clean up.
04:13And if that carrot did have any children, it will remove them as well.
04:17Then carrots on the next line, removeLastObject, we want to take it out of the
04:23objects that are displayed as children in the hudLayer and then we want to take
04:27it out of the carrots array.
04:29And finally, we are going to check to see if the game is over.
04:33So in if statement below that statement, we are going to check to see if
04:37carrotsLeft is <= 0, and we are not going to handle the game over now, but
04:43that's going to be the game over area of code.
04:45If you like to mark it with a comment, feel free to do so and then an else
04:50statement below the if statement. So there are still carrots left, the game is not yet over.
04:54We are going to get all the moles that are up, so CCArray, call this moles, set
04:59it equal to Utils::gameLayer()-> getMoles, pass in true, so all the moles that
05:05are up, and we are going to loop through these moles.
05:08So again, standard loop here. i<moles->count();
05:12i++ and we will reference a mole called m, we will set it to typecasted Mole.
05:19It's going to be moles-> objectAtIndex, let's pass in i and we will tell
05:26that mole to stopEarly.
05:28Save the file and go back to the Mole class and we will find stopEarly and we
05:33will define what happens in this method.
05:35So all we will do here, we will set didMiss to false, set isUp to false,
05:41stopAllActions and then we will call stop, so this->stop();.
05:45So that's it, so we will Save and test this in a simulator.
05:50What we should get is the carrots laid out at the top right of the screen, when
05:53you miss a mole a carrot disappears and all the moles in the screen go down.
05:59So let's save and test.
06:00So I will click Play and I will look for those carrots at top right and I won't
06:05tap the mole but you will see all of them go down and the carrot disappears.
06:09And finally, last carrot is gone.
06:12And of course, nothing happens after that because we haven't defined exactly
06:14what happens when you get a game over, but it is working properly.
06:18So we have successfully created what happens when you miss a mole and now our
06:22game is starting to get that stressful element that happens when you feel like
06:26you are going to lose.
Collapse this transcript
Controlling the number of moles on the screen
00:00Our goal now is make the game get more difficult as it progresses.
00:04And to do that we want to increase the number of moles allowed on the screen at once.
00:09We will start in the Game::tick method.
00:12At the very bottom, we will check to see if increasedElapsed is greater than or
00:17equal to increaseMolesAtTime, and here we will control the number of moles that
00:22can be on the screen at once and the amount of time between the moles, so the
00:26game will get progressively more difficult.
00:28So the first thing we will do is create an integer maxMolesAtOnce and set
00:33that equal to 18 and then we will check to see if molesAtOnce is less than maxMolesAtOnce.
00:41If so we will increase molesAtOnce.
00:42Then we will create a float called minMoleTime, this is going to be minimum time
00:48between moles. Set that equal to .1f, so a tenth of a second is the minimum
00:53time between moles.
00:55On the next line, we will subtract from time between moles.
00:59timeBetweenMoles -=, in parentheses will do a condensed if statement on this
01:04line, so timeBetweenMoles > minMoleTime, and if that's the case we are going to
01:11subtract .05 from timeBetweenMoles, if not we will subtract nothing.
01:17Go to the next line, we are going to add on to increaseMolesAtTime by ten seconds.
01:23So += 10.0f.
01:24So it will gradually get harder and each time there are more moles on the
01:29screen, it will take ten more seconds to add an additional mole.
01:32Outside of that inner if statement, we are going to set increaseElapsed = 0.
01:37Now we will save and test this in the emulator, and what you should see is that
01:43overtime the game becomes more and more difficult.
01:47So there are more and more moles on the screen at once.
01:49So now I will click Play and I will play the game for over 10 seconds and after
01:58that time we should start seeing four moles on the screen at once.
02:01There are our four moles.
02:08So as you play longer and longer, the game should get more and more difficult
02:12and now it feels more challenging.
02:13So it's more game like.
02:16I just remember that if the game is too easy or too hard for you then you can
02:21adjust that simply by controlling the values of these variables.
Collapse this transcript
Adding sound
00:00Sound effects and music will give more life to your game.
00:04To do that, we are going to use simple audio engine.
00:07If you go to the MainMenu class, you will see that I already have a few lines of
00:11code where I used simple audio engine.
00:13You can access the singleton instance through sharedEngine and you can run
00:16simple methods like stopBackgroundMusic, preloadBackgroundMusic,
00:18playBackgroundMusic, preloadEffect and playEffect.
00:24I am going to copy this preloadEffect line of code and just paste it on the next line.
00:28I am also going to preload moles_miss.wav.
00:33Save this file and go over to Game.cpp.
00:36In initializeGame(), I am going to play the background music.
00:40So it's SimpleAudioEngine and make sure that you include this class if you
00:44haven't already, sharedEngine()-> playBackgroundMusic and the BackgroundMusic is
00:49going to be moles_bg.mp3.
00:53I use mp3 files for background music to conserve file size and WAV files for
00:59effects to preserve quality.
01:02And that's because the effects are always very, very short, so an mp3 doesn't
01:07save a ton of space in a half second.
01:09Let's scroll down and we are going to find the TouchesBegan method and where the
01:15mole->wasTapped and we didScore, I am going to play the Splat effect.
01:20So SimpleAudioEngine:sharedEngine()-> playEffect and the effect is going to be SOUND_SPLAT.
01:29Save the file and then we'll go over to the HUD.cpp and when we miss a mole,
01:35which we handle in missedMole, near the top I am going to play the miss sound.
01:40So I will paste that code that I copied earlier to preload the Effect.
01:44I will change it to playEffect.
01:46Change SOUND_SPLAT to the string, moles_miss.wav and that's it.
01:52So now we should build the save and run the app in the emulator and once it
01:56launches we will hear that background music play as we play the game, the miss
02:01sound, when you miss a mole, and the hit sound when you tap a mole.
02:05So we hit the Play button and we should hear the sound.
02:07(music playing)
02:08So I will close the emulator and you could hear the background music playing as
02:18I play the game and when I tapped a mole, it played the splat sound, and when I
02:23missed a mole it played the missed sound.
02:25So you can use sound effects using Simple Audio Engine and the simple methods
02:28like play effect and preload effect.
Collapse this transcript
Enabling a pause feature
00:00Now we'll look at how to pause the game, stop all the animation during the
00:04gameplay and have an option to resume or go to the main menu.
00:08So let's jump over to the Pause class and we'll start in the header file to
00:12just look at the properties and methods that exist for this class, and then go
00:17over to the Pause.cpp.
00:19In the init method we will give a value to pauseButton and we will set that
00:23equal to CCMenuItemSprite::create and then we need to pass in a sprite for the
00:29default sprite and then the secondary sprite.
00:33The default sprite is going to be a CCSprite that we will create right
00:36here, this is going to be createWithSpriteFrameName and the FrameName is pause_button.png.
00:45Second parameter for CCMenuItemSprite:: create is the selected sprite which we'll
00:51pass in NULL, then the target which is this, and the selector we want to run. And
00:57remember you have to pass in a special format for that, that's' menu_selector
01:02and in the parentheses we pass in the selector which is Pause::pause.
01:07Make sure you don't run the method here that you just reference it.
01:11Go to the next line and we will create a CCMenu and we will call this menu, set
01:16it equal to CCMenu::create and we will pass in pauseButton and then NULL,
01:23terminate the list of objects.
01:25Then we are going to set the position of the menu, so menu->setPosition and here
01:29I am not going to adjust the Anchor point, but I am going to put the pause
01:33button in the bottom right of the screen.
01:35The reason I don't want to adjust the anchor point is because we are controlling
01:39the position of the menu and the pause button, and they have relative
01:42coordinates to each other.
01:43I have had a lot of problems with laying out menus and their individual buttons
01:49by using anchor points, so I always leave the default anchor points in the case
01:53of buttons and menu items.
01:54So we'll pass in the ccp here and then this is going to be Utils::s().width
02:01- pauseButton->getContentSize().width/2, and the Y position is just going to
02:10be half the pauseButton's height, which we will align it with the bottom of the screen.
02:14So pauseButton->getContentSize().height/2.
02:15Then we are going to add it as a child of the pause layer, so this->addChild and
02:22then we will pass in menu and 1.
02:25So the Z position is going to be 1 and now we are going to give the value to the pop up object.
02:31So popup = Popup::popupWithTitle.
02:36We'll pass in a string for the title which is going to be PAUSED, and on the
02:41next line we will run addButtonWithText.
02:43so popup->addButtonWithText(), now we need to pass in the text for the button
02:49which is going to be RESUME.
02:51Target is this, selector is menu_ selector and then we pass in the method we want
02:58to run, that's going to be Pause::resume.
03:00Then on the next line we will do the same thing, so I am going to copy and paste
03:05the previous line of code and change the text to MAIN to go the Main Menu, and
03:10the method that I want to run is Pause::mainMenu.
03:13Now you may wonder why I don't just run MainMenu, mainMenu since that already
03:19exists to take us to the Main menu.
03:21That's because we are running an instance method here.
03:24We pass in this and that grabs the target and it runs a selector on the
03:29target, which is mainMenu.
03:30I will show you how I chose to work that below here.
03:33On the next line of code, add the popup as a child.
03:36So this->addChild, pass in the popup, z of 1.
03:41Remember you can share z values, it just puts the objects you add later in front
03:47of the earlier added objects.
03:49So in Pause::pause, I am going to run this->togglePause, pass in true and then
03:57we will just copy and paste this into resume, pass in false.
04:01In mainMenu we will run MainMenu::mainMenu.
04:03Then we'll return to the MainMenu and in togglePause we will show the popup.
04:09It's popup->show, remember we need to pass in whether or not to show or hide the
04:15pop-up, so we just pass in that pause parameter. And if we want the game to
04:18pause, then we will show the popup, if not we won't show it.
04:22So the next line, Utils::gameLayer(), then we are going to setTouchEnabled to
04:29the opposite of paused, so !paused.
04:33So that way if we paused the game, then Touch is disabled in the gameLayer and
04:37if we unpause the game then touch is enabled again.
04:40Go to the next line, and we are going to hide the pause button based on
04:44whether the game is paused.
04:46Pause Button->setVisible and we will pass in !paused.
04:50So again if the game is paused, we want to hide the pause button, and if the
04:55game is resuming we want to show the pause button.
04:57So let's Save and test this out in the emulator.
05:00Okay, I will click the Play button and then I should be able to pause the game
05:04when I click the Pause button.
05:06(music playing)
05:07So the music stops as specified in the popup class, I can chose to resume the
05:12game or go to the Main Menu.
05:13(music playing)
05:14I resume and the animation continues.
05:17I can pause again that I can go to the main menu and there we are.
05:21So now if you ever want to pause your game, make sure to setTouchEnabled to
05:24false in the gameLayer and then you can use this popup class or create one of
05:28your own and use the similar method to stop audio and to pause the scheduler
05:35and actions.
Collapse this transcript
Displaying the game-over screen
00:00Now we'll create a way to lose the game by getting a game over.
00:04Go over to the HUD class, into the missedMole method, and remember that code
00:08that we said would be the game over code, that's if carrotsLeft <= 0.
00:14So that's where we'll start and here what we want to do is reference a GameOver
00:18object, that's the GameOver layer and we can get it to Utils::layerWithTag, and
00:24we will pass in TAG_GAMEOVER.
00:27Now of course we'll have to typecast this because this is just going to return CCLayer.
00:31So we'll typecast it to a GameOver object and then go to the next level and
00:36then run go->gameover.
00:39I'll Save this file and go over to GameOver.h just to take a look at the existing code.
00:45So we have a Popup property and this actually looks pretty similar to the Pause class.
00:50So I'm going to open up Pause.cpp and I'm just going to copy the four lines of
00:56code where we create the popup.
00:58I'll close that file and go back over to GameOver.cpp, double tapping the tab to
01:04expand the area and inside the init method I'll paste that code.
01:10Change the title to GAME OVER, change the first button to REPLAY and the method
01:17to GameOver::replay, and will leave MAIN same for the text, and then change the
01:24method to GameOver::mainMenu.
01:27So in replay, we'll change the scene by using
01:30CCDirector::sharedDirector()-> replaceScene and then we need to pass in a new
01:36scene which we can grab from Game::scene method.
01:40So that's just going to create a new instance of the game and change the scene
01:44so we can start the game over again simply by re-creating the game scene. And
01:49that's what we're doing here.
01:50So the mainMenu method is just going to be like the pause one, so just
01:54MainMenu::mainMenu and then game over.
01:58All we're going to do is run popup->show.
02:01We will pass in true to show the screen, and that's really all there is to it.
02:06So now we should be able to save and test the game, and when we get a game over
02:10or after all the carrots are gone, the popup should show up and should ask us if
02:15we want to the play the game again or go to the main menu.
02:18So I'll click to play the game and purposely get a game over to watch the screen popup.
02:23(music playing)
02:26And there is the Game Over screen.
02:33Now remember that this is the emulator and so when you see the moles animations
02:38not finishing, that's an emulator bug.
02:41If you test it on device you should not see that.
02:44So I can click Replay and I can play the game again and I'll lose again and if I
02:49click Main I can go to the Main menu.
02:51(music playing)
02:59Now I'll click Main and return to the Main Menu and it's working.
03:03So again, if you want to show that popup screen, you can use the Popup class, and
03:07you can always change the scene using the director's replace scene method.
Collapse this transcript
Saving the player's high score
00:00In your games you can save the player's high score to increase the gameplay value.
00:05So we'll start doing that in Constants.h by defining a new key value called HIGH_SCORE.
00:13The value I'll give to it is just the string highscore.
00:16Save this and go into HUD. cpp into the missedMole method.
00:20In missedMole find the area that checks to see if carrotsLeft <= 0.
00:25Remember, this means that there's a GameOver.
00:26When the game is over we're going to see if the player's score is greater than
00:31the saved high score.
00:33You can access saved values using CCUserDefault.
00:37These values can be integers, strings, Boolean etc.
00:42You can look it up in the Cocos2d documentation if you like to know more
00:46information about the specifics.
00:47So we can access it by the Singleton CCUserDefault::sharedUserDefault().
00:51Then we can run the method getIntegerForKey, and the key is HIGH_SCORE.
00:59And now if the score is greater than the saved high score then we want to set
01:03the saved value to the new value.
01:06So I'll paste that inside of the if statement and change getIntegerForKey in
01:11this pasted code to setIntegerForKey.
01:14After HIGH_SCORE send in the second parameter score, so we'll save that integer
01:20for the HIGH_SCORE key.
01:21Now we'll scroll up and copy the code in the init method that sets the value of scoreLabel.
01:28Save HUD, go to the MainMenu class and right under where we create the
01:33background object I'm going to paste the code I just copied.
01:36Here we just make a few modifications and then the high score label will show
01:42when we play the game.
01:43So we don't already have a variable called score label, so I'll just need to
01:47make sure to define this.
01:48So right before we set the scoreLabel=CCLabelTTF, just make sure you define that as a CCLabel.
01:55So I have CCLabelTTF *scoreLabel and then instead of zero for the string I
02:01am going to change that to CCString:: createWithFormat, and I want a string that says HIGH:
02:06and then the high score. So HIGH:
02:09%d for digit, and then after the string I'm going to pass in
02:15CCUserDefault::sharedUserDefault-> getIntegerForKey and then pass in HIGH_SCORE.
02:25And then outside of the closed parentheses for createWithFormat, make sure
02:29you call getCString.
02:30Now the other values that create using the Toonish font from that constant value
02:37and the size, those are the still good.
02:39So we'll just go down to the next lines and we don't have padding defined, so
02:44I'll just change those two padding values to 10 each.
02:48And then I'm going to change the Z position instead of 1 to 10, and that's it.
02:52I can Save and test and when I check out this app in the emulator, you should
02:57see that it says High:
02:580 in the top left of the Main menu, and when you play the game and lose after
03:03you've scored a few points, when you return to the Main menu you should see
03:07that your new high scores reflected there and that saves even after you exit the game.
03:11So now if you save and test the app you can see that there it says High:0 at the
03:16top left and you play the game and score a few points and lose,
03:19(music playing)
03:22so I will just score a point or two and then die, and then when I lose I can
03:29go back to the Main Menu and my high score, which is currently 2, you'll see up there.
03:35So if I beat that and say I get three the next time I play it, then it should
03:39say High of three and so on.
03:41So remember, if you need to save any kind of data, what you're going to use is
03:46the CCUserDefault class.
03:49So you can do things like set and get integers, Boolean and strings, and again,
03:55you can find more information about that in the Cocos2d documentation.
Collapse this transcript
5. Placing Ads in Your Game
Preparing your game to support Google ads
00:00Ads are an excellent and easy way to make some revenue for your free apps.
00:05Of course you can even put ads in a paid app.
00:10To set up Google ads, go to developers.google.com/mobile-ads-sdk.
00:15Here you'll see the basic steps to implementing Google ads in your Android game.
00:21If you scroll down to How do I start?
00:23You will see that you first have to sign up as an AdMob publisher.
00:27So you can click that link if you're not already an AdMob publisher, sign up,
00:31and then you'll have to create an app, and we'll look at that in just a minute.
00:36And the next step is to download the SDK.
00:39So we're actually going to scroll up and then click SDK Downloads on left side
00:42of the page, and you'll see the GoogleAdMobAdsSdkAndroid.zip file.
00:46So if you download that, you are going to find a JAR file in there, and that's
00:51the file that you'll need to implement the Google ads.
00:54If you keep clicking the links here, you'll see more information about how to
00:58implement the ads into your apps.
01:01If you click the AdMob link and then Banner Ads 1, this is the type of ad
01:05we're going to use.
01:06And it explains how to implement the ad in either Java or XML.
01:12We're going to do the XML version here, and here's some sample code that
01:15explains how to do it.
01:17I am going to go over to AdMob now to show you what that looks like.
01:21Once you've created an app in AdMob, you can go to the app, in your Sites & Apps
01:26section, and find your Publisher ID.
01:29That's the number that you're going to need in AdMob when you create your ads.
01:33So make sure to copy that and we'll use it later.
01:37Now, let's go over to Eclipse.
01:39In Eclipse, to import the GoogleAds. jar, I change the file name, so that it
01:44doesn't have the version on it anymore, and I drag that onto the libs
01:49folder, and choose Copy.
01:52Note that if this method is giving you any kind of trouble, you can go to your
01:55Project>Properties>Java Build Path and add this file as an external JAR.
02:00I also had to use the Android API level 13.
02:06So, to do that, I went to my apps Properties, and under Java Build Path, I went
02:12to Libraries and I removed the previous Android version that I had and then I
02:18hit Add External JARs.
02:21And then I found the JAR file for Android level 13 that's inside of your Android
02:26SDKs folder in the platforms subfolder.
02:30So remove that, and replace that with Android API level 13 or you can always go
02:35into your Android properties through Project>Properties and change the API level there.
02:41And then you'll also have to go into all of these ant.properties,
02:45local.properties, and project.properties and just add this line of code at the bottom;
02:50target=android-13 and I put that in each of those files.
02:55And there it is in project.properties.
02:57So once you've set your target to be Android 13, and you've implemented the
03:02Android API level 13 and you've linked the GoogleAdMobAddsSdk.jar file, you're
03:09ready to start writing the code to add Google ads into your apps.
Collapse this transcript
Implementing Google ads in your game
00:00The code for implementing Google ads is fairly simple, but there is a lot of it.
00:05So I chose to have it prewritten for this exercise.
00:08You'll need to start by creating a file called main.xml inside of the Resources
00:13folder, in the Layout subfolder. So there it is!
00:16I'm going to expand that file now so it fills the whole view.
00:20Here, most of this code is copied and pasted from Google.
00:23If you look up their XML example, you'll see that the code is already
00:27written for you here.
00:28Of course, you'll need to replace MY_AD _UNIT_ID with your actual publisher ID
00:34that we looked at in the last movie.
00:36And the big difference here is that we're wrapping our OpenGL view in a RelativeLayout.
00:43This GL view now is going to be set through XML as well, so we'll need to make a
00:48change to moleit.java.
00:49So I have it declared here, then I have my ad view, and then I've replaced my adUnitId.
00:54For testDevices, I just have TEST_ EMULATOR, so it should work in the Emulator,
00:58and then I'll go to the manifest.
01:01Now, we've changed the manifest a little bit.
01:03One thing I've added that you could copy and paste from Google if you don't have
01:06access to the Exercise Files is this activity under the main moleit activity,
01:12that's the com.google.ads.AdActivity.
01:15So again, if you look in the Google tutorial, you'll see this block of code and
01:19just paste it right in.
01:21Also, you'll need to add some permissions including the ACCESS_NETWORK_STATE and
01:27that INTERNET permission.
01:29You can do that by going to the Permissions Tab and then hitting Add, and then
01:32just hit Uses Permission, and just select it in the dropdown menu.
01:37So again, that's ACCESS_ NETWORK_STATE and INTERNET.
01:41So just remove that permission I just added, save the file and go back to
01:45moleitx.java, and now here I've declared an adView.
01:48And of course you'll need to import the adView class, and then I've commented
01:53out this huge block here to change the GL code to use the XML layout.
02:00So, we set the ContentView to R. layout.main, that's that main XML file.
02:04And then I set the value of the GL view based on the XML file, and I'm still
02:10setting these two values here, then I reference the adView, set it to be
02:15Visible, and tell it to load an ad. And that's it!
02:18Now, when you test it in the Emulator, here's what you should get.
02:22Now, see how I have this ad at the bottom, and note that I just struck the Play
02:26button down a little bit to accommodate the ad space.
02:29Now, I had a problem that I spent hours looking up, and I don't want you to do the same thing.
02:35In my logcat, I could see that ads were loading in, but I did not see them on the screen.
02:41And I looked it up online and a lot of people said it takes about two minutes
02:45for the ads to load.
02:46For me, it actually took about two hours.
02:48So, if you don't see an ad on here, try testing it on your device.
02:53And for me, on the device it came up right away, but in the emulator, it took
02:57hours for an ad to appear.
02:59So, I wouldn't count on that.
03:01I would definitely be testing on a device for this.
03:04If you see this test ad, you can click it.
03:06But remember, don't click any ads on your device if they are real ads; that is,
03:10ads for some kind of product or something, not just from Google, because
03:14Google's policies could possibly ban you from ever using Google ads again if you
03:19click on your own ad, so definitely don't do that.
03:22So just remember when you're configuring your ad view that you'll need to
03:26update that main XML file and add the adView, update your manifest with the
03:32appropriate permissions, and the ad view and then update your main activity
03:36file to add the adView as well.
Collapse this transcript
6. Adding In-App Purchases
Handling skins in your game code
00:00Now we are going to look at how to add in-app purchases to your games.
00:04We'll look at how to do that through both Amazon Appstore and through Google Play.
00:08The purchase I chose to implement is an artwork change called the skin.
00:13To see what that looks like, I'm going to click SKINS at the title screen
00:16and I'll click ALIENS.
00:19This is going to change all of the graphics for the game, that when I play it
00:23I'll hear the music, see the artwork and animations and all the menu buttons
00:29that are associated with that different skin graphic.
00:32I'll go back to the Main Menu now.
00:33Now I understand that not all of you're going to choose to use a skin as your
00:38in-app purchase, so I pre-wrote all of this code and I am going to show you how
00:43I did it in the event that you want to implement that in your own game.
00:47Let's look at the code I've written and we'll start and Utils.ccp.
00:50Here I have a static character constant called currentSkin and I set that
00:55equal to SKIN_MOLES.
00:57And that's just a constant value that I added to Constants.h. You can see that
01:02if I open that file up in Classes.
01:05So I have that in-app purchase code for the Jetpack handyman skin, I have
01:09SKIN_MOLES and SKIN_JETPACK;
01:12I've also added TAG_SKINS to Constants.h. So I'll go back to Utils and so we're
01:19initializing the current skin.
01:20At the bottom of added getters and setters for that value, very simple and that
01:25I created another one called getFullName.
01:27What this does is it creates a formatted string that puts the currentSkin in
01:32front of the suffix that's passed in.
01:35So we can use this for all different file types.
01:37Let's go over to Skins.cpp.
01:40This is a lot like the pause menu or the game over menu, it's really simple.
01:44I created a button that says MOLES and a buttons that says ALIENS.
01:48In the show method, instead of calling popup show I just call popup->setVisible,
01:53just because the skin screen is always going to be run from the Main Menu so I
01:57just need to show the popup; I don't need to pause the schedule or anything.
02:01And then I have set MoleSkin which sets the skin and then mainMenu reloads the Main Menu.
02:07Now that's significant, we'll look at that in just a second.
02:09setAlienSkin is the same thing, but what I've commented out here that I will
02:14uncomment after this movie, is I'm checking to see if the user default is set
02:20for that in-app purchase.
02:21So, what I do when I buy the item after its confirmed purchase, then I set that
02:27bool for that in-app purchased value to true.
02:30So that way I know that it's been purchased and if that's not true, then I run
02:34the code to buy the item.
02:36Now again buyItem and everything else related to the in-app purchase we're going
02:40to look at in detail later on.
02:42Let's go to MainMenu and see how we handle changing the skin there.
02:46I added a significant line of code here, where I purge the
02:50SharedSpriteFrameCache.
02:53That means we get rid of all the sprite frames held in the cache and then I run
02:57sprite frames with file.
02:59You'll notice for the sounds that I'm preloading that I'm using
03:03the Utils::getFullName.
03:04So that's going to put the skin name in front of _bg.mp3 etcetera.
03:11So I've used that for all of my file names that contain skin relative names.
03:16You'll see that I've added the skin in the scene method, so I created the skins
03:20object and then added it as a child of the main scene, just like what we did
03:25with our game. And then at the bottom I have a method that runs called showSkins,
03:30that runs when you hit the SKINS button from the Main Menu and it just calls the
03:34show method of skins.
03:35Let's go over to Game.ccp.
03:37And here all I did differently was I found anywhere that referenced anything
03:42that had the word moles in it and then I ran Utils get file name, change the
03:47value based on the skin.
03:49Now in case it's not obvious, you're actually going to have to have a set of
03:54artwork in audio files with different names that match your skin if you're going
03:58to use the same technique.
03:59So if you don't have access to the Exercise Files, you'll need to create
04:03Jetpack_bg.mp3, etcetera.
04:07So I created another sprite sheet with all different sprites in there, but I
04:12named the sprites the same so that they would apply to both, and I just named the
04:16file for the sprite sheets differently.
04:18So you'll see that all across my cover I'm running Utils::getFullName I did the
04:23same thing in the HUD, so when I run the miss sound I'm playing the
04:27Utils::getFullName miss and that's about it.
04:30So again, if you want to add a custom skin, create some way that you can
04:35efficiently swap out parts of a file name to include different artwork or sound effects.
04:41And then just make sure for the artwork that you're purging the shared sprite
04:45frame cash before you load the new sprites.
04:48And then you can reload the Main Menu scene and those new sprite frames will be
04:53loaded in and applied.
Collapse this transcript
Setting up in-app purchases (IAP) for an Amazon Appstore app
00:00To create an in-app purchase for Amazon App Store app you'll of course first
00:05need at Amazon App Store account.
00:08You can get that by going to developer.amazon.com.
00:12Then you'll need to create an app using that add new app button and in your app
00:16you'll need to create an in-app purchase to the In-App Items area.
00:20Here you'll see I have one called Jetpack Handyman Skin. The identifier that you
00:24are going to be using in your code to reference the purchase is this one here so
00:29now is a good time to copy that and for the type I chose Entitlement that's a
00:34one time purchase that you unlock something.
00:37Once you setup your in-app purchase, you can get the SDK to the SDK link hit
00:42Download SDK and here you'll find a getting started with in-app purchasing
00:47API which you should definitely look at if you're serious about doing in-app purchases.
00:51You can find some extra information there.
00:54Let's go over to the desktop here.
00:56In the SDK file that you download, you'll see a folder called In-App-Purchasing
01:00and folder in their called lib and there is a jar file.
01:04You can just drag that into your libs folder in your Eclipse project to add
01:08it to your project.
01:09Remember it choose copies so it copies in your project.
01:12You are also going to need some files in the tools folder.
01:17This Jason files needs to be edited to reflect your specific In-App Purchase.
01:21I'll open that in a text editor.
01:23So here is a description of how to use it of course I'll need to uncommon
01:27everything, and when you use this you put a whole list of them like I have here,
01:32make sure you use the same SKU here and then if you have one rapid in some
01:38curly braces like that.
01:40And then delete everything in the file that you don't need.
01:43So once you've created you're as to look something like that.
01:47So once you've created that you're going to need to copy that file into the SD
01:52Card directory of your android device.
01:54That could be in a different place for each device the one I used was a
01:58candle fire and that was actually in the root directory when I plugged it into my computer.
02:03So copy that into your SD card folder and then you're going to need to install
02:07the Amazon SDK tester app.
02:09Or I did to install that is I copy the file into my android SDK platform tools.
02:17So we see here AmazonSDKTester.apk. The reason I copied back in there is because
02:23the adb is in there.
02:25And so I opened up a command line window, changed the directory to this platform
02:29tools directory, and I ran adb install AmazonSDKTester.apk.
02:36Now once you've installed that, you should test the app on your device just to
02:40make sure that it works.
02:42To test in-app purchases, you'll need this app running; and if you've just
02:47copied over that json file, you'll need to unmount from your computer to save that change.
02:53So once you've done all those steps, you're ready to start writing the code
02:56necessary to add Amazon In- App Purchases to your app.
Collapse this transcript
Implementing Amazon IAP code
00:00So now we'll look at the code to implementing Amazon In-App Purchases; I'm going to
00:05scroll down to my android manifest and you'll see that I have some code here
00:09starting with the receiver block.
00:11You can copy and paste this code from the Amazon in-app purchase SDK tutorial if
00:15you want and that's exactly what I did here.
00:18So we're just going to need the receiver block and then let's go to Skins.cpp.
00:23As I mentioned before, I just checked to see if that user default is true.
00:29If so, I set the skin and rerun MainMenu, if not I run buyItem.
00:35So to unlock the item all we need to do is set that user default value true.
00:39Let's look at buyItem.
00:40I'll go over to jniIAP.cpp.
00:44I added this file to the folder where all of the jni files are and all it does
00:50is it runs a static method buyItem passing in the string to in moleitx.java.
00:55Remember you have to past in the fully qualified class name here, so
01:00that's fairly simple.
01:01Here is the header file in case you'd like to see it, and moleitx.java let's
01:06scroll down to buyItem.
01:07In buyItem I used PurchasingManager. initiatePurchaseRequests passing in the item.
01:14PurchasingManager is an Amazon class.
01:17So let's scroll up and see how to handle the Amazon purchases.
01:22I created a class called my observer inside of my moleitx file and that
01:27extends BasePurchasingObserver and this is like a listener that listens for purchasing events.
01:33So in there I have a private moleitx called mainActivity.
01:37In the constructor I pass in that super and then I set mainActivity as the
01:42activity passed into the constructor.
01:44And if you want to you can override on itemDataResponse; this is when you get
01:48item data so you can display any extra information to the user should you wish.
01:54And then the method that is executed when a purchase is responded to is called
01:59onPurchaseResponse, and that gives you the information about whether the
02:03purchase was successful or unsuccessful or they already have it.
02:07So here I have a string call response and I'm getting the string from the
02:12purchaseResponse.getPurchaseRequestStatus method, so that gives me the request status.
02:18I got it as a string then I check to see if it's successful or the person
02:22already has this purchase.
02:24If so I'll run mainActivity unlockSkin.
02:27If not, I Log to see what the problem is.
02:30So it's pretty straightforward and of course you can find more information about
02:33this purchase response class inside of the documentation for the Amazon API.
02:40So let's scroll down a little bit and look at some other code that I added.
02:44The unlockSkin method runs native unlockSkin, which is a native method, which
02:50we'll look at in just the second.
02:52You'll notice that on start I create the observer, passing in this and then I
02:58tell the PurchasingManager to register the observer and in onResume I run
03:02PurchasingManager.initiateGetUserIdRequest.
03:06So let's look at native unlocks skin, that's defined in jniUnlock.cpp.
03:13For this file there is no header file.
03:15Here I am defining the Java_com_ toddparkins_moleitx_moleitx_nativeUnlocksSkin
03:21with just the basic parameters.
03:23And then I just run this CCUserDefault method and set that value true for the
03:27skin and that's how we unlock it.
03:30So when you test this out on your device, you should see that when you tap on
03:34the aliens, a popup window should show up, ask you to purchase the skin.
03:38If you do and the purchase is successful, if you hit ALIEN again, then it will
03:42change to the Alien Skin and that's all there is to it.
03:46So there is kind of a lot of code to implementing the Amazon In-App Purchases,
03:51but as you've seen the code is fairly simple.
03:54Once you have all this code setup, you can test the app on your device and
03:57confirm the In-App Purchases working by clicking on the ALIENS button from the
04:01skins menu and seeing that dialog popup.
04:04And when you get a successful purchase, you can close the dialog and hit ALIEN
04:09again and the skin will change.
Collapse this transcript
Setting up IAP for Google Play
00:00Adding In-App Purchases through Google Play is a somewhat complex process.
00:05The Google sample code is thousands of lines of code for you to add a
00:09custom implementation.
00:11If you're looking for something as easy as implementing an Amazon In-app
00:14Purchase, you can use the AndroidBillingLibrary from robotmedia.
00:19You can find this project at GitHub.
00:21This code simplifies Google Play In-App Purchases to reduce them down to 20 or
00:2630 lines of code that you can mostly copy and paste.
00:30So you can download the ZIP file here, and you can see the implementation
00:34is fairly simple, and you're going to need to copy and paste this code
00:38inside of your Manifest.
00:39So you can do that now, and then we're going to use the
00:43BillingController implementation.
00:44You will also need some information from the Android Developer Console.
00:49From the Android Developer Console, click Edit Profile.
00:53From here, scroll down and copy your Public Key as well, or you can just leave
00:58this page open for later, and paste it in when it's necessary.
01:01Let's go over to Eclipse.
01:03In Eclipse, I am going to open up my AndroidManifest.xml file.
01:07You'll need to add the permission com.android.vending.BILLING.
01:14Here's where I've pasted my code, the robotmedia service.
01:18And then you'll need to bring in all the code files into your Eclipse project.
01:23To do that, open up the robotmedia project, and find the AndroidBillingLibrary.
01:29In the source folder, you'll see a com folder, and a net folder.
01:32The com folder contains the Android package for the vending library.
01:36So just drag this Android folder into your com folder.
01:41Don't overwrite your com folder, or also you may lose some of your existing files.
01:46And then just drag that net folder right into the source folder for your
01:49project, and you can see that I've done that here.
01:51So inside of my source folder for my project, I have the net folder, and then
01:55in com, I have toddperkins and Android.
01:58After you've done that, jump back over to Eclipse and refresh or press F5, and
02:05you should see all of these classes imported in the source folder.
02:09If you have any warnings or errors when you do this, you can do two things;
02:14you can try cleaning your project, and you can go to Moleitx.java.
02:18And if you see a line of code that imports android.r, delete it.
02:23Sometimes that line of code gets inserted automatically by Eclipse.
02:27Now, once you've imported all these classes into Eclipse, you've updated your
02:32Android Manifest and you're ready to start writing the code to adding In-App
02:36Purchases through Google Play.
Collapse this transcript
Implementing Google Play IAP code
00:00Let's write the code to add Google Play In-App Purchases to our game.
00:04Note that most of the code we'll be looking at I actually copied and pasted from
00:09the Android Billing Library.
00:11If you open up the Dungeons folder, go into source, all the way down to all the
00:16code, and if you open up Dungeons.java, Application.java, that's where I got the sample code.
00:23So any methods that I reference here, you'll find that in there, which
00:26should be especially helpful for those of you who don't have access to the Exercise Files.
00:30So let's go into Eclipse, and first I'm going to point out that I have imported
00:36all these robotmedia classes.
00:38So you will need to do that, and then scroll down, I created a property
00:43that's an AbstractBillingObserver called mBillingObserver, scroll down into
00:48onCreate and I set BillingController to debug, and then I set the
00:52configuration for the BillingController.
00:55And here, you can copy and paste this ObfuscationSalt code, but this is a
00:59special key that should be customized in random from you.
01:04So you can go in and edit these numbers if you're going to publish your app.
01:08I just copied this from the Dungeons project, so I'm not worried about it being
01:12unique because I'm not going to publish the version that you're looking at right now.
01:15Then, I have my Public Key, and this is where you're going to need to paste in
01:19that Public Key that you've got from your Android developer account.
01:23I set the mBillingObserver = new AbstractBillingObserver, and then I am just
01:30saying that for each of these methods, I'm going to call onBillingChecked,
01:35onPurchaseStateChanged, onRequestPurchaseResponse, onSubscriptionChecked.
01:36So you'll need to implement those methods inside of this class.
01:45Register the observer, check for billing support, check for subscription
01:50support, and then I've implemented onDestroy, and in onDestroy, I unregister
01:57the BillingObserver.
01:59I'm going to scroll down, and in the buyItem method, I run BillingController,
02:03requestPurchase, passing in me, that's the instance of moleitx, and then I
02:09pass in this string.
02:10Now, if you haven't already uploaded your app and created In-App Purchase you
02:14can actually still test that it works by testing for the purchase
02:18android.test.purchased.
02:20Of course if you created an In-App Purchase for your app, you want to pass
02:24in that string here;
02:26android.test.purchased will also automatically return true.
02:30So as long as that billing service is running, then it's going to work.
02:34And then you can see how I've implemented most of these other delegate methods.
02:38I just have a log that explains what happened, I tagged it with IAP, and
02:43onRequestPurchaseResponse, I check to see if the response is equal to
02:48ResponseCode.RESULT_OK.
02:51If so, I unlock the skin.
02:53You can also define what you do when you check the billing, and when you check
02:57the subscription status.
02:58So you could see, it's not super complicated, and if you want more detailed
03:03code, you can look at the Dungeons sample and see what else you can do and
03:08what other methods you could implement to check for your In-App Purchases and to restore them.
03:13But once you have this code set up and you run it on a device that has the
03:18latest version of Google Play, you'll be able to make In-App Purchases
03:22through Google Play.
Collapse this transcript
7. Going Forward and Getting Help
Using the Cocos2d-x website
00:00It's a good idea to follow what happens on the Cocos2d-x website.
00:04The site is regularly updated and you can find information about the new
00:08updates to Cocos2D and other utilities that can make Cocos2D game development easier for you.
00:14One resource that I used a lot in particular when developing this course was the Forums.
00:20Just like any other forum, you'll find tons of useful information and
00:24conversations both from the community, and the developers and creators of Cocos2d-x.
00:29I highly recommend looking through here and searching here if you run into any
00:33problems as you're developing your games.
00:36In addition to the forums, you'll also see the Reference page.
00:40You can go to the Reference and hit Cocos2d-x Online API Documentation, and you
00:45see the documentation for all of the classes.
00:48I'll hit Classes, and then Class Index, and you can see the documentation for
00:53every class in Cocos2d-x.
00:55It's especially important to visit this regularly because as the versions
00:59of Cocos2D update, the use of a particular class or the class itself might have changed.
01:06So, throughout the Cocos2d-x website, you have many resources that will help you
01:11better develop your games.
Collapse this transcript
Viewing additional Android game development resources
00:00After you've made the game we made in this course, you may be interested in learning
00:04more about game design and creating your own commercial games.
00:09There are some obvious places to look, like web searches.
00:13In developing six commercial games, I have yet to find a problem that
00:16somebody else didn't have.
00:18If something doesn't work, paste your error code into a search engine and find
00:23out what other people have had the same problem.
00:26If you don't see the problem for Cocos2d-x and it's related to a class use or
00:30something with the Cocos2d framework, just look at regular Cocos2d-x and see if
00:35you can translate the code into C++.
00:38The Objective C language is not incredibly different from C++, seeing as it's
00:43in the same C family.
00:45So you may be able to find your solutions in that way.
00:48Here's another resource that I found particularly useful.
00:51The website is emanueleferonato.com.
00:54This is perhaps the best resource for learning how to develop games that I've
00:59found anywhere on the web.
01:01If you look at the different articles, you'll see that most of them are related
01:05to Flash and ActionScript.
01:06But there are over 500 articles related to game design.
01:10So, if you click that link, you can find a bunch of information about how to develop a game.
01:16This website finds games that exist that are popular and explains how to
01:20build those game engines.
01:22So through that, you can learn how to think like a game developer and how to
01:26plan and program different types of apps and venture beyond what we created in this course.
01:33So I encourage you to experiment, and to look at other resources on the web
01:37to find more information about game design, and if you find any yourself, let
01:42me know.
Collapse this transcript
Conclusion
Goodbye
00:00That concludes this course on how to build and monetize an Android game.
00:05I hope you've learned a lot about how to use a Cocoas2d-x framework to build
00:10a game for Android.
00:12Remember, there are many resources out there to advance your game
00:15development skills.
00:16And like I said, if you find anything interesting that you'd like to share, you
00:20have any questions about the course, or if you make a game using this
00:24framework, I want to know.
00:26You can find me on Twitter, @asktodd.
00:28I'll see you next time!
Collapse this transcript


Suggested courses to watch next:


Online Marketing Fundamentals (1h 47m)
Lorrie Thomas Ross

Java Essential Training (7h 17m)
David Gassner


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,069 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,024 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