2011-12-30 3 views
1

私はまだAndroid用アプリケーションをOpenGLに移行する作業をしており、もう一度問題が発生しています。描画コマンドを送信するより理想的な方法はありますか?

私はすべての点で機能していますが、唯一の問題はアニメーションがちょっと邪魔に思えることです。

フレームレートを監視しており、描画スレッドが減速していないことを確認していますが、メインループが少し遅くなり、私が心配していた問題があると思われます。

新しいオブジェクト(例えば、敵)が作成されると、実際には2つのオブジェクトが作成されます。最初のものが作成されてメインスレッドにマッピングされ、そのコンストラクタでメッシュオブジェクトが作成され、グループに追加されてレンダラによって引き続き描画されます。 (例えばその座標など)

オブジェクトの属性が変更されるたびに、オブジェクトはそのメッシュの対応に必要なコマンドを中継(メッシュを変換するために、この例では。)

これがあることが示唆されましたスレッドセーフな通信が、私は疑問を持っています。私はまた、新しいオブジェクトが作成されたときに大量のフレームスキップが発生していることに気付きます。同じメッシュオブジェクトを同じGameオブジェクトに再利用することでこれを修正できますが、それだけですべてが修正されるとは思われません。

これをより効率的かつスレッドセーフにする方法を考えてもいいですか?

もう1つの可能な解決策:ゲームロジックがまったく更新が33ミリ秒を渡すそれまでは行われないように、私はそれが実際に設定したフルスピード(リアルタイム)に行く必要はありません。だから明らかに、私は描画するフレーム間に多くの時間を持っている必要がありますので、抽選は(ゲームのロジックが更新された後に)スレッドのコマンドでのみ呼び出されるように設定することはできますか?

+0

どのような方法でメッシュの状態変化を「中継する」のですか?私はあなたが減速が起こっていると感じるところの印象を受けます。 – OldCurmudgeon

+0

また、新しいプレーヤーが作成されているときにフレームスキップをさらに観察している場合、それらを作成するためにどのようなメカニズムを使用していますか?彼らは新しいスレッドですか?あなたは 'Executor'を使っていますか? – OldCurmudgeon

+0

私は現在、wait()やNotify()などのリレーを実装していません。また、新しいオブジェクトを作成する方法は、オブジェクトのハッシュマップを実装し、.putを使用して各新しいオブジェクトに一意のキーを割り当てることです。いいえ、新しいスレッドではなく、非常に単純なオブジェクトです。敵オブジェクトには、実際にはいくつかの属性と、それらを更新するのに必要なメソッドだけが含まれています。作成するメッシュオブジェクトはすべて、私が実装するテクスチャマネージャクラスを通してテクスチャ化できるすべての四角形です。これは理想的ではないかもしれませんが、各フレームに使用されるテクスチャを単に切り替えることができます。 – cody

答えて

1

ScheduledThreadPoolExecutorのようなものが必要なようです。それは、フレーム間のオブジェクトマップに行う必要があるものは何でもするあなたのメイン/制御スレッドを残して30fpsの時に実行されるよう

は、これらのいずれかを使用すると、スケジュールにあなたのレンダラを置くことができます。

wait/notifyが本当に必要なのは、レンダラーがそれを歩いている間にmapへのアクセスをブロックすることだけです。これを行うには、マップを作成する必要があります​​。これは1/30秒に1回しか発生しないため、かなりのオーバーヘッドが発生することはありません。

あなたの主な目的は、CPUの負荷をできるだけ少なくすることです。これは、マルチスレッドの作業を円滑にするための鍵です。可能な限り多くの時間を過ごすようにしてください。

を追加しました

私はそれが33msからループにかかった時間を減算し、睡眠の長さを指定するために、結果を使用します()。

これは問題の一部である可能性があります。 Windowsマシンでは、currentTimeMillisで15msの解像度を得ることが多いため、睡眠がほとんど眠らないことがあります。タイミングを改善するかどうかを確認するためには、ScheduledThreadPoolExecutorを試してみる価値があります。 ...おっと...これはAndroidではありません。まだ...それは試してみる価値があるかもしれません。

+0

私はちょっとこのアイデアを使用しましたが、若干異なるものがありました。私の場合はRenderWhenDirtyを使用しているので、フレームワークはレンダリングスレッドの実行を制御するために既に存在しています。だから、私は単に要求のレンダリングを呼び出した直後にメインスレッドでwait()を呼び出します。フレームの描画が終了するとnotifyが呼び出されます。また、私はfpsを抑制するために使っていたよりも洗練されたソリューションを思いつきました。 33msからループするまでの時間を引いて、その結果をsleep()の長さを指定するために使用します。これまでのところはうまくいくようです。 – cody

+0

その場合、私はあなたがchoppinessがどこから来ているかを見つけるためにさらに掘削することを提案します。スレッディングの問題が原因かもしれませんが、正しい場所でブロックしたりスリープしたりしていない可能性が高くなります。 – OldCurmudgeon

+0

私はちょうどこのアイデアを使用し、それが助けをしたことを意味しました。私が少し気にしているもう1つの場所は、時々、レンダラーが要求なくフレームを描画するように見えるということです。それが私に起こっているのだろうか? – cody