2017-10-12 26 views
0

長い物語: 私はLibGDXでロード画面を作成しようとしているだけでなく、私はテクスチャやオーディオなどの資産をロードする必要があります、私は世界のオブジェクト(10以上を作成する必要があります何百万ものオブジェクト) - 将来的にオブジェクトの量を減らすことを検討したいかもしれませんが、それが1つのオブジェクトであろうと何兆であろうと、私の質問はまだ適用されます。LibGDXローディング画面

オブジェクトの初期化中、GDX render()メソッドが遅れているために停止します。アプリケーション全体が数秒間「応答しない」状態になるほど遅くなります。

私は数ヶ月間ずっと研究していません。私が見つけたトピックや私が尋ねる人々の90%は、常に同じことを言っています。 AssetManagerを使用します。私はこれを試しましたが、重い処理世界のオブジェクトではなく、資産のみをサポートするようです。誰かがカスタムクラスをサポートできると私に言いましたが、ドキュメントの不足のためにこれを動作させることはありませんでした。

私に最も似ている最高の話題はoneで、これはGdx.app.postRunnable()をGdx.app.postRunnable()内で使用するアイデアを与えました。結果は次のとおりです。

Gdx.app.postRunnable(new Runnable() { 
    @Override 
    public void run() { 

     // do some heavy processing 
     // set loading screen percent to x% 

     Gdx.app.postRunnable(new Runnable() { 
      @Override 
      public void run() { 

       // do some more heavy processing 
       // set loading screen percent to y% 

      } 
     }); 

    } 
}); 

解決策は素晴らしいです。それは重い処理を行い、ローディングスクリーンのパーセントを設定し、それを描いた。だから、表示するために、この解決策は決して描かれなかった私の問題を解決しました。しかし、このソリューションは依然としてアプリケーションを重いプロセス間で「応答しない」状態にします。これは最終的な音楽の再生をフリーズさせます。

postRunnablesの内部に十分なpostRunnablesを追加することで、重いプロセスが存在しなくなるため、ラグは発生しません。代わりに、重いプロセスがミニプロセスに分割され、「応答しない」状態が解決されます。しかし、この多くのpostRunnablesは30以上のpostRunnableを必要とするため、 "クリーンコード"にはあまり実用的ではありませんが、上記のコードは2です。コードが醜いほど簡単です。

Thisポストも非常に面白かったし、私が直面している全く同じ問題を説明しているが、結果はうまくいかなかった。

私はJava Swingでこれを2つのスレッドで実現しました。 1つのメインスレッドとloadScreenスレッド(LCThread)。 loadingScreenに入ると、LCThreadはloadScreenを描画し始め、メインスレッドは処理を重視しました。終了すると、メインスレッドは以前に処理したオブジェクトを使用しました。残念ながら私は2つのスレッドが別々に描画することができないので、これをLibGDXに変換することはできません。

短編小説:私はすべての遅れなしに、ロード画面を表示しながら(render()方法で取り扱わ)進捗状況を描画し、音楽を再生しながら、重いバックグラウンド処理(オブジェクトの多くを初期化)をロードするロード画面をコーディングする必要があります「応答していない」と多く入力するアプリケーション

アドバイスをありますか?

答えて

1

GameObjectを分解してプロセッサを解放することができます。うまくいけば、これはチャンクに読み込まれ、レンダーループを自由にして音楽を再生できるようにします。基本的に、すべての読み込みおよび作成アセットはAssetManagerを経由し、レンダリングループでは、ゲームの状態を確認してそれに応じて動作します。 カスタムGameObjectローダー。 GameObjectは、ジェネリッククラスに過ぎません。あなたのプロジェクトにこれを適用します。

AssetMangerの更新(int millis)メソッドでは、指定されたミリ秒数のCPUが生成されます。すべての処理を分割してAssetLoadersに入れると、その時点でAssetManagerが更新され、CPUをブロックしません。

public class GameObjectLoader extends SynchronousAssetLoader<GameObject, GameObjectLoader.GameObjectParameters> { 

    public GameObjectLoader(FileHandleResolver resolver) { 

     super(resolver); 
    } 

    @Override 
    public GameObject load(AssetManager assetManager, String fileName, FileHandle file, GameObjectParameters parameter) { 

     TextureAtlas atlas = assetManager.get(parameter.src, TextureAtlas.class); 
     ShaderProgram shaderProgram = assetManager.get(parameter.shaderSrc, ShaderProgram.class); 
     JsonValue json = assetManager.get(parameter.jsonSrc, JsonValue.class); 
     Calculation calculation = assetManager.get(parameter.id, Calculation.class); 

     GameObject gameObject = new GameObject(
      atlas.findRegion(parameter.name), 
      shaderProgram, 
      json, 
      calculation 
     ); 

     assetManager.unload(parameter.id); // unload it otherwise it stays in memory 

     return gameObject; 
    } 

    @Override 
    public Array<AssetDescriptor> getDependencies(String fileName, FileHandle file, GameObjectParameters parameter) { 

     Array<AssetDescriptor> dependencies = new Array<AssetDescriptor>(); 

     dependencies.add(new AssetDescriptor<TextureAtlas>(parameter.src, TextureAtlas.class)); 
     dependencies.add(new AssetDescriptor<ShaderProgram>(parameter.shaderSrc, ShaderProgram.class, parameter.shaderParameter)); 
     dependencies.add(new AssetDescriptor<JsonValue>(parameter.jsonSrc, JsonValue.class)); 
     dependencies.add(new AssetDescriptor<Calculation>(parameter.id, Calculation.class)); 

     return dependencies; 
    } 


    public static class GameObjectParameters extends AssetLoaderParameters<GameObject> { 

     // maybe you have a lot of game logic and dont need to load everything from disk make a custom loader for that too 
     public String id = ""; 
     public String src = ""; 
     public String name = ""; 
     public String jsonSrc = ""; 
     public String shaderSrc = ""; 
     public ShaderProgramLoader.ShaderProgramParameter shaderParameter = null; 
    } 
} 

AssetLoadersは、それを使用するファイルを持っている必要はありません。

class CalculationLoader extends SynchronousAssetLoader<Calculation, AssetLoaderParameters<Calculation>> { 

    public CalculationLoader(FileHandleResolver resolver) { 

     super(resolver); 
    } 

    @Override 
    public Calculation load(AssetManager assetManager, String fileName, FileHandle file, AssetLoaderParameters<Calculation> parameter) { 

     // this is the heavy processing 
     // the AssetManager dictates how many of these per cycle will be calculated 
     return new Calculation(); 
    } 

    @Override 
    public Array<AssetDescriptor> getDependencies(String fileName, FileHandle file, AssetLoaderParameters<Calculation> parameter) { 

     return null; 
    } 

    public static class CalculationParameters extends AssetLoaderParameters<Calculation> { 


    } 
} 
+0

ありがとうございました。前述のように、オブジェクトの初期化や数学計算のような膨大な処理を行っているので、「資産」(テクスチャ、オーディオ、シェーダ)のロードは主要な悪役ではありません。私はこれをAssetManagerにマージする方法をよく理解していない – Squiddie

+0

AssetManagerは、サイクルあたりの資産の数がロード/計算されるため、CPUをブロックしないようにAssetManagerが指示する答えを編集しました。 – Tejay

+0

これは有望そうです。しかし、結果は同じでしたが、私はあなたに誤解しているかもしれません。 「すべての処理を中断する」とはどういう意味ですか?複数のAssetLoaderがあることを意味しますか?私のテストでは、1つしかありませんでした – Squiddie

関連する問題