儚く消ゆる

プチ更新


iPhoneで2Dアクションゲームを開発中。
前回の記事では、

  • 遊びの土台となるフィールドとキャラクターとの当たり判定を実装
  • キャラクターが出すビームとフィールドとの当たり判定も実装

まで完成していました。

今回はプチ更新で「ビームとターゲットとの当たり判定」を実装しました。

ターゲットをこわせ


開発予定のゲームは複数のデバイスで通信対戦を想定しているので、キャラクターの出すビームは他のキャラクターに当たらなければなりません。
ですが通信部分が未実装なので、今回は他のキャラクターに見立てたターゲットを用意し、ビームとキャラクターとの当たり判定を実装しました。

CollisionDetection


Fighterクラスは自分の撃った弾(ビームや弾丸)をNSMutableArrayのインスタンスとして持っています。引数として当たり判定されるオブジェクトを受け取るメソッドcollisionDetectionは以下のようになっています。

- (BOOL)collisionDetection:(Widget *)widget {
  for (int i = 0; i < [shotsArray_ count]; ++i) {
    Shot *shot = [shotsArray_ objectAtIndex:i];
    if ([shot hasCollidedWithWidget:widget]) {
      [shotsArray_ removeObjectAtIndex:i];
      [shot disappear];
      [widget disappear];
      return YES;
    }
  }
  return NO;
}

shosArray_に自分の撃った弾が格納されているので、全ての弾についてオブジェクトとの当たり判定を行います。もし当たっていれば当たった弾はshotsArray_から削除し、弾とオブジェクトを画面から消します。
弾を表すShotクラスのメソッドhasCollidedWithWidgetは以下のようになっています。

- (BOOL)hasCollidedWithWidget:(Widget *)widget {
  return CGRectIntersectsRect(self.frame, widget.frame);
}

CGRectIntersectsRectメソッドはCGRectの変数2つを引数として受け取り、2つの矩形が交わっていれば真を返してくれます。

儚く消ゆる


ビームに当たったターゲットにはパッと消えるのではなく、パリーンと儚く消えて欲しい。
そこで、Targetクラスのメソッドdisappearではアニメーションを使ってこれを実現しています。

- (void)disappear {
  [UIView beginAnimations:nil context:NULL];
  [UIView setAnimationDelegate:self];
  [UIView setAnimationDidStopSelector:@selector(didFinishAnimation:)];
  [UIView setAnimationDuration:1.0];
  self.alpha = 1.0;
  self.image = [UIImage imageNamed:kBrokenTargetImageName];
  self.alpha = 0.0;
  [UIView commitAnimations];
}

今までUIImageViewのanimationImagesプロパティに複数の画像をセットするアニメーションは使ったことがあったのですが、今回はアニメーション実行→UIImageViewを親ビューから削除ということをしたかったので、アニメーションの終了を通知してもらう必要がありました。方法を探していたらこちらの記事(「プログラミングノート UIViewで手軽にアニメーションを実行する方法」)で発見!
UIViewのクラスメソッドを使ってアニメーションの細かな設定を行えるようです。
アニメーションの終了を通知してもらうには、setAnimationDelegateで通知を受け取るオブジェクトを指定し、setAnimationDidStopSelectorで終了を通知してもらうメソッドを指定してやればOKです。
終了通知を受け取るメソッドdidFinishAnimationでは自身を親ビューから削除しています。

- (void)didFinishAnimation:(id)sender {
  [self removeFromSuperview];
}

こんな感じになります!