Java Libgdx Actions.parallel不工作
我希望我的加载屏幕同时加载我的资源/生成字体,并显示加载屏幕的淡入淡出顺序 然而,Actions.parallel(…)似乎不起作用。如果我在添加几个System.out.println()后检查控制台,它清楚地表明这两个操作是按顺序执行的。运行代码时,我首先会看到一个黑屏,直到加载/生成资产,然后开始fadeIn/fadeOut操作 代码: }Java Libgdx Actions.parallel不工作,java,libgdx,Java,Libgdx,我希望我的加载屏幕同时加载我的资源/生成字体,并显示加载屏幕的淡入淡出顺序 然而,Actions.parallel(…)似乎不起作用。如果我在添加几个System.out.println()后检查控制台,它清楚地表明这两个操作是按顺序执行的。运行代码时,我首先会看到一个黑屏,直到加载/生成资产,然后开始fadeIn/fadeOut操作 代码: } 我缺少什么?Assets.manager.finishLoading()会阻止所有内容,直到加载所有资产。这就是为什么我相信你会有这种行为。除此之外,
我缺少什么?Assets.manager.finishLoading()会阻止所有内容,直到加载所有资产。这就是为什么我相信你会有这种行为。除此之外,你的行为似乎是正确的!如果你去掉这条线,我相信你会看到这两个动作实际上是平行的
您可以为loadAssets操作添加重复操作,并使用Assets.manager.update()直到更新所有资产。加载字体后,您可以从后台删除操作。更改
Assets.manager.finishload()
到Assets.manager.update()代码>这样它就不会阻塞线程来完成所有的加载。由于您希望它在完成之前反复调用update
,因此在update
返回true之前,您不希望返回true。因此,在加载完成之前,load
变量也应保持为true
您可以在匿名操作类中移动加载
、生成器
和参数
声明,因为这是您唯一需要它们的地方。下面,我将load
倒置,并将名称更改为done
,以减少歧义
最后,您不想一次又一次地重新创建字体生成器。您可以使用switch语句分解要加载的内容序列。切换的最后一部分可能是对资产管理器的重复调用。现在,每次对操作调用act
(每帧一次),它将只执行其中一个步骤,而不是所有步骤
Action loadAssets = new Action(){
private boolean done = false;
private int steps = 0;
private FreeTypeFontGenerator generator;
private FreeTypeFontParameter parameter;
@Override
public boolean act(float delta){
if(!done){
switch (steps){
case 0:
generator = new FreeTypeFontGenerator(Gdx.files.internal("res/fonts/TUNGAB.TTF"));
parameter = new FreeTypeFontParameter();
steps++;
break;
case 1:
//generate first font
steps++;
break;
case 2:
//generate second font
steps++;
break;
case 3:
//and so on
steps++;
break;
case 4:
generator.dispose();
steps++;
break;
case 5:
done = Assets.manager.update();
break;
}
}
return done;
}
};
我和你面临着同样的问题
编辑不完全是这样,因为您不一定希望并行运行,只希望您的UI线程不会冻结。在这种情况下,您可以在此处找到答案:
更具体地说,这段代码:
public void render() {
if(manager.update()) {
// we are done loading, let's move to another screen!
}
// display loading information
float progress = manager.getProgress()
... left to the reader ...
}
我认为这会在每次调用update()
时加载一点资产。直到完成加载所有内容。这是必要的,因为加载纹理需要OpenGL上下文(即,必须在主线程上完成)
不过,您可以使用下面的代码在单独的专用线程中加载非OpenGL资产
“旧”答案:
因此,我创建了以下简单类:
public abstract class ReadyRunnable implements Runnable {
/**
* Flag whether we're ready
*/
protected boolean ready = false;
/**
* Are we ready yet?
*
* @return
*/
public final boolean isReady() {
return this.ready;
}
/**
* Method run when {@link ReadyRunnable#run()} is done
*/
public abstract void ready();
}
它用于我的加载屏幕,如下所示:
public class LoadScreen extends BaseScreen {
private ReadyRunnable runner;
[...] // Create a nice loading bar etc.
public void render() {
if(runner.isReady()) runner.ready();
}
}
然后,当我需要加载某些内容时:
this.setScreen(new LoadScreen(new ReadyRunnable() {
public void run() {
// Do your loading here in parallel (outside the UI thread)
this.ready = true;
}
public void ready() {
// This actually runs in the main thread!
}
}));
当然谢谢你的更正,先生。然而,我仍然没有得到我想要的行为。我将代码更改为,但控制台打印以下顺序:生成、开始字体生成、结束字体生成、序列、生成、序列、生成、序列、生成、序列。。。但是我希望它在字体生成操作时启动sequenceAction。parralel实际上不在parralel中运行操作。请看这里:它只是将它们组合起来,并在每个帧上运行“act”,直到它们全部完成。例如,当你希望某个东西同时反弹并变黄时。那么我必须创建一个新线程并在后台加载我的资源?是的,但不幸的是,对于图形资源,你需要OpenGL所在的主线程。因此,在我的用例中,我从互联网下载了图像,并将它们加载到主线程中的GPU中。请参阅下面的我的答案。问题是,我的加载屏幕徽标的fadeIn效果会出现口吃。它不是连续的。我认为这是因为这些步骤可能会被打断,从而导致口吃。我没有使用FreeTypeFontGenerator,但我想生成每种字体都需要一段时间,这会导致口吃。我建议删除此操作中的字体生成,并在并行资产管理器和淡入操作后按顺序运行新操作。一旦徽标淡入,屏幕不会改变,因此您可以允许字体阻止线程并一次加载,就像以前一样。因此,您的操作变得类似于序列(并行(loadAssets,fadeIn(0.4f)),loadFonts,fadeOut(0.4f),completeAction)
。新序列:序列(alpha(0)、fadeIn(0.4f)、loadAssets、fadeOut(0.4f)、completeAction)loadAssets操作生成字体并调用Assets.manager.finishLoading()
this.setScreen(new LoadScreen(new ReadyRunnable() {
public void run() {
// Do your loading here in parallel (outside the UI thread)
this.ready = true;
}
public void ready() {
// This actually runs in the main thread!
}
}));