Libgdx: AssetManager无法加载资源

5

嗨,我在使用libgdx的AssetManager时遇到了困难。我已经跟随每个教程,阅读了每个维基页面,但我无法让它工作。

资源类:

public class Assets {

private static final AssetManager manager = new AssetManager();
public static final String background = "data/lawn.png";
public static void load() {

    manager.load(background, Texture.class);

}
public static void dispose()     {
    manager.dispose();
}

public static boolean update() {
    return manager.update();
}

主类:

public class TombStone extends Game implements Screen {
@Override
public void create () {

    Assets.manager.update();



}

我在Screen类中使用以下方式命名我的纹理:

public class StoneScreen implements Screen{
public Texture texture;
public StoneScreen(TombStone gam){
loadStandard();
}
public void loadStandard() {
texture= Assets.manager.get(Assets.background, Texture.class);
}

当我运行应用程序时,它会在显示任何内容之前崩溃,并给出以下错误提示:"FATAL EXCEPTION: GLThread 32182" "Asset not loaded: assets/data/lawn.png"。

通常情况下,您不需要将 assets/ 包含在路径中。它希望路径是相对于资产目录的。而且不要使您的 AssetManager 引用静态化,否则会导致内存泄漏和纹理损坏。 - Tenfour04
我不同意这个观点。在我所有的游戏中,我都使用静态AssetManager,并且它运行得非常好。只要正确实现生命周期方法并在适当的时候执行Assets.manager.dispose(),就不会引起任何问题。此外,这非常方便! - noone
3个回答

7

你的代码存在很多问题...

public class Assets {

public static final AssetManager manager = new AssetManager(); // 1)
public static final String background = "assets/data/lawn.png"; // 2)
public static void load() {

    manager.load(background, Texture.class);
    manager.get(background, Texture.class); // 3)
}
public static void dispose()     {
    manager.dispose();
}

public static boolean update() {
    return manager.update();
}

public class TombStone extends Game implements Screen { // 4)
@Override
public void render () {
    //assets.manager.update();
    Assets.load(); // 5)
    Assets.manager.update();
    super.render();
}

1) 你的经理是public的,但你仍然提供其他方法来操作它(例如更新和处理)。将其设为私有或删除这些方法,直接在Assets.manager上进行操作。

2) 资源文件相对于assets目录。因此应该为data/lawn.png

3) 这就是为什么会出现异常。 AssetManager.load()只是标记需要加载的资源,但不会立即加载它们。这就是AssetManager.update()(异步)或AssetManager.finishLoading()(同步)所做的事情。如果你在实际加载之前尝试使用AssetManager.get(),就会出现这个异常。只需删除此行。

4) 扩展Game实现Screen是没有意义的。一次只能选择其中一种。游戏有屏幕,但它本身不是屏幕。

5) 你重复地标记要加载的资源。 render()每帧都会被调用。将Assets.load()移动到Screen.show()方法中,该方法仅在执行一次。


谢谢指出这些问题。已经解决了。但问题仍然存在。还有其他可能出错的地方吗? - Benni
你仍然收到这个异常吗?请将代码更新到当前状态。 - noone
在create()中,你需要执行Assets.load而不是update。 - noone
我建议你阅读关于AssetManager的维基文章。看起来所有你读过的那些教程都是完全错误的,因为你似乎不知道它是如何工作的。 - noone
@noone 同时,在 Android 上制作静态 AssetManager 通常是不好的做法。 - trolley813

0

我知道这个问题之前已经被问过(并且部分回答了),但是我会提供我的解决方法。 在你的渲染方法中,加入以下内容:

if (!assetManager.update()) return;

如果尚未更新资产管理器,则应执行此操作,并防止渲染未加载的纹理。


0

AssetManager 可以同步和异步工作。

  • 异步加载:在加载资源时,您可以显示一个进度条。这是异步的,因为您在后台加载资源同时更新屏幕。您需要不断调用assetManager.update()(作为游戏循环的一部分),直到所有资源都加载完成,这样才能更新进度条。
    这意味着在确认assetManager已经完成加载之前,您不能使用纹理。 以下是示例:

    public MyAppListener implements ApplicationListener {
        public void load(){
            assetManager.load(t1, Texture.class);
             assetManager.load(t2, Texture.class);
             assetManager.load(t3, Texture.class);
        }
    
     public void render() {
         if(manager.update()) {
             // 我们已经完成加载,让我们转到另一个屏幕!
        }
    
        // 显示加载信息
         float progress = manager.getProgress()
            ... 留给读者 ...
        }
    }
    
  • 同步加载所有资源,因此您只需按顺序调用一次(而不是在游戏循环中)

    assetManager.load(t1, Texture.class);
    assetManager.load(t2, Texture.class);
    ...
    assetManager.load.load(tn, Texture.class);
    

然后你调用

    assetManager.finishLoading();

游戏将在资产加载完成之前等待,但这意味着如果您正在加载大量内容,它会冻结您的屏幕。
更多信息请参见:https://github.com/libgdx/libgdx/wiki/Managing-your-assets

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接