问题描述
我想使用 AssetManager 直接从扩展 OBB 文件加载文件.我实现了自己的 FileHandleResolver
I would like to load files directly from expansion OBB file by using AssetManager. I implemented my own FileHandleResolver
public class CustomFileHandleResolver implements FileHandleResolver
{
@Override
public FileHandle resolve(String fileName) {
return new CustomFileHandle(fileName);
}
}
我将它设置为我的 AssetManager.我创建了自己的 FileHandle 并覆盖了 read() 函数
I set it to my AssetManager. I created my own FileHandle and I override read() function
@Override
public InputStream read()
{
InputStream input = null;
try {
input = GameInfo.expansionFile.getInputStream(file.getPath().replace('\', '/'));
} catch (IOException e) {
e.printStackTrace();
}
return input;
}
它会加载所有文件,如 .PNG、.PACK、.FNT,除了 .OGG 文件,所以我猜所有声音文件都不会被加载.我收到此错误:
It loads all the files like .PNG, .PACK, .FNT, except .OGG files, so I guess that all sound files won't be loaded. I'm getting this error:
com.badlogic.gdx.utils.GdxRuntimeException: com.badlogic.gdx.utils.GdxRuntimeException: Couldn't load dependencies of asset: SFx/button_click.ogg
还有这个错误:
com.badlogic.gdx.utils.GdxRuntimeException: java.lang.ClassCastException: com.solidgamesstudio.threedefendersn.framework.CustomFileHandle cannot be cast to com.badlogic.gdx.backends.android.AndroidFileHandle
我读到 zip 无法压缩.在 7zip 中,我选择压缩到存储",这样它就根本不被压缩,但仍然会出现这个问题.
I read that zip can not be compressed. In 7zip I selected compression to "Store" so that it's not compressed at all, but still this problem occurs.
我遍历了加载文件时发生的情况,发现 AssetManager 调用了我的 CustomFileHandleResolver
,它创建了 CustomFileHandle
.对于每个不是 .OGG 的文件,它都会调用 InputStream read()
.在此函数中,它从 zip 加载文件,这很好.但正如我所说,在加载 .OGG 时,它不会调用此函数.所以它甚至还没有尝试从 zip 中获取文件.问题是,为什么 .OGG 文件不调用 CustomFileHandle()
中的 InputStream read()
?
I traversed what is happening when files are being loaded and I found that AssetManager calls my CustomFileHandleResolver
which creates CustomFileHandle
. For every file that is not .OGG it calls InputStream read()
. In this function it loads the file from the zip and it's fine. But as I said when it comes to loading .OGG it doesn't call this function. So it's not even trying yet to get the file from the zip. Question is, why .OGG file doesn't call InputStream read()
in CustomFileHandle()
?
更新
我遍历了更多,我发现它不会调用 InputStream read()
因为它无法以某种方式从 FileHandle 创建声音.线索是
I traversed more and I found out that it won't call InputStream read()
because it can't create a Sound from FileHandle somehow. Clue to this is
CustomFileHandle cannot be cast to AndroidFileHandle
在创建声音时,您需要传递 fileHandle.
While to create a sound you need to pass fileHandle.
public Sound newSound (FileHandle fileHandle);
这是从 SoundLoader
@Override
public void loadAsync (AssetManager manager, String fileName, FileHandle file, SoundParameter parameter) {
sound = Gdx.audio.newSound(file);
}
而且该 soundLoader 使用我的 CustomFileHandleResolver.我不知道声音的处理方式是否与其他类型的文件不同.但默认情况下 AssetManager 使用
And that soundLoader uses my CustomFileHandleResolver. I don't know if Sounds are handled differently then other types of files. But by default AssetManager uses
public class InternalFileHandleResolver implements FileHandleResolver {
@Override
public FileHandle resolve (String fileName) {
return Gdx.files.internal(fileName);
}
}
我无法进入 Gdx.files.internal
以查看是否对声音有任何特殊处理.
I can't get into Gdx.files.internal
to see if there are any special handling for Sounds.
更新
进一步的分析让我知道主要问题是前面提到的.
Further analysis give me clue that the main problem is this as mentioned before.
CustomFileHandle cannot be cast to AndroidFileHandle
我不知道为什么它在加载 OGG 文件时将我的 FileHandle 转换为 AndroidFileHandle.如果它加载了其他类型的文件,那可能意味着它不会为它们进行转换.这意味着 OGG 是特殊的,它需要铸造.有什么线索吗?
I don't know why it's casting my FileHandle to AndroidFileHandle while loading OGG file. If it loads fine other type of files, that probably means it doesn't do casting for them. That means that OGG is special and it needs casting. Any clues?
推荐答案
嗯,我现在正在做这个.每当您需要获得 real FileHandle
以使声音加载机制起作用(或者在任何其他情况下,转换为 AndroidFileHandle
是打扰您),将该文件解压缩到本地目录并在需要时重新使用它:
Well, I'm doing this currently. Whenever you need to get a real FileHandle
in order for the sound loading mechanism to work (or in any other case were the casting to AndroidFileHandle
is bothering you), unzip that file to a local directory and reuse it if needed:
public static FileHandle getRealFileHandle(String zipEntryPath, ZipFile zipFile) {
if (Gdx.files.local(zipEntryPath).exists()) {
return Gdx.files.local(zipEntryPath);
} else {
Gdx.app.log(TAG, "Unzipping file '" + zipEntryPath + "'...");
try {
FileHandle unzippedFile;
ZipEntry entry = zipFile.getEntry(zipEntryPath);
if (entry != null) {
unzippedFile = Gdx.files.local(zipEntryPath);
InputStream is = zipFile.getInputStream(entry);
byte[] buffer = new byte[65536];
int readLength;
while ((readLength = is.read(buffer)) >= 0) {
unzippedFile.writeBytes(buffer, 0, readLength, true);
}
return unzippedFile;
} else {
Gdx.app.error(TAG, "Entry '" + zipEntryPath + "' not found inside zip file.");
}
} catch (IOException ioe) {
Gdx.app.error(TAG, "A problem occurred while writing to the local file.");
}
}
return null;
}
这篇关于无法加载声音文件 LibGdx的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!