Java LibGDX - 在加载屏幕之前黑屏出现很长时间
Java LibGDX - Black Screen Appears for a Stupid Long Period Before Loading Screen
我正在 LibGDX/Java 创建游戏。游戏启动时,它会加载 "assets" 文件夹中的所有资产。在执行此操作之前,它加载一个图像以在资产加载时用作加载图像。这在桌面上运行良好,但在 android 上启动时,黑屏将显示大约 30 秒,然后绘制加载图像并开始加载资产。
我目前的代码如下:
LoadingState.java:
public void render(SpriteBatch batch) {
if (!loadedBg) {
GameManager.getInstance().assetManager.finishLoadingAsset("gui/constant/menuBg.png");
loadedBg = true;
}
Texture background = gameManager.assetManager.get("gui/constant/menuBg.png", Texture.class); // Set background image
/* Drawing */
batch.draw(background, 0, 0);
}
Assets.java:
/** Loads all assets from the asset directories */
public void load() {
List<FileHandle> allFiles = new ArrayList<FileHandle>(); // This will contain all the files in all the subdirectories.
for(FileHandle dir : assetDirs) {
allFiles.addAll(FileUtils.listf(dir.path()));
}
for(int i = 0; i < allFiles.size(); i++) {
if(allFiles.get(i).name().startsWith("._")) {
allFiles.remove(i);
}
}
/* Iterate through all the files and load only the png ones */
for(FileHandle f : allFiles) {
if(f.name().endsWith(".png")) { // Found an image file; load it as a texture
manager.load(f.path(), Texture.class);
}
}
}
编辑:
添加了 FileUtils class
FileUtils.java:
/** Returns all files from a directory */
public static List<FileHandle> listf(String directoryName) {
FileHandle directory = Gdx.files.internal(directoryName);
List<FileHandle> resultList = new ArrayList<FileHandle>();
// Get all the files from a directory
FileHandle[] fList = directory.list();
resultList.addAll(Arrays.asList(fList));
for (FileHandle file : fList) {
if (file.isDirectory()) {
resultList.addAll(listf(file.path()));
}
}
return resultList;
}
这是整个 android 应用程序的问题吗?或者只有 LibGDX?我在开发早期没有遇到这个问题。感谢您提供任何帮助,谢谢!
我最好的猜测是在 Android 上调用目录 list()
非常慢,因为它从压缩的 apk (see here) 中读取文件,所以如果你的assets目录有很多子目录,很占时间。
简单的解决方案是在 render()
方法返回一次(大概已经绘制加载屏幕)之前不调用您的 listf()
方法。但这并没有解决不必要的 30 秒等待。
由于资产文件夹中的文件在编译时是已知的,我建议编写一个脚本来扫描资产文件夹并创建一个列出所有路径的文本文件。您可以将此文件放在资产目录的根目录下,并在 listf
方法中读取它以快速获取文件路径列表。 Here's an example script. 在开发过程中,当您 运行 您的桌面版本时,您可以将此脚本设置为自动 运行。
我正在 LibGDX/Java 创建游戏。游戏启动时,它会加载 "assets" 文件夹中的所有资产。在执行此操作之前,它加载一个图像以在资产加载时用作加载图像。这在桌面上运行良好,但在 android 上启动时,黑屏将显示大约 30 秒,然后绘制加载图像并开始加载资产。
我目前的代码如下:
LoadingState.java:
public void render(SpriteBatch batch) {
if (!loadedBg) {
GameManager.getInstance().assetManager.finishLoadingAsset("gui/constant/menuBg.png");
loadedBg = true;
}
Texture background = gameManager.assetManager.get("gui/constant/menuBg.png", Texture.class); // Set background image
/* Drawing */
batch.draw(background, 0, 0);
}
Assets.java:
/** Loads all assets from the asset directories */
public void load() {
List<FileHandle> allFiles = new ArrayList<FileHandle>(); // This will contain all the files in all the subdirectories.
for(FileHandle dir : assetDirs) {
allFiles.addAll(FileUtils.listf(dir.path()));
}
for(int i = 0; i < allFiles.size(); i++) {
if(allFiles.get(i).name().startsWith("._")) {
allFiles.remove(i);
}
}
/* Iterate through all the files and load only the png ones */
for(FileHandle f : allFiles) {
if(f.name().endsWith(".png")) { // Found an image file; load it as a texture
manager.load(f.path(), Texture.class);
}
}
}
编辑: 添加了 FileUtils class FileUtils.java:
/** Returns all files from a directory */
public static List<FileHandle> listf(String directoryName) {
FileHandle directory = Gdx.files.internal(directoryName);
List<FileHandle> resultList = new ArrayList<FileHandle>();
// Get all the files from a directory
FileHandle[] fList = directory.list();
resultList.addAll(Arrays.asList(fList));
for (FileHandle file : fList) {
if (file.isDirectory()) {
resultList.addAll(listf(file.path()));
}
}
return resultList;
}
这是整个 android 应用程序的问题吗?或者只有 LibGDX?我在开发早期没有遇到这个问题。感谢您提供任何帮助,谢谢!
我最好的猜测是在 Android 上调用目录 list()
非常慢,因为它从压缩的 apk (see here) 中读取文件,所以如果你的assets目录有很多子目录,很占时间。
简单的解决方案是在 render()
方法返回一次(大概已经绘制加载屏幕)之前不调用您的 listf()
方法。但这并没有解决不必要的 30 秒等待。
由于资产文件夹中的文件在编译时是已知的,我建议编写一个脚本来扫描资产文件夹并创建一个列出所有路径的文本文件。您可以将此文件放在资产目录的根目录下,并在 listf
方法中读取它以快速获取文件路径列表。 Here's an example script. 在开发过程中,当您 运行 您的桌面版本时,您可以将此脚本设置为自动 运行。