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

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

ステータスの変更

setState: はstateプロパティー設定時に呼び出されるアクセッサメソッドだ。設定されたステータスにより必要な処理を行う。ここでの処理は大抵の場合タイマーアクションか、アニメーション終了のデリゲートメソッドの中で行われる事の前準備となる。

-(void)setState:(PieceState)st {
  if(state == st)
  	return;	//同じならなにもしない
  state = st;
  switch( state )
  {
  	case STATE_SLEEP:			//眠り
  		........
  		break;
  	case STATE_STAY:			//停止
  		........
  		break;
  	case STATE_ATTACKSTART:		//攻撃開始
  		........
  		break;
  	case STATE_ATTACK:			//攻撃
  		........
  		break;
  	case STATE_DAMAGE:		//ダメージ
  		........
  		break;
  	case STATE_DEAD:			//死亡
  		........
  		break;
  }
  [self update];
}

それでは各ステータス設定時の処理を説明しよう。

眠り

	imageIndex = MOVANGL_SLEEP;

キャラクターの表示を「眠り」に変更する。imageIndexに設定された値が配列のインデックス値として、その画像がupdateメソッドでCALayerのコンテンツに設定される。

停止

  imageIndex = MOVANGL_FRONT;
  delayTimer = 0.5;	//停止の継続時間

キャラクターの表示を「正面向き」に変更する。「停止の継続時間」は停止のパターンになってから0.5秒間、停止パターンのままなにもしないという設定だ。

攻撃開始

  delayTimer = 0.1;	//攻撃までの時間

攻撃開始のパターンになったら0.1秒間。攻撃開始パターンのままなにもしない。時間経過後、後ほど説明するタイマーアクションの中でステータスを「攻撃」に変更している。

攻撃

  int	x=0,y=0;
  if(imageIndex==MOVANGL_FRONT)
  	y = 20;
  else if(imageIndex==MOVANGL_BACK)
  	y = -20;
  else if(imageIndex==MOVANGL_LEFT)
  	x = -20;
  else if(imageIndex==MOVANGL_RIGHT)
  	x = 20;
  //アニメーション
  CABasicAnimation*	anime = [CABasicAnimation animationWithKeyPath:@"position"];
  CGPoint	fromPt = self.layer.position;
  anime.duration = 0.1;
  anime.fromValue = [NSValue valueWithCGPoint:fromPt];
  anime.toValue   = [NSValue valueWithCGPoint:CGPointMake(fromPt.x+x, fromPt.y+y)];
  anime.delegate = self;
  [self.layer addAnimation:anime forKey:@"animatePosition"];

攻撃パターンでは現在向いている方向に向かって20ピクセル分、0.1秒で移動させるアニメーションを行っており、この動きが相手キャラに向かって攻撃を加えるというアクションにしている。

ダメージ

  life--;	//ライフを減らす
  //移動中にダメージを受けた場合
  if( targetTile ){
  	if(nextTile.piece)
  		self.center = [self.tile center];
  	self.tile.piece = nil;
  	self.tile = nextTile;
  	self.tile.piece = self;
  	targetTile = nil;
  	nextTile = nil;
  }
  imageIndex = MOVANGL_DAMAGE;
  //アニメーション
  CABasicAnimation*	animeBounds;
  CGRect		fromRect;
  CGRect		toRect;
  float			scale = 2.0;
  animeBounds = [CABasicAnimation animationWithKeyPath:@"bounds"];
  fromRect = CGRectMake(self.layer.bounds.origin.x, 
  	self.layer.bounds.origin.y, 
  	self.layer.bounds.size.width, 
  	self.layer.bounds.size.height);
  toRect   = CGRectMake(self.layer.bounds.origin.x, 
  	self.layer.bounds.origin.y, 
  	self.layer.bounds.size.width*scale, 
  	self.layer.bounds.size.height*scale);
  animeBounds.fromValue = [NSValue valueWithCGRect:fromRect];
  animeBounds.toValue = [NSValue valueWithCGRect:toRect]; 
  animeBounds.duration = 0.1;
  animeBounds.delegate = self;
  [self.layer addAnimation:animeBounds forKey:@"animateBounds"];

ダメージパターンではキャラクターの表示を「ダメージ」に変更すると共に、キャラクターの表示サイズを0.1秒で2倍にするアニメーションを設定しており、この動きを相手キャラから攻撃を受けたアクションにしている。

死亡

  self.tile.piece = nil;
  imageIndex = MOVANGL_DEAD;
  float	duration = 1.0;
  
  //透明度のアニメーション
  CABasicAnimation*	opacity = [CABasicAnimation animationWithKeyPath:@"opacity"];
  opacity.fromValue = [NSNumber numberWithFloat:1.0];
  opacity.toValue = [NSNumber numberWithFloat:0.0];
  opacity.duration = duration;
  [self.layer addAnimation:opacity forKey:@"animateDeadOpacity"];
  self.layer.opacity = 0.0;
  
  //矩形サイズのアニメーション
  CABasicAnimation*	animeBounds;
  CGRect	fromRect;
  CGRect	toRect;
  animeBounds = [CABasicAnimation animationWithKeyPath:@"bounds"];
  fromRect = self.layer.bounds;
  toRect   = CGRectMake(fromRect.origin.x, fromRect.origin.y, 
  								fromRect.size.width*2.0, fromRect.size.height*2.0);
  animeBounds.fromValue = [NSValue valueWithCGRect:fromRect];
  animeBounds.toValue = [NSValue valueWithCGRect:toRect]; 
  animeBounds.duration = duration;
  [self.layer 	 forKey:@"animateDeadBounds"];
  self.layer.bounds = toRect;
  
  //位置のアニメーション
  CABasicAnimation*	animePos = [CABasicAnimation animationWithKeyPath:@"position"];
  CGPoint	fromPt = self.layer.position;
  animePos.duration = duration;
  animePos.fromValue = [NSValue valueWithCGPoint:fromPt];
  animePos.toValue = [NSValue valueWithCGPoint:CGPointMake(fromPt.x, fromPt.y-320)];
  animePos.delegate = self;
  [self.layer addAnimation:animePos forKey:@"animateDeadPosition"];

死亡パターンではキャラクターの表示を「死亡」に変更すると共に、透明度、サイズ、位置の3つのアニメーションを設定している。このアニメーションによりキャラクターが上がって消えて行く演出を行っている。

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

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

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