続・ゲームのロジック作成

2011年5月20日(金)
北村 真二

タイマーアクションの変更

タイマーアクションメソッドはタイマーから1/60ごとに呼び出される。タイマー関係のパラメーターを更新した後、ステータスごとの処理を行っている。

-(void) moveAction:(NSTimer*)timer {
  BOOL	update = NO;
  
  delay_mov += 1.0 / 60;	//移動アニメーションのためのカウンター
  
  delayTimer -= 1.0 / 60;	//遅延タイマーを減らす
  if(delayTimer < 0)
  		delayTimer = 0;
  
  switch (state) 
  {
  		case STATE_STAY:			//停止中
  			........
  			break;
  		case STATE_MOVEING:		//移動中
  			........
  			break;
  		case STATE_ATTACKSTART:		//攻撃開始
  			........
  			break;
  }
  if(update)
  	[self update];
  if(delay_mov > 0.1)
  	delay_mov = 0;
}

停止

  animeIndex = 0;
  if( delayTimer == 0 ){
  	//攻撃チェック
  	if([self attackCheck])
  		return;
  	//オオカミの場合...
  	if(type==TYPE_WLOF) {
  		//デリゲートに移動先のタイルを要求する
  		if( [delegate respondsToSelector:@selector(gamePieceTargetMovTile:)] ){
  			GameBoardTile*  ret_tile = [delegate gamePieceTargetMovTile:self];
  			if( ret_tile ){
  				[self moveWith:ret_tile];
  			}
  		}
  	}
  }

delayTimerが0の場合にのみ処理を行う。attackCheckメソッドは攻撃を行うかチェックするメソッドだ。

-(BOOL) attackCheck {
  //オオカミ & 攻撃するか?
  if( type==TYPE_WLOF && [delegate respondsToSelector:@selector(gamePieceIsAttack:)]){
  	//攻撃対象
  	GamePieceView*	piece = [delegate gamePieceIsAttack:self];
  	if( piece ){
  		MovAngleType	attackAngle = [self angle:piece];
  		if( attackAngle!=MOVANGL_NON ){
  			imageIndex = attackAngle;
  			animeIndex = 0;
  			self.state = STATE_ATTACKSTART;
  			return	YES;
  		}
  	}
  }
  return	NO;
}

デリゲートに問い合わせ攻撃を行うなら必要な処理を行ってYESを返す。NOなら攻撃は行わない。攻撃をするなら移動のための処理は行わない。以下の内容はこの部分については前回のサンプルコードから変わっていない。キャラクターがオオカミの場合、デリゲートに移動先の要求を出している。移動先として有効なGameBoardTimeが帰ってくればそこに向かって移動を開始する。

移動

  if(delay_mov >= 0.1){
  	update = YES;
  	animeIndex++;
  	if(animeIndex > 2)
  		animeIndex = 0;
  }

こちらも前回のサンプルコードから変わっていない。delay_movが0.1を超えていたら移動アニメーションのパターンを変更するために配列から画像を取得するためのインデックス値を変更するプロパティーを更新している。

攻撃開始

  if( delayTimer == 0 ){
  	self.state = STATE_ATTACK;
  }

delayTimerが0の場合にのみ処理を行う。ステータスを攻撃に変更している。

アニメーション停止時のデリゲートメソッド

アニメーション終了後に呼ばれるデリゲートメソッドにも以下のようなコードを追加する。各ステータスにより必要な処理を行い。自身のステータスの再設定などを行っている。

  - (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag {
  //死亡
  if( state==STATE_DEAD ){
  	self.tile.piece = nil;
  	if( [delegate respondsToSelector:@selector(gamePieceDead:)] ){
  		[delegate gamePieceDead:self];
  	}
  	return;
  }
  //ダメージ
  if( state==STATE_DAMAGE ){
  	if(life <= 0)
  		self.state = STATE_DEAD;
  	else {
  		imageIndex = MOVANGL_FRONT;
  		animeIndex = 0;
  		self.state = STATE_STAY;
  	}
  	return;
  }
  //攻撃 
  if( state==STATE_ATTACK ){
  	imageIndex = MOVANGL_FRONT;
  	animeIndex = 0;
  	self.state = STATE_STAY;
  	return;
  }
  //移動中
  if( state==STATE_MOVEING ){
  	~ 略 ~
  	//攻撃チェック
  	if([self attackCheck])
  		return;
  	~ 略 ~
  }
}

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

GameControllerにもいくつかコードが追加されているので、このサンプルコードを確認してもらいたい。

  • 「続・ゲームのロジック作成」サンプルプログラム

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メルマガ会員のサービス内容を見る

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