长篇故事: 我试图在LibGDX中创建一个加载屏幕,不仅需要加载纹理和音频等资源,我还需要创建世界对象(超过1000万个对象) - 我可能想要查看减少的对象数量未来,但我的问题仍然适用于它是一个对象还是数万亿。
在对象初始化期间,由于我假设的延迟,GDX render()
方法停止。它将落后于整个应用程序进入的多少#34;没有响应"几秒钟。
我几个月来一直在研究,没什么好发现的。我找到的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,不会有任何延迟,因为繁重的进程不再存在 - 而是建立在重度进程分成迷你进程的基础上,解决了#34;没有响应"州。虽然这很多postRunnables对于干净的代码并不是很实用,因为它需要超过30个postRunnables,而上面的代码只是2.代码很容易变丑,因此我寻求替代方案。
This帖子也非常有趣,解释了我遇到的完全相同的问题,但结果并没有成功。
我通过两个线程在Java Swing中实现了这一点;一个main和一个loadScreen线程(LCThread)。当进入loadingScreen时,LCThread开始绘制loadingScreen,而主线程进行重处理。完成后,主线程使用它先前处理的对象。遗憾的是,我无法将其转换为LibGDX,因为两个线程无法单独绘制。
短篇小说:我需要编写一个加载屏幕来加载大量的后台处理(初始化很多对象),同时绘制进度(在render()
方法中处理)并播放音乐显示加载屏幕,所有这些都不会使应用程序滞后进入"没有响应"。
你有什么建议吗?
答案 0 :(得分:1)
你可以分解你的GameObject,以便释放处理器。希望这会加载块并保持渲染循环自由播放音乐。基本上所有加载和创建资产都通过AssetManager并在渲染循环中检查以查看游戏的状态并采取相应的行动。 自定义GameObject加载器。 GameObject只是一个泛型类,将其应用于您的项目specifecs。
在AssetManger update(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> {
}
}