Hello Space

翻訳元

Thanks for good tutorial :)
Mac Dev : Game Demo Tutorial #2: Hello Space

チュートリアル

Hello World フルソースコード

※ 下地のコードが本家のインストーラで生成されるプロジェクトテンプレートとは異なるようなので、修正が難しい人は、まず上記のソースコードをDLしてプロジェクトを開いてください。

私は、スクリーンキャストのアプローチからゲームデモ作成のチュートリアルに移行することを決定しました。とにかく、このcocos2dゲームデモチュートリアルでは、Hello Worldアプリケーションにいくつかの画像と動きを追加して、コードを拡張してあります。このパートでは、最終的に、宇宙を背景にレーザーを発射できる宇宙船を移動させるところまで行き着くことが出来るでしょう。

まず始めにすることは画像リソースをプロジェクトに追加することです。配布しているファイルを解凍すると"art"フォルダを見つけることが出来るでしょう。xcodeの画面左にあるプロジェクトビューの中から、"Resource"フォルダを探してください。見つけたらそれを右クリックして、"追加 - 既存のファイル..."を選択してファイルに画像リソースを追加します。(ドラッグ&ドロップでも構いません。)

ポップアップウインドウで全てのリソースを追加し終わったら、次に、"GameScene.m"に移動してください。以前使用していたラベルは使用しないので取り除きます。そのためコードを次のように変更してください。

 
-(id) init {
	self = [super init];
	if(self != nil) {
		Label *test = [Label labelWithString:@"Hello World" fontName: @"Helvetica" fontSize: 24];
		test.position = cpv(160, 240);
		[self addChild: test];
	}
	return self;
}
 

 ↓ 下記のように変更

 
-(id) init {
	self = [super init];
	if(self != nil) {
	// 背景を追加します
		Sprite *bg = [[Sprite spriteWithFile:@"bg.png"] retain];
		bg.position = cpv(160,240);
		[self addChild: bg];
 
	}
	return self;
}
 

この新しいコードは、背景イメージにある"Hello World"の文字列を削除したものです。 今私たちは、宇宙船を追加してさらにそれを移動させる必要があります。そこでinitメソッドを次のように書き加えましょう。

 
-(id) init {
	self = [super init];
	if(self != nil) {
	// 背景を追加します
		Sprite *bg = [[Sprite spriteWithFile:@"bg.png"] retain];
		bg.position = cpv(160,240);
		[self addChild: bg];
 
    // 宇宙船を追加します
		ship = [[Sprite spriteWithFile:@"ship.png"] retain];
		ship.position = cpv(50,50);
		[self addChild: ship];
 
	// 宇宙船を移動させます
		[self schedule: @selector(moveShip:)];
 
	}
	return self;
}
 

新たなスプライトをロードして船を呼び出しスケジューラを設定します。スケジューラはcocos2dによって提供される素晴らしい機能で、指定したメソッドを繰り返し呼び出すことを可能にします。また、スケジューラには、どのくらいの頻度でそのメソッドを呼び出すか指定するためのインターバルを引数として渡すことが出来ます。この引数を指定しなかった場合、スケジューラは可能な限り頻繁にそのメソッドを呼び出そうとします。

さて、initメソッドに追加するためのmoveShipメソッドを実装しましょう。次のコードを書き加えてください。

 
-(void) moveShip: (ccTime) dt
{
	t += dt; // "ccTime t"はヘッダーで指定します
	ship.position = cpv(120*sin(t)+160, 50);
}
 

私が上記のコメントで述べているように、"GameScene"のヘッダーを書き換えて、"ccTime t"や"Sprite *ship"のプロパティを"GameLayer"に追加する必要があります。

うまくいけば、ビルドして実行すると、宇宙の背景の上を宇宙船が前後に移動するはずです。

次に、ゲームで使用する"Chipmunk"物理エンジンを設定してみましょう。始めに、"GameScece.m"に移動して、"@implementation GameScene"の前のインポートステートメントの後に、次にC言語の関数を追加してください。

 
static void eachShape(void *ptr, void* unused)
{
	cpShape *shape = (cpShape*) ptr;
	Sprite *sprite = shape->data;
	if( sprite ) {
		cpBody *body = shape->body;
		[sprite setPosition: cpv( body->p.x, body->p.y)];
		[sprite setRotation: (float) CC_RADIANS_TO_DEGREES( -body->a )];
	}
}
 

この関数は、物理演算を適用して更新するために利用されます。次に、"GameLayer"に行き、以前追加したスケジューラの後に次のコードを書き加えます。

 
// Chipmunkの初期化:
		cpInitChipmunk();
 
		space = cpSpaceNew();
		cpSpaceResizeStaticHash(space, 400.0f, 40);
		cpSpaceResizeActiveHash(space, 100, 600);
 
		space->gravity = cpv(10, 0);
		space->elasticIterations = space->iterations;
 
		// Chipmunkの更新
		[self schedule: @selector(step:)];
 

見て分かるように"step"と言う名前の新たなメソッドがスケジュールされています。このメソッドは物理シミュレーションを実行するために呼び出されます。さあ、"GameLyer"にこのメソッドを追加して先に進みましょう。

 
-(void) step: (ccTime) delta
{
	int steps = 2;
	cpFloat dt = delta/(cpFloat)steps;
 
	for(int i=0; iactiveShapes, &eachShape, nil);
	cpSpaceHashEach(space->staticShapes, &eachShape, nil);
}
 

次に、宇宙船が発射する弾丸を作成しましょう。私たちは、"Chipmunk"物理エンジンによって弾丸をアップデートさせたいため、"cpBody"メソッドを呼び出すためのラッパーオブジェクトを作成しなくてはなりません。シミュレーションスペースにおける、"Chipmunk"でオブジェクトをモデリングするための構造体です。"cpBody"はオブジェクトではないのでNSArrayやNSMutableArrayに格納することは出来ませんが、それをラップすることで格納できるようにさせます。

弾丸のラッパークラスの作成を始めるために新しいクラスを追加します。"Classes"フォルダを右クリックして"追加 - 新規ファイル..."を選択してください。プロンプトで"NSObject subclass"を選択します。クラス名を"Bullet"にして作成してください。

"Bullet.h"は次のように書き換えます。

 
#import "chipmunk.h"
 
@interface Bullet : NSObject {
	cpBody *bulletBody;
	bool ready;
}
-(id) initWithCPBody: (cpBody *) bodyIn;
-(void) fireFromX: (float) x y:(float)y;
-(float) getY;
-(void) resetPosition;
 
@property(readwrite) bool ready;
@end
 

"Bullet.m"は次のように書き換えます。

 
#import "Bullet.h"
 
@implementation Bullet
-(id) initWithCPBody: (cpBody *) bodyIn
{
	self = [super init];
	if(self != nil){
		bulletBody = bodyIn;
		ready = YES;
	}
 
	return self;
}
-(void) fireFromX: (float) x y:(float)y
{
	bulletBody->p = cpv(x,y);
	bulletBody->v = cpv(0, 500);
}
-(float) getY
{
	return bulletBody->p.y;
}
-(void) resetPosition
{
	bulletBody->p = cpv(-50,-50);
	bulletBody->v = cpv(0,0);
}
@synthesize ready;
@end
 

さて、"GameScene.h"を切り替えて次のようにプロパティを書き加えます。

 
NSMutableArray *bullets;
 

このNSMutableArrayは宇宙船によって発射される弾丸を管理するのに使用されます。これを使用することで、一見無限に弾丸が生成されているかのように見えますが、実際には10のバレットクラスのインスタンスのみしか生成しません。

"GameScene.m"を書き換えて、"GameLayer"のinitメソッドまでスクロールします。弾丸を管理するいくつかのコードを加えましょう。

 
// 最大10の弾丸をロードするバレットマネージャー
		bullets = [[NSMutableArray alloc] init];
		for(int i = 0; i < 10; i++)
		{
			Bullet *b = [[Bullet alloc] initWithCPBody:[self makeBulletX:-50 y:-50]];
			[bullets addObject: b];
			[b release];
		}
 

このコードでは、ヘッダーで宣言されたNSMutableArrayをセットアップして、バレットクラスのインスタンスを10個生成します。

次に、宇宙船から弾丸を発射するのにタッチイベントを使用するため、タッチイベントを有効にさせます。上記のコードに次の行を追加します。

 
// タッチイベントが有効かどうか:
		isTouchEnabled = YES;
 

さて、次にタッチを読み取るための新しいメソッドを実装しなければなりません。"GameLayer"のinitメソッドの後ろに次のメソッドを書き換えてください。

 
- (BOOL)ccTouchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
	for(Bullet *b in bullets)
	{
		if([b ready])
		{
			[b fireFromX:ship.position.x y:ship.position.y+12];
			[b setReady: NO];
			break;
		}
	}
 
	return kEventHandled;
}
 

ccTouchesBeganメソッドは、cocos2dにタッチがあったことを知らせるために使用されます。また、ccTouchesMoved、ccTouchesEndedと言った同様のメソッドもあります。上記のコードでは、反復処理を行い、準備が済んでいる弾丸の配列から発射可能な弾丸を探します。発射可能な弾丸が見つかったらそれを発射し、発射不可能な状態にセットします。そしてループから抜け出すのでそれ以上弾丸は発射されません。ループの後にkEventHandledを返しますが、これはcocos2dにタッチイベントが処理されたことを伝えるためのものです。

さて、次に弾丸を追跡して、スクリーンの外に出たらそれをリセットするコードを追加しましょう。"GameLayer"に次のメソッドを追加しましょう。

 
-(void) updateBullets
{
	for(Bullet *b in bullets)
	{
		if([b getY] > 500)
		{
			[b resetPosition];
			[b setReady: YES];
			break;
		}
	}
}
 

このメソッドを呼び出すために、"Chipmunk"物理エンジンのために生成されたstepメソッドを戻す必要があります。終端に次の行を追加しましょう。

 
[self updateBullets];
 

これだけです。うまくいけば、ビルドしてコードを実行すると、宇宙の星々を背景に宇宙船が振動する画面が見れるでしょう。また、画面をタッチすると宇宙船から弾丸が発射されます。何か問題が発生したら次のソースコードを確認してください。 Game Demo Tutorial: Entry 2


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2015-07-05 (日) 22:39:42 (871d)