我在加载屏幕中使用非连续渲染,因此我可以更新它,因为我在辅助线程中输入了我的代码的不同部分。这样我就可以手动增加我用来绘制Sprite的动画计数器,该Sprite显示与我的资产加载一致的填充沙漏。
所以,我在另一个线程(地图集,纹理,初始化变量等)的帮助下加载我的游戏画面:
Runnable load_game_screen = new Runnable(){
public void run(){
new_game_screen.load_all();
}
}};
Thread thread_load_game = new Thread(load_game_screen);
thread_load_game.start();
在我的游戏屏幕 load_all 功能中,我使用 Gdx.app.postRunnable 在主UI线程的下一个渲染上运行这些初始化,所以我不会得到任何上下文错误:
public void load_all(){
Gdx.app.postRunnable(new Runnable(){
@Override
public void run(){
...load stuff
loading_screen.loading_counter += 0.025f;
loading_screen.loadingTimerSprite.setRegion(loading_screen.animation.getKeyFrame(loading_screen.loading_counter, true));
}
Gdx.graphics.requestRendering();
Thread.sleep(25);
Gdx.app.postRunnable(new Runnable(){
@Override
public void run(){
...load stuff part2
loading_screen.loading_counter += 0.025f;
loading_screen.loadingTimerSprite.setRegion(loading_screen.animation.getKeyFrame(loading_screen.loading_counter, true));
}
Gdx.graphics.requestRendering();
Thread.sleep(25);
... etc ...
}
问题是 requestRendering 没有立即行动,有时 postRunnables 会一个接一个地运行,而不会立即进入主UI渲染功能,因此用户无法看到加载精灵的完整动画;它发生在跳跃中。我如何从正在加载代表主线程的资产和变量的辅助线程强制主UI线程中的渲染?
答案 0 :(得分:2)
如果加载速度比帧时间快(例如,如果加载步骤的速度超过每秒60步),用户将无法看到所有动画步骤。这对我来说听起来不错!
但是,如果你想确保显示动画的所有步骤,我认为你的后台线程应该只设置一个“目标”动画帧,渲染线程应该将实际帧提前一,直到目标是击中。它可以像这样运作:
target = 10
(并请求呈现)target = 11
(并请求渲染)。这样两者可以按照自己的节奏进行。如果你想快速加载,渲染线程只能绘制目标框架。如果你想显示每一帧,它可以突然1。
一个注意事项:发布runnable将隐式请求渲染。
其次,它看起来像所有你的“后台”线程中的工作是在发布的runnables中完成的(这可能是真的,因为大多数加载需要OpenGL上下文),但也许它只是因为您简化了发布问题的代码。无论如何,如果这是真的,那么它只是在渲染线程上运行所有内容的一种尴尬方式。您可能最好设置一个简单的状态机,并让渲染线程逐步执行它以直接运行您的加载过程:
if (! done) {
switch(loadingStep) {
case 0:
// step 0 code
break;
case 1:
// step 1 code
break;
case 2:
...
case 10:
done = true;
break;
}
loadingStep++;
}
这样做的好处是每个渲染只运行一步。