1

私は非常に単純な「ゲーム」を iPhone にセットアップしました。物事は動き回ったり、回転したり、操作したりできます。シミュレーターでは問題なく動作しますが、デバイスでは約 0.25 FPS になり、タッチを認識する時間がないほど遅いようです。

Itemこれはもともと、それぞれが Tick と Draw 関数を持つ s の配列を持つ UIView を使用していました。アプリの開始時に、Tick を呼び出す 60 FPS で発射するタイマーを開始し、Tick の最後に呼び出します。[self setNeedsDisplay];

動作が非常に遅かったので、アイテムを再描画する代わりにレイヤーを移動してItem、クラスをクラスのサブクラスに変えました。CALayerただし、CALayerフレームごとに手動で動かしていましたが、これは明らかに良くありません。それでも遅すぎました。そこで、最終目的地に移動するように指示し、そこに到達するまでのティック数に等しい長さを与えました。

それは問題なく機能しましたが、何かを操作すると、その動きを止めて代わりに別のことをする必要がある場合があります。そこで、すべてのティックを移動することに戻り、新しい位置を設定するだけでなく、それを CATransaction でラップし、トランザクションにティックと同じ長さを与えました。

正常に動作しますが、新しい問題が発生します。何かをアニメーション化する場合、 を呼び出すティックごとに [self setNeedsDisplay] を使用する必要がdrawInContext:あり、これは速度低下の大きな問題のようです。

以前のようにすべてを手動で描画する方法はありませんか? CGContext* 呼び出しを行っていたところ、シミュレーターで問題なく動作しました。J2ME または組み込み C++ で同様のものを実装すれば、問題なく動作します。私は何が欠けていますか?興味深い手動アニメーションを作成するには、OpenGL を学ぶ必要がありますか?

4

4 に答える 4

2

CG アニメーション レイヤーについてはわかりませんが、OpenGLES は高性能グラフィックスに対する iPhone の答えです。一日の終わりには、その方法でより良いパフォーマンスを得ることができます。openGLES を使用するのは面倒ですが、作業コードから始めれば (crashlanding アプリのテクスチャとビュー クラスを参照)、必要なものを十分に抽象化できるはずです。

正直なところ、いくつかの 2D スプライトを描画するためだけに openGLES を使用しなければならないことにあまり満足していませんでしたが、完全な物理エンジンとスクリプト レイヤーで約 50 fps を得ているので、それだけの価値はあったと思います。

于 2009-01-28T16:07:52.710 に答える
1

ポイントAからポイントBに移動する何かをアニメートするだけでよい場合、UIViewとCALayerはこれを十分に処理できます。iPhoneのCoreGraphics、UIViews、またはCore Animationを使用して、スプライトの位置を60FPSで手動で変更する必要はありません。

CALayerを使用した単純な移動の場合、次のことができるはずです。

[CATransaction begin];
[CATransaction setValue:[NSNumber numberWithFloat:0.5f] forKey:kCATransactionAnimationDuration];

CGSize spriteSize = currentSprite.frame.size;
currentSprite.frame = CGRectMake(newPosition.x, newPosition.y, spriteSize.width, spriteSize.height);

[CATransaction commit];

currentSpriteがCALayerであり、newPositionが線形移動全体の終点です。これにより、一定の速度を使用して、現在の場所から新しい位置までスムーズにアニメーション化されます。

Core Animationでは、レイヤーの最終的な場所を指定して、中間のフレームを補間する作業を実行させるだけです。同じレイヤーで実行する別のアニメーションを指定してこのアニメーションを中断すると、ある場所への移動から別の場所への移動にスムーズに移行します。CAKeyframeAnimationsを使用して、より複雑なアニメーションを設計できます。繰り返しになりますが、Core Animationに開始状態と終了状態を与え、残りを最適化させます。

CALayersの軽量ラッパーであるUIViewsを使用すると、デバイスで少なくとも30 FPSを取得し、数十の半透明のレイヤーを一度に移動できます。

于 2009-01-29T18:53:17.330 に答える
0

残念ながら少し書き直しになりそうですが、Cocos2d エンジンはご覧になりましたか? 画面上で一連のスプライトをアニメーション化するだけの場合は、すべての OpenGL 呼び出しを素敵な Objective-C ラッパーでカバーします。

http://code.google.com/p/cocos2d-iphone/

于 2009-01-28T17:54:16.520 に答える
0

本当の問題は、 を呼び出す必要があることであることがわかりました[self setNeedsDisplay]。フレームごとに再描画するのは悪いモジョです。そのため、ほとんどの場合、代わりに画像を使用していますが、CALayer のアクションを null に設定することで、フレームごとに位置を設定することを回避できます。具体的には:

NSMutableDictionary *customActions=[NSMutableDictionary dictionaryWithDictionary:[self actions]];
[customActions setObject:[NSNull null] forKey:@"position"];
[customActions setObject:[NSNull null] forKey:@"transform"];
[customActions setObject:[NSNull null] forKey:@"opacity"];
self.actions=customActions;

その呼び出しの後、フレームごとに計算すると、すべてがはるかに高速になります。

于 2009-01-30T17:32:51.237 に答える