ゲームの仕上げ

2011年6月3日(金)
北村 真二

タイトル画面

最後に簡単なタイトル画面を作り、ゲーム起動時にはそこから開始されるようにしてみよう。そして、画面タップでゲーム開始、ゲームオーバーやゲームクリアになったら画面タップでタイトルに戻るという流れを作ってみる。

図4:タイトルとゲーム画面の流れ(クリックで拡大)

タイトル画面には「Game Start」という文字を表示しておくことにする、その表示のための画像をプロジェクトに登録して、GameControllerのプロパティーに表示用のUIImageViewを追加する。また、現在表示されている画面がタイトルなのか、ゲームなのかを記録しておく型を以下のように定義しておく。さらに画面クリアとタイトル画面、ゲーム画面を作るメソッドを追加する。

01typedef enum {
02  MODE_TITLE,   //タイトル
03  MODE_GAME,    //ゲーム
04} ModeType;
05 
06@interface GameController : NSObject {
07  ~ 省略 ~
08  UIImageView*      imageView;
09  ModeType          mode;
10}
11  ~ 省略 ~
12-(void)clearGameView;
13-(void)setUpTitle;
14-(void)setUpGame;
15@end

以下が追加メソッドの内容だ。画面クリアのメソッドは現在GameBoardViewに乗っているサブビューを全て削除している。

1//画面のクリア
2-(void)clearGameView {
3  NSArray*  ary = [gameView subviews];
4  for (int i=0; i < [ary count]; i++) {
5    UIView* view = [ary objectAtIndex:i];
6    [view removeFromSuperview];
7  }
8}

タイトル画面の作成はモードタイプの設定と画面クリアを行った後、画面中央にイメージビューを表示している。

1//タイトル
2-(void)setUpTitle {
3  mode = MODE_TITLE;
4  [self clearGameView];
5  imageView = ;
6  [gameView addSubview:imageView];
7  imageView.center = CGPointMake(160, 240);
8}

ゲーム画面は今まで初期化メソッドにあったビューの作成をここで行うようにしている。先に説明したSEやBGM関係の初期化はそのまま初期化メソッドに残して、BGMの再生開始のみをここで行うようにする。

001//ゲーム画面
002-(void)setUpGame {
003   
004    mode = MODE_GAME;
005    [self clearGameView];
006    isGameClear = NO;
007    isGameOver = NO;
008    //キャラクターを生成
009    //ニンジン
010    {
011      carotCount = 3;
012      int       tileIndex[3] = {10, 55, 66};
013      for (int i=0; i < 3; i++) {
014        UIImage*    image = [UIImage imageNamed:@"carot_00.png"];
015        NSMutableArray* array = [NSArray arrayWithObject:image];
016        GamePieceView*  carot = ;
017        tile.item = carot;
018        carot.tile = tile;
019        carot.center = [tile center];
020        carot.state = STATE_STAY;
021      }
022    }
023 
024    //うさぎ
025    {
026      NSMutableArray*   array = [NSMutableArray array];
027      int           i;
028      for(i=0; i < 15; i++){
029        NSString*   name = [NSString stringWithFormat:@"rabit00_%03d.png", i];
030        UIImage*    image = [UIImage imageNamed:name];
031        [array addObject:image];
032    }
033    pieceView = [[[GamePieceView alloc] initWithFrame:CGRectMake(0, 0, 48, 48)
034              Images:array
035              Delegate:self] autorelease];
036      pieceView.type = TYPE_RABBIT;
037      //配置
038      [gameView addSubview:pieceView];
039      GameBoardTile*    tile = [self.gameView tileAtIndex:44];
040      tile.piece = pieceView;
041      pieceView.tile = tile;
042      pieceView.center = [tile center];
043      //タイマースタート
044      [pieceView timerStart];
045    }
046   
047    //オオカミ
048    {
049      NSMutableArray*   array = [NSMutableArray array];
050      int           i;
051      for(i=0; i < 15; i++){
052        NSString*   name = [NSString stringWithFormat:@"wlof00_%03d.png", i];
053        UIImage*    image = [UIImage imageNamed:name];
054        [array addObject:image];
055    }
056    enemyView = [[[GamePieceView alloc] initWithFrame:CGRectMake(0, 0, 48, 48)
057              Images:array
058              Delegate:self] autorelease];
059    enemyView.type = TYPE_WLOF;
060    enemyView.speed = 50;
061    //配置
062    [gameView addSubview:enemyView];
063    GameBoardTile*  tile = [self.gameView tileAtIndex:22];
064    tile.piece = enemyView;
065    enemyView.tile = tile;
066    enemyView.center = [tile center];
067    enemyView.state = STATE_SLEEP;
068    //タイマースタート
069    [enemyView timerStart];
070  }
071   
072  //ライフ表示
073  EffectView*   efView;
074  lifeImageArray = [[NSMutableArray array] retain];
075  UIImage*  image = [UIImage imageNamed:@"LifeHart.png"];
076  for (int i=0; i < 3; i++) {
077    efView = [[EffectView alloc] initWith:image];
078    efView.isFinishDelete = YES;
079    [lifeImageArray addObject:efView];
080    [gameView addSubview:efView];
081    [efView release];
082    efView.center = CGPointMake(320-24-(24*i),32);
083  }
084   
085  [bgmPlayer play];//BGM再生開始
086   
087  gameTimeCount = 90;   //制限時間
088  //タイム表示
089  timeLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 100, 32)];
090  [gameView addSubview:timeLabel];
091  timeLabel.backgroundColor = [UIColor clearColor];
092  timeLabel.textColor = [UIColor whiteColor];
093  timeLabel.center = CGPointMake(160, 32);
094  [timeLabel release];
095  timeLabel.textAlignment = UITextAlignmentCenter;
096  timeLabel.font = [UIFont boldSystemFontOfSize:28];
097  timeLabel.text = [NSString stringWithFormat:@"%02d:%02d",
098            gameTimeCount/60,
099            gameTimeCount-(60*(gameTimeCount/60))];
100  //タイマー開始
101  gameTimer = [NSTimer scheduledTimerWithTimeInterval:1.0   //1秒ごとにタイマー実行
102                      target:self
103                      selector:@selector(gameTimeCount:)
104                      userInfo:nil
105                      repeats:YES];
106  }

そして、タイトル画面、ゲーム画面の切り替えを行うため、GameBoardViewからのタッチアップイベントを受けるデリゲートメソッドの先頭で、モードとフラグなどから判断して処理の切り分けを行う。これにより、タイトル画面でタップすればゲームが開始され、ゲームクリアやゲームオーバーでタップすればタイトル画面に移行できるようになる。

01//タッチアップ
02-(void) gameBoardViewTouchUp:(GameBoardView*)gmView
03            Location:(CGPoint)touchPt Taps:(int)taps
04            Event:(UIEvent*)event
05{
06    if(mode==MODE_TITLE){
07      [self setUpGame];
08      return;
09  }
10  else if(mode==MODE_GAME && ( isGameClear || isGameOver )){
11      [self setUpTitle];
12      return;
13  }
14   
15  GameBoardTile*    tile = [gmView tileAtPoint:touchPt];
16  if( tile ){
17      [pieceView moveWith:tile];
18  }
19}

サンプル一式は、会員限定特典としてダウンロードできるので、記事末尾をご確認いただきたい。

最後まで読んでくださった皆さま、ありがとうございました。

  • 「ゲームの仕上げ」サンプルプログラム

STUDIO SHIN

家庭用ゲームの企画開発、Mac OS / iOSアプリの開発を主な生業とする。
20年ほど前から家庭用ゲーム開発に携わりファミコンからDS、PSP、Wiiまで幅広く開発。15年前からMac OS Xアプリケーションを開発「DotShotX」「GIFQuickMaker」などを公開。iPhoneアプリ「将棋盤」「DotTouch」「Rabbit Maze」などを開発。開発アプリはアップルのApp Storeで公開中。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています