Androidスレッドがデザインに頭を悩ませる問題


9

ゲームデザインに頭を悩ませています。Androidプラットフォームでは、アクティビティがあり、そのコンテンツビューにカスタムサーフェスビューを設定しています。カスタムサーフェスビューがパネルとして機能し、すべてのクラスのインスタンスを作成し、そこですべての描画と計算を行います。

質問:代わりに、アクティビティで他のクラスのインスタンスを作成する必要がありますか?

次に、ゲームループを処理するカスタムスレッドクラスを作成します。

質問:この1つのクラスをすべてのアクティビティでどのように使用しますか?または、毎回拡張スレッドクラスの個別のインスタンスを作成する必要がありますか?

前のゲームでは、スレッドクラスのインスタンスを作成する必要のある複数のレベルがあり、スレッドクラスでは、各個別のレベルにコンストラクターメソッドを設定し、ループでswitchステートメントを使用して、レンダリングする必要があるレベルを確認しましたそして更新。混乱するようでしたら申し訳ありません。

私が使用している方法が非効率的であるかどうか(おそらくそうであるかどうか)と、それを正しい方法で設計する方法を知りたいだけです。私はそこにたくさんのチュートリアルを読みました、そして私はまだこの特定のトピックで多くの問題を抱えています。多分これを説明するいくつかのチュートリアルへのリンク?ありがとう。

回答:


13

レンダースレッド(Canvas/ を使用するとOpenGL ESCanvasおそらく設定が少し簡単になります)と、ゲームロジックを配置するゲームスレッドを用意することを強くお勧めします。

ゲームを実際に「ロード」するには、GameEngineクラスを作成し、それをアプリケーションの中心点にすることができます。レンダラーの準備ができたら、GameEngineインスタンスへのコールバックを作成できます。これはRunnable、レンダリング用に2つのスレッドを作成Runnableし、ゲームロジック用にもう1 つを使用して開始します。

サンプルコード:

アプリケーション開始

private GameEngine engine;
private CanvasRenderer renderer;

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   // Create instances of your two Runnable classes and pass that into
   // the GameEngine constructor.
   // Create an instance of the game engine.
   engine = new GameEngine(canvasRunnable, gamelogicRunnable);
   renderer = new CanvasRenderer(this, engine); 
   setContentView(renderer); 
}

CanvasRenderer

private GameEngine engine;    

// Save your instance from the GameEngine reference in your constrcutor and make
// a global initializion for your GameEngine instance.  

@Override
public void surfaceCreated(SurfaceHolder holder) {  
   // One time setup here.
   // When your view is ready, make this callback to the 
   // GameEngine.
   engine.surfaceIsReady();
}

GameEngine

private Thread canvasThread;
private CanvasRunnable canvasRunnable;
// You should be able to figure out how to create a second thread
// where you should put your game logic. :)

// Constructor stuff like creating instances of your threads
// and passing references as you wish to those.
// Don't start the threads here.
// Remember to set references from your Runnable's into your Thread's 
// instances here!

/**
 * Callback. Now your renderer is ready and you
 * can start your threads.
 */
public void surfaceIsReady() {
   thread.setName("Canvas");
   thread.start();
   // Same for game logic.
}

わぁ、ありがとう。私はあなたがそれを説明する方法が好きでした。その1つの説明で、コンセプト全体がわかります。
セマハン2011年

@semajhan:さらに問題があるかどうか尋ねてください。:)

これが私の頭の中にあるものです。パネルを持つ他のすべてのクラスへの「リンク」または「参照」として機能するGameEngineクラスです。アクティビティ>パネル> GameEngine>他のすべてのクラス。
セマハン2011年

@semajhan:その通りです。あなたの知識のためだけに:あなたが一緒に行くことに決めるなら、OpenGL ESあなたはレンダラーがOpenGL ESすでに独自のスレッドを持っていることを知っているべきです、そしてその場合、あなたは手動で新しくThreadそしてRunnableそのシステムのために作成して開始する必要はありません。

このコメントは無視してください。
セマハン2011年

3

通常、ゲームループは単一のアクティビティ内に自己完結しています。

アクティビティを切り替えると、ゲームループが一時停止/終了します。個別のアクティビティは、とにかくゲームの一時停止に対応する必要があります(たとえば、「友達にメールを送信する」または「メインメニュー」のアクティビティに切り替えたため)

追加のレベルについては、新しいスレッドを作成したり破棄したりしないでください。「レベル完了、次のレベルの読み込み、お待ちください」アクティビティに切り替えて、「メインゲーム」を再起動する必要がある場合を除きます「とにかく活動。しかし、その場合でも、実際には「追加の」スレッドを作成するのではなく、その1つのアクティビティで1つのスレッドを作成し、そのアクティビティを順次強制終了/再起動/強制終了/再起動...などします。レベルが完了するたびに。


3

あなたがドイツ語を理解しているなら、このチュートリアルはとてもいいです。

英語については、このチュートリアルをお勧めします

スレッドクラスについて:アプリケーションのすべてのクラスから参照できることが本当に必要かどうかはわかりません。私のゲームでは、それをそのように解決しました:

メインGUIの描画を担当するクラスには、オーバーライドされたrenderメソッドがあります。このメソッドでは、すべてのGUI要素を更新し、ユーザー入力を処理するスレッドクラスが呼び出されます。

スレッドはまた、一定のフレームレートを維持する責任があります。開発しているゲームによっては、これが重要になる場合があります。


そのドイツ語のチュートリアルは素晴らしいですが、大まかにvai googleに翻訳されていたので、理解するのがちょっと難しいです。
セマハン2011年
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.