連載 :
実践!iOSで作るゲームアプリゲームの仕上げ
2011年6月3日(金)
タイトル画面
最後に簡単なタイトル画面を作り、ゲーム起動時にはそこから開始されるようにしてみよう。そして、画面タップでゲーム開始、ゲームオーバーやゲームクリアになったら画面タップでタイトルに戻るという流れを作ってみる。
図4:タイトルとゲーム画面の流れ(クリックで拡大) |
タイトル画面には「Game Start」という文字を表示しておくことにする、その表示のための画像をプロジェクトに登録して、GameControllerのプロパティーに表示用のUIImageViewを追加する。また、現在表示されている画面がタイトルなのか、ゲームなのかを記録しておく型を以下のように定義しておく。さらに画面クリアとタイトル画面、ゲーム画面を作るメソッドを追加する。
typedef enum { MODE_TITLE, //タイトル MODE_GAME, //ゲーム } ModeType; @interface GameController : NSObject { ~ 省略 ~ UIImageView* imageView; ModeType mode; } ~ 省略 ~ -(void)clearGameView; -(void)setUpTitle; -(void)setUpGame; @end
以下が追加メソッドの内容だ。画面クリアのメソッドは現在GameBoardViewに乗っているサブビューを全て削除している。
//画面のクリア -(void)clearGameView { NSArray* ary = [gameView subviews]; for (int i=0; i < [ary count]; i++) { UIView* view = [ary objectAtIndex:i]; [view removeFromSuperview]; } }
タイトル画面の作成はモードタイプの設定と画面クリアを行った後、画面中央にイメージビューを表示している。
//タイトル -(void)setUpTitle { mode = MODE_TITLE; [self clearGameView]; imageView = ; [gameView addSubview:imageView]; imageView.center = CGPointMake(160, 240); }
ゲーム画面は今まで初期化メソッドにあったビューの作成をここで行うようにしている。先に説明したSEやBGM関係の初期化はそのまま初期化メソッドに残して、BGMの再生開始のみをここで行うようにする。
//ゲーム画面 -(void)setUpGame { mode = MODE_GAME; [self clearGameView]; isGameClear = NO; isGameOver = NO; //キャラクターを生成 //ニンジン { carotCount = 3; int tileIndex[3] = {10, 55, 66}; for (int i=0; i < 3; i++) { UIImage* image = [UIImage imageNamed:@"carot_00.png"]; NSMutableArray* array = [NSArray arrayWithObject:image]; GamePieceView* carot = ; tile.item = carot; carot.tile = tile; carot.center = [tile center]; carot.state = STATE_STAY; } } //うさぎ { NSMutableArray* array = [NSMutableArray array]; int i; for(i=0; i < 15; i++){ NSString* name = [NSString stringWithFormat:@"rabit00_%03d.png", i]; UIImage* image = [UIImage imageNamed:name]; [array addObject:image]; } pieceView = [[[GamePieceView alloc] initWithFrame:CGRectMake(0, 0, 48, 48) Images:array Delegate:self] autorelease]; pieceView.type = TYPE_RABBIT; //配置 [gameView addSubview:pieceView]; GameBoardTile* tile = [self.gameView tileAtIndex:44]; tile.piece = pieceView; pieceView.tile = tile; pieceView.center = [tile center]; //タイマースタート [pieceView timerStart]; } //オオカミ { NSMutableArray* array = [NSMutableArray array]; int i; for(i=0; i < 15; i++){ NSString* name = [NSString stringWithFormat:@"wlof00_%03d.png", i]; UIImage* image = [UIImage imageNamed:name]; [array addObject:image]; } enemyView = [[[GamePieceView alloc] initWithFrame:CGRectMake(0, 0, 48, 48) Images:array Delegate:self] autorelease]; enemyView.type = TYPE_WLOF; enemyView.speed = 50; //配置 [gameView addSubview:enemyView]; GameBoardTile* tile = [self.gameView tileAtIndex:22]; tile.piece = enemyView; enemyView.tile = tile; enemyView.center = [tile center]; enemyView.state = STATE_SLEEP; //タイマースタート [enemyView timerStart]; } //ライフ表示 EffectView* efView; lifeImageArray = [[NSMutableArray array] retain]; UIImage* image = [UIImage imageNamed:@"LifeHart.png"]; for (int i=0; i < 3; i++) { efView = [[EffectView alloc] initWith:image]; efView.isFinishDelete = YES; [lifeImageArray addObject:efView]; [gameView addSubview:efView]; [efView release]; efView.center = CGPointMake(320-24-(24*i),32); } [bgmPlayer play];//BGM再生開始 gameTimeCount = 90; //制限時間 //タイム表示 timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 32)]; [gameView addSubview:timeLabel]; timeLabel.backgroundColor = [UIColor clearColor]; timeLabel.textColor = [UIColor whiteColor]; timeLabel.center = CGPointMake(160, 32); [timeLabel release]; timeLabel.textAlignment = UITextAlignmentCenter; timeLabel.font = [UIFont boldSystemFontOfSize:28]; timeLabel.text = [NSString stringWithFormat:@"%02d:%02d", gameTimeCount/60, gameTimeCount-(60*(gameTimeCount/60))]; //タイマー開始 gameTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 //1秒ごとにタイマー実行 target:self selector:@selector(gameTimeCount:) userInfo:nil repeats:YES]; }
そして、タイトル画面、ゲーム画面の切り替えを行うため、GameBoardViewからのタッチアップイベントを受けるデリゲートメソッドの先頭で、モードとフラグなどから判断して処理の切り分けを行う。これにより、タイトル画面でタップすればゲームが開始され、ゲームクリアやゲームオーバーでタップすればタイトル画面に移行できるようになる。
//タッチアップ -(void) gameBoardViewTouchUp:(GameBoardView*)gmView Location:(CGPoint)touchPt Taps:(int)taps Event:(UIEvent*)event { if(mode==MODE_TITLE){ [self setUpGame]; return; } else if(mode==MODE_GAME && ( isGameClear || isGameOver )){ [self setUpTitle]; return; } GameBoardTile* tile = [gmView tileAtPoint:touchPt]; if( tile ){ [pieceView moveWith:tile]; } }
サンプル一式は、会員限定特典としてダウンロードできるので、記事末尾をご確認いただきたい。
最後まで読んでくださった皆さま、ありがとうございました。
「ゲームの仕上げ」サンプルプログラム
連載バックナンバー
Think ITメルマガ会員登録受付中
Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。