1 / 25

Objective-C でシューティングゲーム を作成してみる

Objective-C でシューティングゲーム を作成してみる. OpenGLES を使用して作成していきます。 http://ja.wikipedia.org/wiki/OpenGL_ES ※OpenGLES に関わる部分は解説致しません。 Objective-C の仕様に関わる部分を基本に 解説致します。. 使用する技術. 使用するツール : Xcode. ・① ViewController : 画面描画を管理するクラス ・② Sprite : 画面に表示されるオブジェクトを表現するクラス. 作成するファイル. 処理の流れ. ViewController.

linh
Download Presentation

Objective-C でシューティングゲーム を作成してみる

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Objective-Cでシューティングゲームを作成してみるObjective-Cでシューティングゲームを作成してみる

  2. OpenGLESを使用して作成していきます。 http://ja.wikipedia.org/wiki/OpenGL_ES ※OpenGLESに関わる部分は解説致しません。 Objective-Cの仕様に関わる部分を基本に 解説致します。 使用する技術

  3. 使用するツール : Xcode

  4. ・①ViewController : 画面描画を管理するクラス ・②Sprite : 画面に表示されるオブジェクトを表現するクラス 作成するファイル

  5. 処理の流れ ViewController Sprite viewDidLoad initWithFile glkView render update update

  6. ・主人公は自動的に上下に動く。 ・画面をタップすると弾を発射する。 ・弾を敵に当てれば敵を倒せる。 ・敵は5体。登場する位置、動くスピードはランダム。 ・敵が主人公に触れる、もしくは弾切れ(5発)になると負け。 ・敵を全て倒すと勝ち。 ゲームのルール

  7. ・ Objective-Cではクラスは「インターフェース」と「実装部分」を・ Objective-Cではクラスは「インターフェース」と「実装部分」を 分けて記述します。(Javaのinterfaceとその実装みたいなもの) ・インターフェース部には、クラスのインスタンス変数と、 実装すべきメソッドを宣言します。 ・インターフェースはヘッダファイル(拡張子 .h)として作成し、 実装部分(拡張子 .m)のファイル内でインクルードします。 ex. Testクラスを作成しようと思ったら、Test.h と Test.mを 作成することになります。 Objective-Cのクラスの作成方法

  8. @interface クラス名 : スーパークラス名 ここにインスタンス変数やメソッドを宣言します。 @end @propertyと書いた後に変数名を記述すると、ゲッタとセッタも定義したことになります。 NSMutableArrayは変更可能な配列。NSArrayとすると変更不可の配列となります。 ViewController.h 解説

  9. #import <Foundation/Foundation.h> #import <GLKit/GLKit.h> @interface Sprite : NSObject ~ Frameworkに関わるプロパティは省略 // 座標 @propertyGLKVector2 position; // 加速度 @propertyGLKVector2 velocity; // 拡大率 @propertyfloat scale; // オブジェクトのサイズ @propertyCGSize contentSize; // 透明度 @propertyGLKVector4 color; // 透明度の変化率 @propertyGLKVector4 colorVelocity; ※頭にGLと付くものは、OpenGLESのライブラリで定義されているクラスです。 Sprite.h①

  10. ~ 続き // 初期化処理 - (id)initWithFile:(NSString *)fileName effect:(GLKBaseEffect *)effect; // 描画処理 - (void)render; // 毎フレームオブジェクトの位置を計算するメソッド - (void)update:(float)dt; // 当り判定 - (CGRect)boundingBox; @end Sprite.h②

  11. メソッドの定義方法 - (戻り値の型)メソッド名:(引数の型)引数名; 頭に「-」を付けると、メソッドを定義したことになります。 (id)のidは型で、オブジェクトはどのクラスでも、idという特別な型で表現されます。 そのため、initWithFileはオブジェクトを返却するメソッドということになります。 NSStringは変更不可な文字列クラスです。 NSMutableStringは変更可能な文字列クラスです。 尚、Objective-Cでは文字列は以下の様な形式で表現します。 @"文字列" 後ほど使用例が登場します。 Sprite.h② 解説

  12. ~ Frameworkの初期処理は省略 self.hero = [[Spritealloc] initWithFile:@"hero.png"effect:self.effect]; /// 主人公作成 self.hero.position = GLKVector2Make(860, 320); // 主人公の位置を設定 self.hero.velocity = GLKVector2Make(0, 300); // 主人公の移動速度を設定 [self.spritesaddObject:self.hero]; // 管理用配列に追加 self.enemies = [NSMutableArrayarray]; // 敵管理配列生成 for (int i = 0; i < 5; i++) { // 敵オブジェクト生成 Sprite * enemy = [[Spritealloc] initWithFile:@"jyoumu.png"effect:self.effect]; int rand = arc4random() % 640 + 10; enemy.position = GLKVector2Make(0, rand) // 敵の位置をランダムに決める; rand = arc4random() % 100 + 10; enemy.velocity = GLKVector2Make(rand, 0); // 敵の速度をランダムに決める; [self.spritesaddObject:enemy]; [self.enemiesaddObject:enemy]; } self.bulletCount = 5; self.enemyCount = 5; self.bullets = [NSMutableArrayarray]; self.dogezas = [NSMutableArrayarray]; ViewController.m : viewDidLoad(初期処理)

  13. Objective-Cでは「メッセージ式」というものが頻繁に登場します。Objective-Cでは「メッセージ式」というものが頻繁に登場します。 例えば以下のようなオブジェクト、objが宣言されていたとします。 id obj; このobjが、msgというメソッドを持っていた場合、以下のように呼び出します。 [obj msg]; これはobjに対し、msgというメッセージを送信して、msgメソッドを呼び出しています。 これが「メッセージ式」と呼ばれるものです。 メッセージ式は、オブジェクトが受信したメッセージを処理した値を返却します。 この場合、[obj msg]が、msgメソッドの戻り値そのものとなります。 ViewController.m : viewDidLoad(初期処理) 解説①

  14. インスタンスの生成は以下の様に行います。 インスタンスの生成は以下の様に行います。 [クラス名 alloc] よって、以下の式はSpriteクラスのインスタンスを生成した後、 initWithFile, effectメソッドを呼び出しています。 引数は 「: 引数」のように表します。 生成したインスタンスをself.heroという変数に代入しています。 self.hero = [[Spritealloc] initWithFile:@"hero.png"effect:self.effect]; /// 主人公作成 尚、変数selfはその処理を行っているオブジェクト自身を指します。 (Javaでいう「this」のようなものです) この場合、ViewController.mのインスタンスを指します。 ViewController.m : viewDidLoad(初期処理) 解説②

  15. オブジェクトを生成したら、その管理用の配列に追加しています。オブジェクトを生成したら、その管理用の配列に追加しています。 以下の例で言えば、自身のプロパティspritesは配列なので、 spritesのaddObjectメソッドを呼び出し、自身のプロパティのheroを引数として渡し、 配列の要素としています。 self.hero = [[Spritealloc] initWithFile:@"hero.png"effect:self.effect]; /// 主人公作成 self.hero.position = GLKVector2Make(860, 320); // 主人公の位置を設定 self.hero.velocity = GLKVector2Make(0, 300); // 主人公の移動速度を設定 [self.spritesaddObject:self.hero]; // 管理用配列に追加 ViewController.m : viewDidLoad(初期処理) 解説③

  16. // 弾描画 for (Sprite * sprite inself.bullets) { [sprite render]; } // 主人公描画 NSLog(@"hero.position.y == %f", self.hero.position.y); if (self.hero.position.y >= 600) { self.hero.velocity = GLKVector2Make(0, -400); } elseif (self.hero.position.y <= 30) { self.hero.velocity = GLKVector2Make(0, 400); } [self.herorender]; // 敵描画 for (Sprite * sprite inself.enemies) { [sprite render]; } // 弾が当たった時のエフェクト描画 for (Sprite * sprite inself.dogezas) { [sprite render]; } ViewController.m : glkView(描画処理)

  17. ログ出力はNSLogクラスを使用します。 使い方は書式文字列と、それに対する引数を渡して使用します。 C言語のprintf()と良く似ています。 NSLog(@"hero.position.y == %f", self.hero.position.y); 上記の場合、「%f」の箇所に、引数の「self.hero.position.y」が展開されます。 配列は以下のように要素を巡回して操作することができます。 for (Sprite * sprite inself.enemies) { [sprite render]; } 敵配列の要素を巡回して、全ての要素の描画処理を呼び出しています。 ViewController.m : glkView(描画処理) 解説

  18. for (Sprite * sprite inself.sprites) { [sprite update:self.timeSinceLastUpdate]; } NSMutableArray * bulletsToDelete = [NSMutableArrayarray]; NSMutableArray * enemiesToDelete = [NSMutableArrayarray]; for(Sprite * enemy inself.enemies) { if ( CGRectIntersectsRect(self.hero.boundingBox, enemy.boundingBox)) { [selfviewAlertTitle:@"ゲームオーバー!!" viewAlertBody:@"出向になった。。。"]; } for (Sprite * bullet inself.bullets) { if ( CGRectIntersectsRect(enemy.boundingBox, bullet.boundingBox)) { [bulletsToDelete addObject:bullet]; [enemiesToDelete addObject:enemy]; [selfgenerateDogeza:bullet.position]; self.enemyCount--; } } } ViewController.m : update(更新処理①)

  19. for( Sprite * bullet in bulletsToDelete ){ [self.bulletsremoveObject:bullet]; [self.spritesremoveObject:bullet]; } for( Sprite * enemy in enemiesToDelete ){ [self.enemiesremoveObject:enemy]; [self.spritesremoveObject:enemy]; } NSMutableArray * toDelete = [NSMutableArrayarray]; for( Sprite * dogeza inself.dogezas ) { if ( dogeza.color.w < 0 ) { [toDelete addObject:dogeza]; } } for ( Sprite * dogeza in toDelete ) { [self.dogezasremoveObject:dogeza]; [self.spritesremoveObject:dogeza]; } if (self.enemyCount == 0) { [selfviewAlertTitle:@"ゲームクリア!!" viewAlertBody:@"出向を阻止した!!"]; } ViewController.m : update(更新処理②)

  20. - (void)generateDogeza:(GLKVector2)position { Sprite * dogeza = [[Spritealloc]initWithFile:@"dogeza.png"effect:self.effect]; GLKVector2 emptyVector2 = GLKVector2Make(0, 0); dogeza.position = GLKVector2Add(position, emptyVector2); dogeza.colorVelocity = GLKVector4Make(0, 0, 0, -1); [self.spritesaddObject:dogeza]; [self.dogezasaddObject:dogeza]; } ViewController.m : generateDogeza(弾が当たった時の画像表示処理)

  21. - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { if (self.bulletCount == 0) { [selfviewAlertTitle:@"ゲームオーバー!!" viewAlertBody:@"声が出なくなった。。。"]; } [selfshotBullets]; self.bulletCount--; } GLKViewControllerを継承したクラス内 (正確にはUIResponder, またはUIViewを継承しているクラス)で、 上記名前のメソッドを実装すれば、画面をタップした時に自動的に呼び出されるようになります。 ViewController.m : touchesBegan(画面をタップした時の処理)

  22. - (void)shotBullets { Sprite * bullet = [[Spritealloc]initWithFile:@"message.png"effect:self.effect]; bullet.position = self.hero.position; bullet.velocity = GLKVector2Make(-200, 0); [self.spritesaddObject:bullet]; [self.bulletsaddObject:bullet]; } ViewController.m : shotBullets(画面をタップして、弾を撃つ処理)

  23. - (void)update:(float)dt { GLKVector2 deltaX = GLKVector2MultiplyScalar(self.velocity, dt); self.position = GLKVector2Add(self.position, deltaX); GLKVector4 deltaC = GLKVector4MultiplyScalar(self.colorVelocity, dt); self.color = GLKVector4Add(self.color, deltaC); } ※他殆どFramework的な処理だったので省略 Sprite.m : update(更新処理)

  24. サンプルを持ってきたので試して見て下さい。サンプルを持ってきたので試して見て下さい。 動作確認

  25. ・簡単なiPhoneゲーム制作の解説 http://kozukamahiro.blog.fc2.com/blog-entry-3.html OpenGLESを使う為の方法や、ゲームを作る上でのテクニックなど、殆どの部分を参考にさせて頂きました。 ・詳解 Objective-C 2.0 第3版 http://p.tl/mrKA Objective-Cの仕様を詳細に解説して下さっています。 ボリュームは多いです。 参考

More Related