FC2ブログ

Entries

cocos2d 初心者ガイドレッスン3の巻

レッスン3を日本語訳していきます。

ここでは、メニューとかシーンとかについて説明されてるみたいです。

かっこいいメニューが作れたらいいなって良く思います。

さて、cocos2d ではどうメニューやシーンを実現してるんですかね。

興味津々にまいりましょう!!

--------------------
<目次
レッスン3 メニューとシーン

このレッスンで、Cocos2d でどのようにゲームをシーンの分けるのか、そしてどのようにシーン間を遷移させるのかについて学んでいきます。

それらのことはとても簡単に理解できるようになるので、CCMenu と、メニューシーンの構築を簡単にしてくれる関連クラスの解説もしましょう。

このレッスンは、レッスン1 インストールとテストレッスン2 はじめてのゲーム をすでに理解していることを想定しています。

シーン

cocos2d では、シーンとは、みえている他のすべてのノードの基本となる親ノードとして動作する特別なノードと定義されています。

好きなように使用しても良いのですが、典型的な使用方法は、実際にゲームをプレイするシーンやタイトルのシーン、ハイスコアのシーン、設定のシーンなどでしょう。

シーンは CCScene クラスで表されます。

シーンは、それが目に見える場合や、シーン上に動作するアクションが存在する場合などに「実行中」と呼ばれます。

一度にひとつのシーンしか実行できません。

しかし、現在実行中のシーン上に別のシーンを差し込むことが可能です。その時は、現在実行中のシーンは一時に中断され、重ねた別のシーンが実行中となります。

その後、差し込んだシーンを閉じた時は、最初に実行中だったシーンが再度実行中となります。

シーンを他のシーンに入れ替えることもできます。これは、ほとんどメモリを消費しないので、好まれてる方法です。

このシーンの差し込み・抜き出しやシーンの入れ替えは、ディレクター(CCDirector) によって行われます。

レッスン1で紹介したテンプレート内を確認した際に CCDirector をすでに見かけたと思います。

アプリケーションデリゲートの中を確認してみてください。(例えば、Lesson1AppDelegate.m など、プロジェクトの中でそれが呼ばれてるならどこでも構いません。)applicationDidFinishLaunching メソッドの下の方にこのようなコードがあると思います。

	[[CCDirector sharedDirector] runWithScene: [HelloWorld scene]];


このコードは、ディレクターに対して、引数として指定したシーン(HelloWorld)でシーンを開始するように伝えています。

例えば、メニューシーンでユーザがプレイボタンをタップした場合や、ゲームオーバーになったときにメニューに戻りたい場合などに、実行しているシーンを別のに変更するためには、ディレクターの replaceScene メソッドを呼び出すだけでいいのです。

	[[CCDirector sharedDirector] replaceScene: [SomeOtherScene scene]];


このコードは現在実行中のシーンを終了し、指定した次のシーンを開始します。後で、最初の(または、他の)シーンを、replaceScene を呼び出してもう一度再開することができます。

かわりに現在のシーンをいったん停止しておきたいだけなのであれば、replaceScene のかわりに pushScene を使用します。popScene を後ほど呼び出すことで、新しく実行中になったシーンを終了し、以前実行中だったシーンを再開することができます。

ただし、iPhone のメモリは限られており、シーンはメモリ上に常駐するので、このメソッドは、ちまちまと使用してください。

ディレクターには他にいろいろと便利なことができます。たとえば適切に一時停止・再開したい時などは、CCDirector リファレンスで詳細を確認してください。

ファンシーな(装飾された)遷移

CC~Transition では多くのシーン間のファンシーな遷移をサポートしています。

[[CCDirector sharedDirector] replaceScene:
[CCTransitionFade transitionWithDuration:0.5f scene:[SomeOtherScene scene]]];


一般的によく使われる遷移には、以下のようなものがあります。

・CCTransitionFade
・CCTransitionFlipAngular
・CCTransitionShrinkGrow
・CCTransitionMoveInB
・CCTransitionMoveInT
・CCTransitionMoveInL
・CCTransitionMoveInR
・CCTransitionFadeTR
・CCTransitionFadeUp
・CCTransitionFlipX
・CCTransitionFlipY
・CCTransitionPageTurn
・CCTransitionCrossFade

遷移の種類をもっと確認したいのであれば、 API ドキュメントをチェックしてください。

メニュー

メニューは、よく知られた GUI の概念であるボタンを使うことによってゲームとユーザを相互的に動作させる方法を提供します。

メニューは、ディレクターにシーンの変更を伝えるためによく使用されますが、ゲームをコントロールする際に、便利に柔軟に使用することもできます。

メニューを作るためには単にメニューのインスタンスを作るだけです。

    CCMenu * myMenu = [CCMenu menuWithItems:nil];


このコードで、メニューアイテムがない空のメニューが作られます。

メニューを使用可能とするためには、メニューアイテムを追加する必要があります。

メニューアイテムにはいくつかの選択肢があります。

・CCMenuItemAtlasFont
・CCMenuItemFont
・CCMenuItemImage
・CCMenuItemLabel
・CCMenuItemSprite
・CCMenuItemToggle

それぞれのメニューアイテムの種類には、微妙な違いがあります。

ただし、基本的に、それらにはボタンがタッチされた時に呼び出されるターゲットとセレクターを定義することができます。

一番簡単につくれるメニューのひとつに、CCMenuItemImage があります。これは、メニューアイテムのためにヒット領域が定義されたイメージとして使用可能です。


    CCMenuItemImage *menuItem1 = [CCMenuItemImage itemWithNormalImage:@"myFirstButton.png"
selectedImage: @"myFirstButton_selected.png"
target:self
selector:@selector(doSomething:)];


・itemWithNormalImage はメニューアイテムとして使用したい画像を設定します。
・selectedImage はボタンが押下された際に使用される画像を定義します。
・target はメニューアイテムの押下にどのオブジェクトが応答するかを定義します。この場合「self」は、メニューが作成されたシーンを参照します。
・selector は呼び出されるべきターゲットメソッドです。

メモ:@selector(doSomething) と @selector(doSomething:) には違いがあります。(違いはコロンの有り無しです)コロンが付いている方は、そのメソッドに menuItem オブジェクトが渡されます。

これは、呼び出されたメソッドに付加的な値を渡したい時に役立ちます。

例えば、メニューアイテムの tag で次に何をするのか決定することができます。

また、MenuItemType のサブクラスに付加的な情報を含めることにより、doSomething メソッド内でその情報にアクセスすることもできます。

いったんメニューアイテムを構築したら、他の CCNode に追加したのと同じ方法でメニューにアイテムを追加することができます。

   [myMenu alignItemsVertically];


あるいは、次のように menuWithItems コンストラクタを次のように変更することにより、複数のメニューアイテムを一度に構築してそれをメニューに追加することができます。(この例のように、コンストラクタの最後に nil を指定するのを忘れないようにしてください)

CCMenu *myMenu = [CCMenu menuWithItems:menuItem1, menuItem2, menuItem3, nil];


CCMenu には alignItemsVertically や alignItemsInRows といったメニューをレイアウトするいくつかの便利なメソッドがあります。それらは以下のように使用します。

   [myMenu alignItemsVertically];


同時にそれを指定し、以下のようにメニューを構築します。

// いくつかのメニューアイテムを構築します
CCMenuItemImage * menuItem1 = [CCMenuItemImage itemWithNormalImage:@"myfirstbutton.png"
selectedImage: @"myfirstbutton_selected.png"
target:self
selector:@selector(doSomethingOne:)];
 
CCMenuItemImage * menuItem2 = [CCMenuItemImage itemWithNormalImage:@"mysecondbutton.png"
selectedImage: @"mysecondbutton_selected.png"
target:self
selector:@selector(doSomethingTwo:)];
 
 
CCMenuItemImage * menuItem3 = [CCMenuItemImage itemWithNormalImage:@"mythirdbutton.png"
selectedImage: @"mythirdbutton_selected.png"
target:self
selector:@selector(doSomethingThree:)];
 
 
// メニューを構築し、メニューアイテムを追加します
CCMenu * myMenu = [CCMenu menuWithItems:menuItem1, menuItem2, menuItem3, nil];
 
// メニューアイテムを垂直に配置します
[myMenu alignItemsVertically];
 
// メニューをシーンに追加します
[self addChild:myMenu];


この6つの画像を使ってこのテストを実施してみてください。



この画像でテストを行うためには、まず画像をプロジェクトのルートディレクトリにダウンロードして、Xcode の Resources フォルダに追加します。(iPhone システムは大文字小文字を区別するので、ダウンロードするときは大文字小文字の違いに気をつけてリネームしてください。)

それぞれのメニューアイテムは別々のコールバック関数を定義しているので、それらを追加する必要があります。

- (void) doSomethingOne: (CCMenuItem  *) menuItem 
{
NSLog(@"The first menu was called");
}
- (void) doSomethingTwo: (CCMenuItem *) menuItem
{
NSLog(@"The second menu was called");
}
- (void) doSomethingThree: (CCMenuItem *) menuItem
{
NSLog(@"The third menu was called");
}


メニューやその仕様方法についてより詳細に理解するために、CCMenu についての文書をひと通り確認して下さい。

最初の3つのレッスンを終えたら以下のようなコードになっているはずです。メニューのセットアップは別メソッドに分けてあるので注意してください。

//
// HelloWorldLayer.m
// Lesson1
//
 
 
// Import the interfaces
#import "HelloWorldScene.h"
#import "CCTouchDispatcher.h"
 
 
CCSprite *seeker1;
CCSprite *cocosGuy;
 
// HelloWorld implementation
@implementation HelloWorld
 
+(id) scene
{
// 'scene' is an autorelease object.
CCScene *scene = [CCScene node];
 
// 'layer' is an autorelease object.
HelloWorld *layer = [HelloWorld node];
 
// add layer as a child to scene
[scene addChild: layer];
 
// return the scene
return scene;
}
// set up the Menus
-(void) setUpMenus
{
 
// Create some menu items
CCMenuItemImage * menuItem1 = [CCMenuItemImage itemWithNormalImage:@"myfirstbutton.png"
selectedImage: @"myfirstbutton_selected.png"
target:self
selector:@selector(doSomethingOne:)];
 
CCMenuItemImage * menuItem2 = [CCMenuItemImage itemWithNormalImage:@"mysecondbutton.png"
selectedImage: @"mysecondbutton_selected.png"
target:self
selector:@selector(doSomethingTwo:)];
 
 
CCMenuItemImage * menuItem3 = [CCMenuItemImage itemWithNormalImage:@"mythirdbutton.png"
selectedImage: @"mythirdbutton_selected.png"
target:self
selector:@selector(doSomethingThree:)];
 
 
// Create a menu and add your menu items to it
CCMenu * myMenu = [CCMenu menuWithItems:menuItem1, menuItem2, menuItem3, nil];
 
// Arrange the menu items vertically
[myMenu alignItemsVertically];
 
// add the menu to your scene
[self addChild:myMenu];
}
// on "init" you need to initialize your instance
-(id) init
{
// always call "super" init
// Apple recommends to re-assign "self" with the "super" return value
if( (self=[super init] )) {
 
 
// create and initialize our seeker sprite, and add it to this layer
seeker1 = [CCSprite spriteWithFile: @"seeker.png"];
seeker1.position = ccp( 50, 100 );
[self addChild:seeker1];
 
// do the same for our cocos2d guy, reusing the app icon as its image
cocosGuy = [CCSprite spriteWithFile: @"Icon.png"];
cocosGuy.position = ccp( 200, 300 );
[self addChild:cocosGuy];
 
// schedule a repeating callback on every frame
[self schedule:@selector(nextFrame:)];
[self setUpMenus];
 
// register to receive targeted touch events
[[CCTouchDispatcher sharedDispatcher] addTargetedDelegate:self
priority:0
swallowsTouches:YES];
}
return self;
}
 
// on "dealloc" you need to release all your retained objects
- (void) dealloc
{
// in case you have something to dealloc, do it in this method
// in this particular example nothing needs to be released.
// cocos2d will automatically release all the children (Label)
 
// don't forget to call "super dealloc"
[super dealloc];
}
- (void) nextFrame:(ccTime)dt {
seeker1.position = ccp( seeker1.position.x + 100*dt, seeker1.position.y );
if (seeker1.position.x > 480+32) {
seeker1.position = ccp( -32, seeker1.position.y );
}
}
- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event {
return YES;
}
- (void)ccTouchEnded:(UITouch *)touch withEvent:(UIEvent *)event {
CGPoint location = [touch locationInView: [touch view]];
CGPoint convertedLocation = [[CCDirector sharedDirector] convertToGL:location];
 
[cocosGuy stopAllActions];
[cocosGuy runAction: [CCMoveTo actionWithDuration:1 position:convertedLocation]];
}
 
- (void) doSomethingOne: (CCMenuItem *) menuItem
{
NSLog(@"The first menu was called");
}
- (void) doSomethingTwo: (CCMenuItem *) menuItem
{
NSLog(@"The second menu was called");
}
- (void) doSomethingThree: (CCMenuItem *) menuItem
{
NSLog(@"The third menu was called");
}
 
 
@end


メニューアイテムはセレクタのかわりにブロックを使用することもできます。


	// Create some menu items
CCMenuItemLabel *mi1 = [CCMenuItemLabel
itemWithLabel:someLabel
block:^(id sender) {
[theDirector pushScene:[SceneGame node];
}
];


Objective-C のブロックに付いてはここによい文書があります。ブロックを使用することで、簡単なメニューアイテムのための一度だけしか使用しないメソッドをコードから排除することができます。

-------------------------------

終わった。つかれた。

レッスン3も後ほど実施してみますね。
スポンサード リンク

コメント

コメントの投稿

コメントの投稿

管理者にだけ表示を許可する

トラックバック

トラックバック URL
http://miyachikantaro.blog.fc2.com/tb.php/10-e6596450
この記事にトラックバックする(FC2ブログユーザー)

Appendix

出演ゲーム

みやちかんたろうの大冒険

↑インストールはこちらから
予告編

21面デモ

ステージ作成

検索フォーム

訪問者

Apple製品紹介

Apple MacBook Air 1.6GHz 13.3インチ MB003J/A

中古価格
¥59,800から
(2013/1/24 06:45時点)

QRコード

QR

メールフォーム

名前:
メール:
件名:
本文:

Extra

プロフィール

みやちかんたろう

Author:みやちかんたろう
種別:きいろいねこ
年齢:10歳
性別:オス
趣味:昆虫採集
twitter:@gatsupport

※このサイトはリンクフリーです。ご自由にリンクしてください。相互リンクもじゃんじゃん募集中です!!

最新記事

最新コメント

最新トラックバック

月別アーカイブ