Java Libgdx:在屏幕已经渲染之后,如何加载资源?

Java Libgdx:在屏幕已经渲染之后,如何加载资源?,java,android,libgdx,Java,Android,Libgdx,我已经在我的加载屏幕上实现了加载屏幕,它是游戏的孩子。这就是我的AssetInit方法和Screen类的外观。资产中的init方法加载包含AtlasRegion的类。我已经测试过,这个方法是什么使我的屏幕加载一个黑屏,因为它加载了很多资源 public void init (AssetManager assetManager) { this.assetManager = assetManager; // set asset manager error handler

我已经在我的加载屏幕上实现了加载屏幕,它是游戏的孩子。这就是我的AssetInit方法和Screen类的外观。资产中的init方法加载包含AtlasRegion的类。我已经测试过,这个方法是什么使我的屏幕加载一个黑屏,因为它加载了很多资源

    public void init (AssetManager assetManager) {
    this.assetManager = assetManager;
    // set asset manager error handler
    assetManager.setErrorListener(this);

    assetManager.load(Constants.TEXTURE_ATLAS_OBJECTS, TextureAtlas.class);
    assetManager.load(Constants.TEXTURE_ATLAS_UI, TextureAtlas.class);
    assetManager.finishLoading();

    TextureAtlas atlas = assetManager.get(Constants.TEXTURE_ATLAS_OBJECTS);
    TextureAtlas atlasUi = assetManager.get(Constants.TEXTURE_ATLAS_UI);

    //font = new BitmapFont(Gdx.files.internal("data/font.fnt"), Gdx.files.internal("data/font.png"), false);

    clickSound = Gdx.audio.newSound(Gdx.files.internal("data/sounds/click.wav"));

    // create game resource objects
    fonts = new AssetFonts(assetManager);
    skins = new AssetSkins();
    background = new AssetBackgroundImage();
    cards = new AssetCards(atlas);
    cardimages = new AssetImages(atlas);
    cardsjson = new AssetList();
    suitimages = new AssetSuitImages(atlas);
}
这是我的加载屏幕类:

    public class LoadingScreen extends AbstractGameScreen implements Disposable {

    private Stage stage;

    private Image logo;
    private Image loadingFrame;
    private Image loadingBarHidden;
    private Image screenBg;
    private Image loadingBg;

    private float startX, endX;
    private float percent;

    private Actor loadingBar;

    public LoadingScreen(CardGame game) {
        super(game);
    }

    public InputProcessor getInputProcessor () {
        return (null);
    }

    @Override
    public void show() {
        // Tell the manager to load assets for the loading screen
        game.manager.load("data/images-ui/loading/loading.pack", TextureAtlas.class);
        // Wait until they are finished loading
        game.manager.finishLoading();

        // Initialize the stage where we will place everything
        stage = new Stage();

        // Get our textureatlas from the manager
        TextureAtlas atlas = game.manager.get("data/images-ui/loading/loading.pack", TextureAtlas.class);

        // Grab the regions from the atlas and create some images
        logo = new Image(atlas.findRegion("libgdx-logo"));
        loadingFrame = new Image(atlas.findRegion("loading-frame"));
        loadingBarHidden = new Image(atlas.findRegion("loading-bar-hidden"));
        screenBg = new Image(atlas.findRegion("screen-bg"));
        loadingBg = new Image(atlas.findRegion("loading-frame-bg"));

        // Add the loading bar animation
        Animation anim = new Animation(0.05f, atlas.findRegions("loading-bar-anim") );
        anim.setPlayMode(Animation.PlayMode.LOOP_REVERSED);
        loadingBar = new LoadingBar(anim);

        // Or if you only need a static bar, you can do
        // loadingBar = new Image(atlas.findRegion("loading-bar1"));

        // Add all the actors to the stage
        stage.addActor(screenBg);
        stage.addActor(loadingBar);
        stage.addActor(loadingBg);
        stage.addActor(loadingBarHidden);
        stage.addActor(loadingFrame);
        stage.addActor(logo);

        // Add everything to be loaded, for instance:
        Assets.instance.init(game.manager);
    }

    @Override
    public void resize(int width, int height) {
        // Set our screen to always be XXX x 480 in size
        //width = 480 * width / height;
        //height = 480;
        stage.getViewport().update(width, height, false);

        // Make the background fill the screen
        screenBg.setSize(width, height);

        // Place the logo in the middle of the screen and 100 px up
        logo.setX((width - logo.getWidth()) / 2);
        logo.setY((height - logo.getHeight()) / 2 + 100);

        // Place the loading frame in the middle of the screen
        loadingFrame.setX((stage.getWidth() - loadingFrame.getWidth()) / 2);
        loadingFrame.setY((stage.getHeight() - loadingFrame.getHeight()) / 2);

        // Place the loading bar at the same spot as the frame, adjusted a few px
        loadingBar.setX(loadingFrame.getX() + 15);
        loadingBar.setY(loadingFrame.getY() + 5);

        // Place the image that will hide the bar on top of the bar, adjusted a few px
        loadingBarHidden.setX(loadingBar.getX() + 35);
        loadingBarHidden.setY(loadingBar.getY() - 3);
        // The start position and how far to move the hidden loading bar
        startX = loadingBarHidden.getX();
        endX = 440;

        // The rest of the hidden bar
        loadingBg.setSize(450, 50);
        loadingBg.setX(loadingBarHidden.getX() + 30);
        loadingBg.setY(loadingBarHidden.getY() + 3);
    }

    @Override
    public void render(float delta) {
        // Clear the screen
        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

        if (game.manager.update()) { // Load some, will return true if done loading
            if (Gdx.input.isTouched()) { // If the screen is touched after the game is done loading, go to the main menu screen
                game.setScreen(new MainMenuScreen(game));
            }
        }

        // Interpolate the percentage to make it more smooth
        percent = Interpolation.linear.apply(percent, game.manager.getProgress(), 0.1f);

        // Update positions (and size) to match the percentage
        loadingBarHidden.setX(startX + endX * percent);
        loadingBg.setX(loadingBarHidden.getX() + 30);
        loadingBg.setWidth(450 - 450 * percent);
        loadingBg.invalidate();

        // Show the loading screen
        stage.act();
        stage.draw();
    }

    @Override
    public void pause () {}

    @Override
    public void resume () {}

    @Override
    public void hide() {
        // Dispose the loading assets as we no longer need them
        game.manager.unload("data/images-ui/loading/loading.pack");
    }
}

我需要加载屏幕,然后在此
assets.instance.init(new AssetManager())
上加载我的资产,因为这是导致黑屏的原因。问题是我的屏幕加载后加载的资产,因此这使得我的加载屏幕是没有用的。如何在屏幕呈现后加载此方法?

从init方法中删除
finishload
调用。应该这样做<代码>完成加载强制资产立即完成加载,而这不是您想要的。反复调用
update
,这是异步加载资产的方法,您已经在这样做了

这是一个如何实现的一般结构。调用asset manager上的所有
load
方法,然后再调用
render
方法。然后反复调用update,直到加载所有内容。然后在继续之前获取对资产的引用

private boolean loadComplete;

public void show(){
    //...
    loadComplete = false;
}

private void init(AssetManager assetManager){
    this.assetManager = assetManager;
    assetManager.load(/*whatever*/);
    assetManager.load(/*whatever*/);
    assetManager.load(/*whatever*/);
}

private void onAssetsLoaded(){
    loadComplete = true;
    myAtlas = assetManager.get("myAtlas.json", TextureAtlas.class);
    //and so on
}

public void render(float delta){
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    //load one asset at a time per frame until loading is complete
    if (assetManager == null || !assetManager.update()){
        //maybe draw a load screen image that's not a texture that's being managed 
        //by the assetManager. You could even play an animation. Otherwise, 
        //you can leave the screen blank.

        return;
    }

    //will only get here when asset manager is done. The first time, you still
    //need to get references to its assets
    if (!loadComplete)
        onAssetsLoaded();

    //the rest of you render method. Everything below here only happens after assets are loaded and asset references have been aquired

}

从init方法中删除
finishload
调用。应该这样做<代码>完成加载强制资产立即完成加载,而这不是您想要的。反复调用
update
,这是异步加载资产的方法,您已经在这样做了

这是一个如何实现的一般结构。调用asset manager上的所有
load
方法,然后再调用
render
方法。然后反复调用update,直到加载所有内容。然后在继续之前获取对资产的引用

private boolean loadComplete;

public void show(){
    //...
    loadComplete = false;
}

private void init(AssetManager assetManager){
    this.assetManager = assetManager;
    assetManager.load(/*whatever*/);
    assetManager.load(/*whatever*/);
    assetManager.load(/*whatever*/);
}

private void onAssetsLoaded(){
    loadComplete = true;
    myAtlas = assetManager.get("myAtlas.json", TextureAtlas.class);
    //and so on
}

public void render(float delta){
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

    //load one asset at a time per frame until loading is complete
    if (assetManager == null || !assetManager.update()){
        //maybe draw a load screen image that's not a texture that's being managed 
        //by the assetManager. You could even play an animation. Otherwise, 
        //you can leave the screen blank.

        return;
    }

    //will only get here when asset manager is done. The first time, you still
    //need to get references to its assets
    if (!loadComplete)
        onAssetsLoaded();

    //the rest of you render method. Everything below here only happens after assets are loaded and asset references have been aquired

}

在尝试了这么多推荐的解决方案之后,我终于设法解决了这个问题,这要感谢


我使用了一个回调,在异步加载资产时显示一个带有图像的android framelayout。

在尝试了这么多推荐的解决方案后,我终于解决了这个问题,这要感谢



我使用了一个回调函数,该函数显示一个android framelayout,其中一个图像作为资产异步加载。

显示
资产.instance.init
方法。我已将其添加到问题中。我不完全确定我是否正确理解了您的代码和要求,但我认为您不应该在init方法中加载资产,而是为每个资产调用game.manager.load。这样,您可以先加载加载屏幕资源,然后调用game.manager.finishLoading();最后,在显示加载屏幕时加载其余资源。虽然可以说,这是一个不太优雅的解决方案,但在一个地方加载所有内容。感谢您的建议,但我确实需要使用Assets类,我从
游戏
加载AssetManager。如果你的意思是加载每一项资产,我正在使用game.manager,这是我的资产构造函数的参数。显示你的
Assets.instance.init
方法。我已将其添加到问题中。我不完全确定我是否正确理解你的代码和要求,但我认为你不应该在init方法中加载资产,而是为每个资产调用game.manager.load。这样,您可以先加载加载屏幕资源,然后调用game.manager.finishLoading();最后,在显示加载屏幕时加载其余资源。虽然可以说,这是一个不太优雅的解决方案,但在一个地方加载所有内容。感谢您的建议,但我确实需要使用Assets类,我从
游戏
加载AssetManager。如果您的意思是加载每一项资产,我将使用game.manager执行此操作,这是我的资产构造函数的参数。执行此操作将导致assetManager在加载TextureAtlas之前尝试并
get()
。我该如何在没有错误的情况下实现它?@Zack使用isLoaded方法。唯一的问题是你是否已经有了加载屏幕的资源。我的理解是,您没有,因为您将所有内容都加载在一起(加载屏幕和下一屏幕的资源),在我的评论中,我指的是这种情况,但可能我误解了问题。@ChanandlerBong
“isLoaded()
检查是否加载了资产文件,但这里我需要等待多个资产加载。你认为我怎么能做到这一点?@Zack我在考虑为每个需要的资源调用isLoaded(),并等待每个检查返回true。如果要等待所有内容加载完毕,请检查update()是否返回true或getProgress()是否为1。@Zack我添加了一个示例。这样做将导致assetManager在加载TextureAtlas之前尝试并获取它。我该如何在没有错误的情况下实现它?@Zack使用isLoaded方法。唯一的问题是你是否已经有了加载屏幕的资源。我的理解是,您没有,因为您将所有内容都加载在一起(加载屏幕和下一屏幕的资源),在我的评论中,我指的是这种情况,但可能我误解了问题。@ChanandlerBong
“isLoaded()
检查是否加载了资产文件,但这里我需要等待多个资产加载。你认为我怎么能做到这一点?@Zack我在考虑为每个需要的资源调用isLoaded(),并等待每个检查返回true。如果要等到所有内容都加载完毕,请检查update()是否返回true或getProgress()是否为1。@Zack我添加了一个示例。