2011-12-30 6 views
4

私はiOSでアニメーションを再生するために書いている小さなゲームの外観を試しています。多くのサブビューでiOSアニメーションをスムーズに保つ方法

私の目標は、ゲームプレイに基づいて各タイルの表示を一連の画像の1つに変更するタイルのグリッドを持つことです。私は各タイル(24x24まで)を顔が変わったときに反転させたいと思います。ゲームが進行するにつれて、より多くのタイルを同時に反転させる必要があります。私はそれらを同時にフリップしようとした最初の実装では、アニメーションが非常に不気味になりました。

タイルごとの遅延がわずかに増加するように各タイルのアニメーションをスケジュールすることで、一度にすべてを反転するのではなく、10番目のタイルがアニメーション化を開始すると、最初はすでに完了しています。プロセス全体が終了するのに少し時間がかかりますが、視覚的に波及効果があります。

Screen shot from the simulator

しかし、一つの問題が残っている:プレイヤーは新しい色を選ぶゲーム移動の開始時に、それはアニメーションを開始する前に、デバイス上の第2の数分のかかります。これは、ゲームが進行するにつれて悪化し、アニメーションがハングするように見えるポイントまで、移動ごとにより多くのフリップをスケジューリングする必要があり、その間にいずれのフレームも実際に識別できずにほぼ即座に完了します。

これは、関連するタイルの反転をトリガーするコードです(私のUIViewゲームグリッドサブクラス内)。 (私はタイルをスキップする最適化を削除しました。なぜなら、ゲームの初期段階でのみ重要なのでです)。

float delay = 0.0f; 
for (NSUInteger row=0; row<numRows; row++) { 
    for (NSUInteger col=0; col<numCols; col++) { 
     delay += 0.03f; 
     [self updateFlippingImageAtRow:row col:col delay:delay animated:YES]; 
    } 
} 

ゲーム・グリッド・ビューは、上記ループ内rowcol変数を使用してアドレス指定されるタイルサブビューのNSArray有します。

updateFlippingImageAtRow:col:delay:animatedは私FlippingImageViewUIViewのもサブクラス)のメソッドで、この(ゲームロジックは省略)に沸く:

-(void)animateToShow:(UIImage*)image 
      duration:(NSTimeInterval)time 
       delay:(float)delay 
      completion:(void (^)(BOOL finished))completion 
{ 
    [UIView animateWithDuration:time 
          delay:delay 
         options:UIViewAnimationOptionTransitionFlipFromLeft 
        animations:^{ 
         [UIView setAnimationTransition:UIViewAnimationTransitionFlipFromLeft 
               forView:self 
                cache:YES]; 
         self.frontImage = image; 
        } 
        completion:completion 
    ]; 
} 
ファインワークス

、しかし、私はそれを私に語っインスツルメンツの測定から結論私の時間はアニメーションブロックに費やされます。ゲームが始まり、反転するタイルの数が増え、操作の始めにスケジュールされるアニメーションの数が問題になり、フレームを落とすことで追いつく。

Instruments screen shot of a few flip operations

これのパフォーマンスを向上させるためにどのように任意の提案ですか?アニメーションの正確なタイミングは本当に重要ではありません。

+0

実際のプロファイリング!もしそうならば、バグを報告してください!) –

答えて

3

これは、UIViewの代わりにCoreAnimationとCALayersを使用して考えることができます。それは増強的に強力で最適化されたフレームワークです。

これは簡単なことではありません。クラスの少なくとも一部を再コードする必要があります(ビュー階層とヒットテストが私の頭に浮かぶ最初のものです)。しかし、試してみる価値はありますが、なぜなら、CALayerはUIViewと非常に似ているからです。

次のステップはOpenGLです。リアルタイムで何百ものオブジェクトを操作することは間違いありませんが、もっと多くの作業が必要です。

+0

ええ、私はあなたが別のAPIを考える時間があるUIViewの数に打撃を与えていると思います。最大100人までOKです。 –

1

代わりにCoreAnimationを試してみてください。フリップアニメーションを行う1つの方法は、次のようになります

  • フリップ(y軸に沿った回転)の前半をアニメーションCABasicAnimationを作成します。
  • delegate method animationDidStop:finished:では、新しいイメージを設定してから、後半をアニメートする新しいアニメーションを作成します。
  • アニメーションをビューのlayerプロパティに適用するだけです。
  • setValue:forKey:を使用すると、アニメーションに「注釈を付ける」ことができます(アニメーションがどのオブジェクトを記憶しているかを覚えておいてください)。レイヤーにアニメーションを追加すると、アニメーションは保持されずにコピーされます。そのため、単にポインタの値を比較するだけでアニメーションを識別することはできません。
関連する問題