チュートリアルiOS Programming 101の生徒の一人Shawn Grimesからモグラたたきゲームのチュートリアルを作成してほしいとの提案がありました。
「そりゃ、良いアイデアじゃないか」ってことで、このチュートリアルを作成したわけですが、他にも理由があるんです。理由は3つ:
- このサイトにはCocos2Dを使用するチュートリアルがたくさんありますが、それらを束ねて実際に一つのゲームを作成するにのはやっぱり大変ですよね。このチュートリアルはまさしく、そんな貴方の為に作成しました。
- 新しいトピックをカバーするのに、とても良い機会だと思ったんです:iPnone、iPad、そしてiPhone-Ratinaディスプレイに対応するゲームの作成方法。
- そして何よりも、モグラたたきは楽しいという事!
このチュートリアルは以下のチュートリアルを基に作成されています:
- Cocos2Dでシンプルなゲームの作成チュートリアル,
- Cocos2Dでスプライトシートとアニメーションの使用チュートリアル
- Cocos2DでTexture PackerとPixel Formatでスプライトシートの作成チュートリアル
- Cocos2D でスプライトをドラッグ&ドロップする方法
上記のチュートリアルをまだご覧になっていない方は、まずこれらのチュートリアルで勉強される事を強くお勧めします。
このCocos2Dのチュートリアル・シリーズは全2章で構成されています。このパート1は、穴から飛び出してくるモグラの基本的なゲームを作成します。iPnone、iPad、そしてiPhone-Ratinaディスプレイ用にイメージを効率的に対応させる方法をしっかりと勉強していきましょう。 (パート2へジャンプ)
イメージの作成:概要
今回のこのアプリをiPnone、iPad、そしてiPhone-Ratinaディスプレイ用と、これらの3種類に対応させるには、まず始めに、作成するイメージをどのように設定するのかをしっかりと考えなくてはなりません。
イメージの適切なサイズ設定を理解するには、まず以下の3つのトピックをカバーする必要があります:
- Retina ディスプレイ と UIKit
- Retina ディスプレイ と Cocos2D
- iPad, iPhone, と アスペクト比
それでは始めましょう!
Retina ディスプレイ と UIKit
iPhoneと iPhone(Retina ディスプレイ)との違いはRetina ディスプレイが2倍のピクセルを表示出来る事です。iPhone(横画面(landscapeモード))でのサイズは480×320 ピクセルで、Retina ディスプレイならば960×640ピクセルとなります。
「でも、ちょっと待って下さい!」「ピクセル数を2倍にしてしまったら、ディスプレイサイズを480×320と設定しているアプリはダメになっちゃうんじゃないんですか?」はい確かに。でもUIKitでピクセルで設定していれば大丈夫です。
iPhone(non-Retina)では1ポイントは1ピクセルで定義されています。でもiPhone(Retina)では1ポイントは2ピクセルとなっています。ですから座標が(10,10)ポイントなら、iPhone(non-Retina)では(10,10)でiPhone(Retina)では(20,20)となります。そうすると、スクリーン上ではiPhone(non-Retina)とiPhone(Retina)で同じ場所表示されます。
簡単でしょ?
Core Graphics等ではRetinaディスプレイに対応させる為に予めコードが書かれています。
気をつけなくてはならない時は、イメージを使用する時です。あるiPhoneのイメージのサイズが200×200だったとします。何も設定しなければ、Rerinaディスプレイの場合、イメージが2倍に引き延ばされ、画質が明らかに低下してしまします。しかしもちろん、Ratinaディスプレイにはこういった解像度の問題を解決する為の機能が追加されています。
つまり、全てのイメージの別バージョンを作成すれば良いんです。通常サイズのイメージと、2倍のサイズのイメージを用意します。そして、2倍のサイズのイメージには”@2x”を拡張子としてイメージ名の末尾に付けます。そうすると、[UIImage imageNamed:...]等のようにイメージを読み込む際、2@xの拡張子を持ったイメージをRetinaディスプレイ用に自動的に選択してくれます。
はい、このようにUIKitアプリでのRetinaディスプレイ対応は簡単ですね。@2xイメージを追加して終わりです。
じゃあ、Cocos2Dはどうでしょうか?
RetinaディスプレイとCocos2D
ところで、いいニュースがあります!最新のCocos2DはRetinaディスプレイをさサポートしているので、設定がとても簡単になりました!
- Retinaディスプレイに対応させる為、アプリ起動時にCCDirectorのenableRetinaDisplayをYesにします。Cocos2Dテンプレートで作成する時はappDelegateでその行をアンコメントすれば良いだけとなっています。
- それでは2倍のサイズのスプライトを追加して、拡張子を”@2x”の代わりに、”-hd”を拡張子として付けます。これで、Retinaディスプレイ用に自動的に”-hd”の拡張子を持ったイメージを選択してくれます。
- そして、Cocos2Dでスプライトの配置をする時はピクセルではなくポイント(point)を使います。
とても大事な事なんですが、最も簡単な方法としては、アーティストがイメージを用意する時、まず2倍のサイズ(Retina)用を作成させて、それから(non-Retina)をスケールダウンします。
「じゃあなんで、わざわざ2種類のイメージを用意しなきゃいけないんですか?」「常に2倍のサイズを読み込ませてプログラムで縮小すれば良いんじゃないんですか?」アプリの作成に於いてイメージ読み込み時のメモリ管理は最も大変な事の1つで、メモリの消費は出来るだけ最小限に抑える必要があります。
でも、安心して下さい。毎回毎回Photoshopでイメージを縮小する必要はありません。”Texture Packer”を使えばイメージのスケールダウンが簡単に出来ます。よって、今回のチュートリアルでは”Texture Packer”を使います。
iPad, iPhone, と アスペクト比
OK、iPhoneのRetinaディスプレイ対応が簡単な事は分かりました。じゃあ、iPadはどうなるんですか?
それが、ゲームを作成する上で、 iPadと iPhone両方に対応させることは、ちょっと厄介なんですよ。
iPhone は 480×320 、もしくは960×640。アスペクト比は1.5。でも、iPadは768×1024。アスペクト比は1.33.
つまり、iPad(768×1024)の背景イメージ用のイメージがあったとして、iPhoneでもそのイメージを再利用したい時は、、、えっと、、、うまくフィットしません。iPhoneの幅サイズに合う様に縮小した場合、(720×960)となり両端に余分なスペースが表示されてしまいます。
このことが、事を面倒臭くしているんですね。しかも背景イメージの事だけではありません。アスペクト比も同じ座標を使用する事を困難にしています。
この問題を解決する方法は、幾つかあります:
- ゲームに於けるメインの画面をiPhone(Retina)(640×960)に設定しスクリーンの真ん中に配置。そうすると、メイン画面の外の範囲に若干のスペースが空くことになるので、このスペースを背景等のイメージでカバーしてやれば、プレーヤーにとっても気にはならないはずです。この方法を使えば、異なったデバイス同士にも対応出来、この方法を今回のチュートリアルではお見せします。
- iPadをiPhoneのアスペクト比に近づける方法。iPadのスクリーンのそれぞれの端から42ピクセルずつ切り取って、ゲームのメイン画面を684×1024の中に納めます。そこから、スケールダウンしてそれぞれのiPhoneのスクリーンに対応。
- それぞれの違った種類のデバイス毎にイメージを用意する方法(iPhone、iPhone(Retina)、iPad用のイメージを3種類用意する)。違ったデバイス対応のいくつかの方法の中で、一番柔軟性があります。しかし、バイナリサイズが大きくなる事と、デバイス毎のオブジェクトの配置を変えなければいけません。
Cocos2Dは現時点では、この問題に関してiPad用のサポートはありません。故に上記の幾つかの方法のどれを選択するかは、もちろん貴方次第というわけです。
イメージの作成:結論
はいそれではここまでの解説を基に、今回のチュートリアルのプランです。
- ゲームのメイン画面のイメージは960×640の中に納め、iPhone (Retina)用に作成し、iPadスクリーンの中心に配置。
- それぞれのイメージは”Texture Packer”でiPhone(non-Retina)用に(2/1)に縮小したものも同様に用意する。
- 2倍のサイズのイメージに”-hd”の拡張子を付け、後はCocos2Dが自動的に判別してくれる。
- 背景のイメージは常にスクリーンいっぱいに表示されるべきなので、特別なケースです。背景のイメージサイズはiPad用のサイズ(1024×768)に設定してスクリーン全体をカバー。このサイズのイメージはiPhone(Retina)用にも使えます。確かにアスペクト比が違うため、iPnoneの場合背景の周りの部分はいくらかスクリーン外にはみ出る事になるが、この事を念頭に置いてオメージを作成すれば良いわけです。
- iPadバージョンでは”-hd”を付ける事で、座標をメイン画面用に変換し適切なフォントを使いましょう。
それではこちらからラブリーワイフ作のイメージ・リソースをダウンロードしてファイルを解凍して中を確認して下さい:
- “foreground”フォルダの中で、foregroundは1024×768(iPadのサイズ)ですが、実際は2つのパーツに分かれています。:下半分のパーツと上半分のパーツです。イメージを上下半分ずつに分けて、その間にモグラのイメージを挟み、あたかもモグラが下半分の地面から飛び出してくるかのような演出が可能となります。
- “background”フォルダの中には、iPad用のアスペクト比1.33のイメージが含まれています。しかしこの背景イメージのサイズは(512×384)です。何故かというと、三つのモグラの穴を通してしか、この背景は見えませんから、1024×1024のサイズのように重くする必要がないからです。つまり小さなサイズのイメージを読み込んで拡大すれば良いんです。
- “sprites”フォルダの中には、画面サイズ960×640の中にうまく収まるスプライトが含まれています。このモグラのイメージには2種類のアニメーション用のイメージが含まれています。一つは笑っているモグラ、二つ目は叩かれたときのモグラのアニメーション用です。
OK!背景に関するおしゃべりはこのくらいにして、始めちゃいましょう!
さぁ、始めましょう!
それではXcodeを開いて、“FileNew Project…”を選択、そして“User Templatescocos2dcocos2d Application”を選択して”Choose…”をクリック。”プロジェクト名”Product Name”をWhackAMoleにして、”Save”をクリック。
先ほどダウンロードした”Art”フォルダをFinderを使って”WhackAMole”プロジェクトに直接追加してコピーしてください。すると以下の様に表示されるはずです:
次に”Texture Packer”がインストールされている事を確認してください。もしまだインストールされていなくて使い方がわからない方は、こちらのチュートリアルにまず目を通してください。
それでは、このプロジェクトに必要なSprite SheetをTexture Packerを使って作成します。今回は全ての作業をTexture Packerのコマンドラインツールを使って行います。ですから、Texture PackerのGUIは全く使いません。
“Resources”を右クリックして、“AddNew File…”を選択、それからMac OS XOtherShell Scriptを選択して”Next”をクリック。ファイル名をPackTextures.shとして”Finish”をクリック。
そして、PackTextures.shの内容を以下と置き換えてください:
#!/bin/sh TP="/usr/local/bin/TexturePacker" if [ "${ACTION}" = "clean" ] then echo "cleaning..." rm resources/background* rm resources/foreground* rm resources/sprites* else echo "building..." ${TP} --smart-update --format cocos2d --data resources/background-hd.plist --sheet resources/background-hd.pvr.ccz --dither-fs --opt RGB565 Art/background/*.png ${TP} --smart-update --format cocos2d --data resources/background.plist --sheet resources/background.pvr.ccz --dither-fs --scale 0.5 --opt RGB565 Art/background/*.png ${TP} --smart-update --format cocos2d --data resources/foreground-hd.plist --sheet resources/foreground-hd.pvr.ccz --dither-fs-alpha --opt RGBA4444 Art/foreground/*.png ${TP} --smart-update --format cocos2d --data resources/foreground.plist --sheet resources/foreground.pvr.ccz --dither-fs-alpha --scale 0.5 --opt RGBA4444 Art/foreground/*.png ${TP} --smart-update --format cocos2d --data resources/sprites-hd.plist --sheet resources/sprites-hd.pvr.ccz --dither-fs-alpha --opt RGBA4444 Art/sprites/*.png ${TP} --smart-update --format cocos2d --data resources/sprites.plist --sheet resources/sprites.pvr.ccz --dither-fs-alpha --scale 0.5 --opt RGBA4444 Art/sprites/*.png fi exit 0
このスクリプトはTexture Packerに背景イメージのスプライトと前景イメージのスプライトを通常サイズとHDサイズの2バージョンを作成させます。
それぞれのイメージは最も効率的でメモリ消費を抑えた”pvr.ccz”フォーマットで保存されます。加えてピクセルフォーマットとデザリングオプションは出来る限りメモり消費を低く、それぞれのイメージに合わせて最適な選択をしています。
もし、Texture Packerのオプションがよくわからないという方は、ターミナルを開いてTexture Puckerをランしてください。それぞれのオプションの詳細がわかります。
続いて、このプロジェクトでコンパイル時にこのシェルスクリプトを動かす為の設定を行う必要があります。Targetsを右クリックして“AddNew Target…”を選択、“External Target”を選択して(Shell ScriptのTargetではない事に注意!)、”Next”をクリック。Targetの名前を”TexturePacker”として、”Finish”をクリック。
次にTexturePackerターゲットをダブルクリックして、以下の様に設定してください:
最後のステップは、このTargetをこのアプリに関連づける(従属物にする)設定です。TextureFunのTargetをダブルクリックして、Generalタブをクリック。”Direct Dependencies”の下の+ボタンをクリックして、上のリストから”TexturePacker”を選択。そしてAdd Targetをクリック。
それでは、アプリをコンパイルしてください。何も問題がなければ、Texture Packerのoutputに以下のようなビルド結果が表示されればOKです:
次に、Sprite Sheetとプロパティリストをプロジェクトに新しく追加します。”Resources”を右クリックして、“AddExisting Files…”を選択。Resourcesからbackground、foreground、そしてspriteファイル (計12ファイル)を選択して、”Add”をクリック。そして再び”Add”をクリックしてください。完了したら以下の様になるはずです:
お望みなら、どれでも.pvr.cczのファイルをダブルクリックして中を確認してください。これはTexture Packerの新しい機能です。簡単でしょ!
背景の設定
続いて、”HelloWorldScene.m”を開いて”init”メソッドを確認してください。”Hello World ラベル”を作成する為の4行を以下の行に置き換えてください:
// Determine names of sprite sheets and plists to load NSString *bgSheet = @"background.pvr.ccz"; NSString *bgPlist = @"background.plist"; NSString *fgSheet = @"foreground.pvr.ccz"; NSString *fgPlist = @"foreground.plist"; NSString *sSheet = @"sprites.pvr.ccz"; NSString *sPlist = @"sprites.plist"; if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { bgSheet = @"background-hd.pvr.ccz"; bgPlist = @"background-hd.plist"; fgSheet = @"foreground-hd.pvr.ccz"; fgPlist = @"foreground-hd.plist"; sSheet = @"sprites-hd.pvr.ccz"; sPlist = @"sprites-hd.plist"; } // Load background and foreground [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:bgPlist]; [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:fgPlist]; // Add background CGSize winSize = [CCDirector sharedDirector].winSize; CCSprite *dirt = [CCSprite spriteWithSpriteFrameName:@"bg_dirt.png"]; dirt.scale = 2.0; dirt.position = ccp(winSize.width/2, winSize.height/2); [self addChild:dirt z:-2]; // Add foreground CCSprite *lower = [CCSprite spriteWithSpriteFrameName:@"grass_lower.png"]; lower.anchorPoint = ccp(0.5, 1); lower.position = ccp(winSize.width/2, winSize.height/2); [self addChild:lower z:1]; CCSprite *upper = [CCSprite spriteWithSpriteFrameName:@"grass_upper.png"]; upper.anchorPoint = ccp(0.5, 0); upper.position = ccp(winSize.width/2, winSize.height/2); [self addChild:upper z:-1]; // Add more here later... |
OK、このセクションはセクションごとに解説して行きましょう。
- 読み込むSprite Sheetとplistの名前を決定このセクションではTexture Packerで作成された、Sprite Sheetとplistの名前をリストしています。iPhoneのCocos2DではRetinaディスプレイ対応かどうかで、通常バージョンと”-hd”バージョンを自動的に判別します。しかし、iPadはそのように設定していなければ”-hd”バージョンは読み込みませんから、もし、デバイスがiPadならば”-hd”バージョンを使うように設定します。
- 背景と前景の読み込み 次のステップは背景と前景それぞれをsprite frame cacheに読み込んで後で使える様にします。これらのスプライトはそれぞれ一度しか使われない為、CCSpriteBachNodeには追加されない事に注意してください。
- 背景の追加この背景のイメージはレイヤーのchildとして追加されます。このイメージは予め小さく作られ、スクリーンの真ん中に配置して、2倍に拡大されています。
- 前景の追加 前景は2カ所に追加します。この場合一番簡単な方法は、上半分のイメージのアンカーポイントを真ん中下に設定して、下半分のイメージでは真ん中上に設定し、2つのアンカーポイントをスクリーンの中心に合わせる様に配置します。これには難しい計算等は必要なく、上記の様に設定すると全てのデバイスに対応してくれます。背景のイメージはiPhoneの場合、部分的に画面からはみ出る事になる事に注意して下さい、しかしこのイメージはほとんど気付かれないイメージなので構いません。加えてそれぞれのイメージにz値が設定されている事にも注目して下さい。
それでは、コンパイル&ランして下さい。スクリーンに背景と前景が表示されましたね。他のデバイスのシュミレータでも試してちゃんと表示される事を確認して下さい。
もしRetinaディスプレイでスクリーンを拡大してみると、まだ通常の画像が使用されている事に気付くでしょう:
理由は、先ほど解説したステップ1の“RetinaディスプレイとCocos2D”でアプリが起動した時に呼び出されるRetinaディスプレイのサポートをONにしていないからです。
方法はWhackAMoleAppDelegate.mを開いて、applicationDidFinishLaunchingの中の以下の3行をアンコメントして下さい:
if( ! [director enableRetinaDisplay:YES] ) CCLOG(@"Retina Display Not supported"); |
コンパイル&ランして下さい。これで自動的にHDファイルが判別されRetinaディスプレイ対応になりました。
モグラの配置
このゲームではシーンに3匹のモグラを配置します。それぞれの穴に1匹ずつです。普段モグラは下半分の前景イメージの背後に配置されていて、飛び出してきて、それを叩くと言ったイメージですね。
始めにモグラをそれぞれの穴の下に配置する為に追加しましょう。今は仮に一番前面に表示して正しい位置に配置出来ているかを確認出来る様にします。そして、配置が決まったら元の階層に戻してあげます。
HelloWorldScene.hを開いてそれぞれのモグラを格納する為に、以下の様にArrayを追加します:
// Inside @interface HelloWorld NSMutableArray *moles; |
このArrayにモグラを格納することで、それぞれのモグラをループする事が容易になります。
次に以下の様にそれぞれのモグラを配置する為のコードを”init”メソッドの”Add more here later…”の箇所へ追加して下さい:
// Load sprites CCSpriteBatchNode *spriteNode = [CCSpriteBatchNode batchNodeWithFile:sSheet]; [self addChild:spriteNode z:999]; [[CCSpriteFrameCache sharedSpriteFrameCache] addSpriteFramesWithFile:sPlist]; moles = [[NSMutableArray alloc] init]; CCSprite *mole1 = [CCSprite spriteWithSpriteFrameName:@"mole_1.png"]; mole1.position = [self convertPoint:ccp(85, 85)]; [spriteNode addChild:mole1]; [moles addObject:mole1]; CCSprite *mole2 = [CCSprite spriteWithSpriteFrameName:@"mole_1.png"]; mole2.position = [self convertPoint:ccp(240, 85)]; [spriteNode addChild:mole2]; [moles addObject:mole2]; CCSprite *mole3 = [CCSprite spriteWithSpriteFrameName:@"mole_1.png"]; mole3.position = [self convertPoint:ccp(395, 85)]; [spriteNode addChild:mole3]; [moles addObject:mole3]; |
ここではスプライトの為のCCSpriteBatchNodeを作成します。こうする事で3匹のモグラを効率的に描画してレイヤーのチャイルドとして追加します。z値を仮に999としている事に注目して下さい。こうする事でどのレイヤーよりも上に表示され、配置等の設定がOKである確認が出来ます。
次にプロパティリストからスプライトフレームを読み込みます。
続いて、それぞれのモグラの為にスプライトを作成し、シーンに配置し、モグラのリストに追加します。それぞれのモグラの配置の座標が480×320以内である事に注目して下さい。iPadの場合はこれらのポイントは変換される必要があるので、convertPointのヘルパー関数をコールする必要があります。
次のメソッドをinitメソッドのすぐ上に加えて下さい:
- (CGPoint)convertPoint:(CGPoint)point { if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { return ccp(32 + point.x*2, 64 + point.y*2); } else { return point; } } |
これはスクリーン上のメイン画面のポイントをiPad用に対応して変換してくれるメソッドです。:
- iPadではHDグラフィックを使うので、ポイントは2倍です。
- 960×640のエリアをiPadスクリーン(1024×968)の真ん中に配置します。そうするとスクリーンの左端と右端にそれぞれ32ピクセルの余白と上下に64ピクセルの余白が出来ます。
つまりこのメソッドはiPad用のスクリーンに対応させる為の簡単な計算をしてくれているんです。
後もう一つ、allocatedした”moles”のArrayをメモリからクリーンアップする為に、以下の行を”dealloc”メソッドに追加して下さい:
[moles release]; moles = nil; |
それではコンパイル&ランして下さい。以下の様にモグラ達がきちんとした場所にそれぞれ配置された事が分かる様になりました。
飛び出すモグラ!
さて、これでモグラ達の配置設定は完璧です。それではコードを加えて彼等が穴から飛び出す様にしてみましょう。
まず始めにモグラ達のスプライトに設定したz値の999を0に戻して地下に潜らせてあげましょう。
それが終わったら、initメソッドの一番下に以下の行を追加して下さい。:
[self schedule:@selector(tryPopMoles:) interval:0.5]; |
このメソッドを見た事が無い方の為に解説しますね。このスケジュールメソッドを使って他のメソッドを設定した間隔で呼び出します。今回なら、モグラ達には0.5秒に一回穴から飛び出して来てもらいましょう!
次に以下を実装して下さい:
- (void)tryPopMoles:(ccTime)dt { for (CCSprite *mole in moles) { if (arc4random() % 3 == 0) { if (mole.numberOfRunningActions == 0) { [self popMole:mole]; } } } } |
このメソッドは0.5秒毎に1回ずつ呼び出され、それぞれのモグラが3/1の確率で穴から飛び出してきます。でもまだ飛び出していない場合にのみ飛び出します。既に飛び出しているかいないかの簡単な判定方法は、”mole.numberOfRunningActions” が0かどうかで判別出来ます。
最後に”popMole”を追加しましょう:
- (void) popMole:(CCSprite *)mole { CCMoveBy *moveUp = [CCMoveBy actionWithDuration:0.2 position:ccp(0, mole.contentSize.height)]; // 1 CCEaseInOut *easeMoveUp = [CCEaseInOut actionWithAction:moveUp rate:3.0]; // 2 CCAction *easeMoveDown = [easeMoveUp reverse]; // 3 CCDelayTime *delay = [CCDelayTime actionWithDuration:0.5]; // 4 [mole runAction:[CCSequence actions:easeMoveUp, delay, easeMoveDown, nil]]; // 5 } |
上記のコードでは、Cocos2Dのアクションメソッドを使用して、モグラが穴から飛び出して0.5秒停止して、今度は穴の中へ引っ込む為の物です。それでは、少しずつ解説していきましょうね:
- Y軸方向にモグラの高さだけ上方向に移動するアクションを作成します。
- 動きを自然に演出する為に、アクションの設定にCCEaseInOutを選択して動きの始めと終わりをゆっくりに設定します。
- それから今度はモグラが穴に引っ込む為のアクションです。この場合の簡単な方法は上記のアニメーションをリバースさせるメソッドを使用します。
- そして次にモグラが飛び出した後0.5秒停止するアクションを作成します。
- 次にこの1連のアクションを”CCSequence”を使って連鎖的に実行させればアクションは準備完了です。
これでOKです。コンパイル&ランして下さい。これでモグラ達が元気に穴から飛び出して来る様になりましたね!
次にお勧めのチュートリアルは何ですか?
このプロジェクトのサンプルコードはこちらからどうぞ!
それではPart 2をチェックして下さい。パート2ではモグラにキュートなアニメーションを追加(小生意気に笑ったり、殴られた時に悲しそうな顔をする)して、モグラを叩く事が出来たらポイントを付ける方法を学びましょう。
このチュートリアルヘのコメントやご質問は以下のフォーラムからどうぞ。
Cocos2Dでモグラたたきアプリ作成チュートリアル: Part 1/2 is a post from: Ray Wenderlich
The post Cocos2Dでモグラたたきアプリ作成チュートリアル: Part 1/2 appeared first on Ray Wenderlich.