多くのAndroidゲームは、保存/読み込みまたはオプション/設定を正当化するのに十分な大きさではなく、自宅で電車の中で10分間オフハンドでプレイされるという理由だけで、カスタムキャラクターなどを気にしません。
私が最初のAndroidゲームの大きなスコープで何かを始めたという間違いを犯さないでください。たくさんの小さなゲームを作ってから、もっと大きなものを選びましょう
Androidの詳細:
構造:
ほとんどすべてのゲームを1つのアクティビティクラスに含めることをお勧めします。Androidは、各アクティビティがミニアプリのようなものであり、アプリ内の他のアクティビティから半独立しているという考えに基づいています。アプリは基本的にアクティビティのスタックであり、ユーザーはどちらが一番上にあるかを確認できます。
上から1つポップすると、通常は破棄され、ユーザーが新しいアクティビティを開始したときに再作成されます(startActivityインテント)。これにより、アクティビティ間の状態を維持することが難しくなり、単一のアクティビティアーキテクチャにつながります
「新しいゲーム/ゲームの読み込み/オプション」メニューが付いたホーム画面タイプのアクティビティを作成し、それを起動アクティビティにすることができます。ただし、ゲームアクティビティにも同じ機能のほとんどが含まれるゲーム内メニューが必要になります。
私のアプリでは、新しいゲームの起動、保存、読み込み、オプションの変更などの機能を持つ「MenuActivity」を作成しました。次に、私のGameActivityと同様に、HomeActivityがそれを拡張します。
すべてが1つのアクティビティクラスにあるため、アクティビティクラスの階層を作成し、プライベート、保護、およびデフォルトのスコープロットを使用することをお勧めします。このようにすると、少なくとも物事を別のファイルに分割して、1つの管理不可能なアクティビティファイルを作成しないようにすることができます。たとえば、自分のアプリの場合:
GraphicsEngine extends MenuActivity
。
PhysicsEngine extends GraphicsEngine
。
GameLogicActivity extends PhysicsEngine
。
UIActivity extends GameLogicActivity
。
私のアプリは3D opengl-esであるため、私が行う多くのことはクロスアクティビティで機能しないため、すべてが同じアクティビティ内にあるため、1つのアクティビティアーキテクチャを使用する傾向がある
-
スレッディング
ゲームアクティビティについては、2つのスレッドがあります(3D openglを実行している場合は3つ)。1つのスレッドはUI /メインスレッドです。これは、アクティビティが開始および実行されるスレッドであり、Androidによって提供されます。
このUIスレッドは、UI要素(ビュー、レイアウトなど)を更新できる唯一のスレッドです。また、ユーザー入力のリスナーが実行されるスレッドでもあります。UIスレッドのメカニズムは表示されません。バックグラウンドのどこかでループで実行されるだけです。
2番目のスレッドは自分で作成します(すべての欠点にもかかわらず、AsyncTaskを使用することをお勧めします)。これは、動きの更新、衝突の計算、戦闘の計算など、通常のゲームループで行うUI以外のすべての処理を実行します。
このAsyncTaskスレッド/クラスをアクティビティの内部クラスとして作成します。そうすることでVector<Spaceship>
、UIスレッドとゲームループスレッドの両方からアクセスできる、いくつかのアクティビティ全体にわたるオブジェクト()を作成できます。
ゲームロジックはゲームループスレッドで実行されているため、変数の値を実際に変更する必要がある唯一のスレッドです(タンクの速度を更新し、プレイヤーのHPを減らします)。UIスレッドは値を読み取るだけなので、同時実行の問題は最小限に抑えられます。
トリッキーなビットは、UIスレッドがゲームループスレッドの要求に応じて更新を行うようにすることです。これを行うにはいくつかの方法があります。AsyncTaskのドキュメントを読むと、publishProgress()/ onProgressUpdate()メソッドが含まれています。これは実際に、UIスレッドの次のループを実行するためのキューにアイテムを追加しています。
Handlerはまったく同じことを行います。ここで、handleMessage()メソッドを実装し、そのメソッドは、UIスレッドの次のループによって実際に実行されます。
最後に、UIスレッド内にあるユーザー入力は、UI要素をすぐに更新できます(そのため、onClick / onTouchリスナーの実装内)。ゲームオブジェクトを更新する必要がある場合は、同期などを使用するか、UIスレッドのように独自の更新キューをAsyncTaskに実装して、次にゲームループを実行するときに実行することができます。
Androidスレッディングガイド。
-
UI
単一のアクティビティ内の実際のUI構造については、基本レイアウトとしてフレームレイアウトを使用することをお勧めします。フレームレイアウトの子要素は、キューのように機能します。最初の要素が最初に描画され、2番目の要素が最初に描画され、3番目が2番目に描画されます。
このようにして、複数のXMLレイアウトファイルを作成し、フレームレイアウトの子を管理することで、ビューのセットを簡単に入れ替えることができます。
常に下部にSurfaceViewがある場合(フレームレイアウトの最初の子)、通常のすべてのAndroidビュー/ウィジェット(ボタン、テキストビュー、スクロールビュー)などを、サーフェスビューの上部で使用できます。ゲームのグラフィック部分。
たとえば、何かが読み込まれている場合は、ゲームループを一時停止するか、すべてをスキップして、不透明な「読み込み」画面をフレームレイアウトの最後の子として追加すると、画面に「読み込み」が表示されます。 、他のビューがその背後にあることをまったく認識していません。これにより、設定に時間がかかるビューを追加したり、追加/削除するたびに複雑なビューを削除したりする必要がなくなります。
View.setVisibilityロットの使用もお勧めします。たとえば、 'inventory'レイアウト全体をベースフレームレイアウトに追加し、ユーザーがクリックして在庫を表示するときにsetVisibility(View.Visible)を追加し、ユーザーが再び在庫を表示するときにsetVisibility(View.Gone)を追加することができます。そうすれば、フレームレイアウトの子を管理するだけでなく、すべてを追加して、ユーザーが異なることを行ったときに、物を表示/非表示にすることもできます
これは再びスレッド化するのに役立ちます。ユーザーがクリックしてインベントリを開くと、onCLickListenerがUIスレッドで処理され、そこにインベントリが表示され、すべてのゲームオブジェクトのゲッターのみが呼び出されて、UIスレッドからupdateInventoryメソッドが呼び出されます。
これは、単一のアクティビティ/フレームレイアウトのアイデアに関する以前の質問に対して作成した図です。