ゲームエンジンのシーンシステムを作成する

まえがき



現在、私は自分のゲームエンジンに取り組んでいます。 最小限の数のサードパーティライブラリを使用して、ゲームループ(ゲームループ)の実装、フレームのレンダリング、「更新」機能、テクスチャのロードなどを行うと、エンジンの主な「充填」の準備が整いました。 もう1つの重要なコンポーネント-シーン(シーン)を実装するときが来ました。



はじめに



この記事では、エンジンにはすでに「コールバック」機能を備えたゲームループが装備されていると想定しています。 すべてのコードはJavaで記述されますが、 ガベージコレクションをサポートする他の言語に簡単に移植できます。 さあ、始めましょう。



すでにそこにあるもの



前述のように、すでにゲームループがあります。 次のようにします。



void awake() { RenderUtil.init(); //   OpenGL run(); } void run() { // game loop // ... //  input,  frame rate  . . // if (Window.isCloseRequested()) { //    stop(); return; } update(); render(); }
      
      





後でrender()およびstop()メソッドの実装を提供します。



シーンを定義する



シーンのクラスを書き始める前に、それがどうなるかを決める必要があります。 私の場合、これは多くのゲームオブジェクトを含むオブジェクトです。 少し読んで休憩して、あなたの周りを見てみましょう。私たちはあなたが見る(ほぼ)ゲームオブジェクト、そしてあなたがいる場所をすべてシーンと呼びます。



ゲームオブジェクトとはどういう意味ですか? これは、ゲームループの「コールバック」機能を実装するオブジェクトです。 Unity3Dに精通している人向け :クラスがMonoBehaviourを実装するオブジェクトとの類推。



この同じゲームオブジェクトをインターフェイス(または目的の機能に応じて抽象クラス)で表し、 GameListenerを呼び出します (この記事でも、このクラスは既に何らかの方法で実装されています)。

プリミティブインターフェイスの実装は次のようになります。



 public interface GameListener { void start() ; // ,    void update(); //    void draw(); //  update() void destroy(); // ,   "" }
      
      





機能の数は、望ましい制御の程度に依存します 。たとえば、Unity3D には多くの機能があります



クラスSceneを実装します



シーンのアーキテクチャと構造を定義したら、最終的にその実装に進むことができます。



 public abstract class Scene implements GameListener { ArrayList<GameListener> gameListeners = new ArrayList<>(); public abstract void initializeScene(); public final void AddToScene(GameListener gameListener) { gameListeners.add(gameListener); } public final void onInitializeScene() { if (gameListeners.isEmpty()) initializeScene(); } @Override public final void start() { for (GameListener gameListener : gameListeners) gameListener.start(); } @Override public final void update() { for (GameListener gameListener : gameListeners) gameListener.update(); } @Override public final void draw() { for (GameListener gameListener : gameListeners) gameListener.draw(); } public final void onDestroy() { for (GameListener gameListener : gameListeners) gameListener.destroy(); gameListeners.clear(); } @Override public final void destroy() {}
      
      





私はアイテムにコメントを書きます:





すべてのメソッド(自然にinitializeScene()を除く)がfinalキーワードでマークされているため、Sceneクラスではエンジンのユーザーは自分のゲームオブジェクトのみを追加できます(この制限はこれまでのところ適しています)。



ゲームサイクルの変革



ここで、ゲームループで変換を実行する必要があります。 実際、それらはすべて直感的です。



 Scene runningScene; void awake() { RenderUtil.init(); runningScene = SceneManager.getScene(0); run(); } void run() { if (Window.isCloseRequested()) { stop(); return; } runningScene.update(); runningScene.render(); } void stop() { runningScene.onDestroy(); } void render() { runningScene.draw(); }
      
      





作成したすべてのシーンを、たとえばSceneManagerというクラスに含まれる配列に追加できます。 その後、シーンシステムによってコントローラーとして機能し、 getScene()setScene()メソッドなどを提示します。



この段階では、システムの実装は「ステータス」パターンに非常に似ています。 そうです。



シーンチェンジ



シーンを変更するには、SceneManagerでSceneクラスの同様のインスタンスを定義できます。



private static Scene currentScene;









次に、 setter setCurrentScene(Scene)を記述します。



public static void setCurrentScene(Scene scene) { currentScene = scene; }









次に、ゲームループでrunningScenecurrentSceneを比較し、一致しない場合はシーンを変更します。



 void run() { if (Window.isCloseRequested()) { stop(); return; } runningScene.update(); if (runningScene != SceneManager.getCurrentScene()) { runningScene.onDestroy(); runningScene = SceneManager.getCurrentScene(); } runningScene.render(); }
      
      





現在のシーンのonDestroy()メソッドを呼び出してゲームオブジェクトを削除することを忘れないことが重要です。



添加剤添加の実施



同じUnity3D には、 「追加の」読み込みシーンの可能性があります。 このメソッドでは、「古い」シーンのオブジェクトは削除されず(この場合、 onDestroy()メソッドは呼び出されません)、新しいシーンは古いシーンの「上」にロードされます。



これは、たとえば、追加的にロードされたシーンのリストを保存するコンテナを作成することで実現できます。 その後、挑戦とともに



runningScene.update();









あなたは次のようなことを言う必要があります



for (Scene additive : additives)

additive.update();









などなど。



OnDestroy()は、 メインシーンの再起動/変更(runningScene)またはゲームを閉じる場合に呼び出す必要があります。



アーキテクチャ、ゲームオブジェクトを追加する手順、およびシーン自体は同じままです。



All Articles