読者です 読者をやめる 読者になる 読者になる

WonderPlanet DEVELOPER BLOG

ワンダープラネットの開発者ブログです。モバイルゲーム開発情報を発信。

UIDynamicAnimatorで物理演算をやってみよう

Objective-C 物理演算エンジン

今回のエンジニアブログ担当の近藤です。

先日、新しいiPhone5s、iPhone5cの発売にあわせてiOS7がリリースされましたね。
XcodeやObjective-Cで新たにどんなことができるようになったのか調べてみたところ、
UIDynamicAnimatorという新しいクラスが追加され、
なんとUIViewのオブジェクトに対して物理演算でグリグリとアニメーションさせることができるようになっていました。

物理演算といえばBox2Dなどの物理演算エンジンが思い浮かびますが、
これらを使わなくてもオブジェクトを衝突判定してバウンドさせたりできます。
今回はUIKitでの物理演算のさわりの部分をご紹介します。

まずはプロジェクト作成。

物理演算はiOS7での新機能になるので、Xcode5を使いましょう。
プロジェクトの種類はSingle View ApplicationでOK。

アニメーションさせる画像をプロジェクトに入れましょう。

ここでは弊社のロゴマークを使用します。

ViewControllerに以下のように実装しましょう。

//  
//  ViewController.m  
//  PhysicsSample  
//  
  
#import "ViewController.h"  
  
@interface ViewController ()  
  
@property (nonatomic, strong) UIDynamicAnimator *animator;  
@property (nonatomic, strong) UIGravityBehavior *gravity;  
@property (nonatomic, strong) UICollisionBehavior *collision;  
  
@end  
  
@implementation ViewController  
  
- (void)viewDidLoad  
{  
    [super viewDidLoad];  
    // Do any additional setup after loading the view, typically from a nib.  
    //発射ボタン  
    UIButton * button = [ UIButton buttonWithType:UIButtonTypeRoundedRect ];  
    button.frame = CGRectMake( 110, 50 , 100, 50 );  
    [ button setTitle:@"発射" forState:UIControlStateNormal ];  
    [ button addTarget:self action:@selector( tapButton: ) forControlEvents:UIControlEventTouchUpInside ];  
    [ self.view addSubview:button ];  
  
    //アニメーターを設定  
    self.animator = [[UIDynamicAnimator alloc] initWithReferenceView:self.view];  
  
    //衝突判定  
    self.collision = [[UICollisionBehavior alloc] initWithItems:nil];  
    self.collision.translatesReferenceBoundsIntoBoundary = YES;  
  
    //重力を設定  
    self.gravity = [[UIGravityBehavior alloc] initWithItems:nil];  
  
    [self.animator addBehavior:self.gravity];  
    [self.animator addBehavior:self.collision];  
  
}  
  
-(void)tapButton:(id)sender{  
  
    //x座標はランダムで。  
    int posX = random() % 320;  
  
    //ワンプラロゴの画像のUIImagevViewを作成  
    UIImageView *img = [[UIImageView alloc]initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"%@",@"wonpla.png"]]];  
    img.center = CGPointMake(posX, 0);  
  
    [self.view addSubview:img];         //ロゴ画像を表示  
    [self.gravity addItem:img];         //ロゴ画像に重力を反映  
    [self.collision addItem:img];       //ロゴ画像に衝突判定を反映  
}  
  
- (void)didReceiveMemoryWarning  
{  
    [super didReceiveMemoryWarning];  
    // Dispose of any resources that can be recreated.  
}  
@end

実行

発射ボタンを押すと画像が落っこちてきて、
バウンドするアニメーションが再生されます。

UIDynamicAnimator

解説

物理演算をするために
UIDynamicAnimatorクラス、UIGravityBehavirorクラス、UICollisionBehaviorクラス
の3つのクラスを使っています。(他にもいっぱい物理演算関連のクラスがあるみたいです。)

[30行目]
ViewControllerで物理演算できるように設定します。
ここで指定したviewが物理演算のアニメーションを表示させることができるキャンバスになります。

[32〜40行目]
gravityBehaviorとcolisionBehaviorを追加することで、
30行目で指定したview上で重力と衝突判定を使用できるようになります。

[53〜55行目]
画像に対して重力と衝突判定を反映するように設定します。

これらの実装をすることで、
発射ボタンを押した時に、UIImageViewの画像が下方向に落っこちてきてバウンドするアニメーションをさせることができるようになりました。

今までは物理演算を使用するにはBox2DやChipmunkなどの物理演算エンジンを導入する必要がありましたが、標準で物理演算を使うことができるようになったので、もっと手軽に扱うことができますね。
これでobjective-cのみで物理演算によるリアルな動きをするゲームができちゃうかもしれないですね〜。