回答:
私はコードを詳細に検討していませんが、基本的な考え方は、入力イベントはAndroidでは非同期であるため、いつでも発生する可能性があるということです。メインループコードを中断して入力イベントを処理しないでください。ゲームが遅くなり、予期しない方法でゲームの状態が変化する可能性があります。
Lunar Landerサンプルで使用される従来のアプローチは、メインループと各入力ハンドラーの周りに同期ブロックを配置して、それらが同時に発生しないようにすることです。これは小さなゲームには有効なアプローチかもしれませんが、ゲームがより複雑になると、効率が悪く、正しく機能しない可能性があります。
この記事では、入力イベントをキューに格納し、メインループの既知のポイントでそれらを処理する、より良い方法を提案しています。入力ハンドラーは、イベントを(それを記述するInputObjectでラップした後)キューの最後にプッシュするだけで、後でゲームスレッドのprocessInputメソッドで処理されます。
記事の作成者は、実際には入力キューと入力オブジェクトプールの2つのキューを使用しています。入力イベントを取得するたびに新しい入力オブジェクトを作成し続けたくないので、メインアクティビティの入力オブジェクトプールが使用されます。入力イベントが頻繁に発生し、多くのオブジェクトを作成するとガベージコレクターが頻繁に実行され、ゲームが不安定になり応答しなくなるため、これは悪いことです。より良いアプローチは、オブジェクトのプールを1回(基本的にはキュー)作成し、必要なときにキューからオブジェクトを取得し、完了したらそれらをキューに戻すことです。これがメインアクティビティのキューの目的です。もう1つのキューは、受信した入力イベントを実際に含み、processInputメソッドを使用してゲームループを処理するゲームスレッドの入力キューです。
プールキューには常にアクティビティの作成時にcreateInputObjectPoolメソッドで割り当てられる固定数のオブジェクト(たとえば、INPUT_QUEUE_SIZE定数で指定でき、30にすることができます)がありますが、入力キューには可変数の入力イベントがあります。アクティビティによってフィードされ、returnToPoolメソッドを使用して処理されると、プールキューに戻されます。これらのキューはArrayBlockingQueueです。これは、通常のキューがオーバーフローおよびアンダーフローする状況で、キューが準備ができるまでブロックする(リンクリストなどではなく)配列を使用して実装された通常のキュー(先入れ先出し)です。操作。