Tag 11 – Ladebildschirm

veröffentlicht am: 11. Dezember 2012

Es sieht doch irgendwie professionell aus, wenn die App beim Starten einen kleinen Ladebildschirm anzeigt. Sinnvoll ist das natürlich nur, wenn man auch Daten hat, die man vorher laden kann und die in der ganzen App gebraucht werden.

Libgdx hat dafür eine Klasse namens AssetManager. Ein Objekt dieser Klasse speichern wir in unserem Game, damit wir von allen Screens drauf zugreifen können.
Außerdem habe ich einen neuen Screen namens loading-Screen hinzugefügt.

public class TestGame extends Game{
	AssetManager assets;

	@Override
	public void create() {
		setScreen(new LoadingScreen(this));
	}
}

Im Loading-Screen geben wir mit assets.load(„FILE“,[TYPE OF ASSET].class) an, welche Assets geladen werden sollen.

public LoadingScreen(TestGame pGame) {
	game=pGame;
	
	// which assets do we want to be loaded
	game.assets=new AssetManager();
		
	game.assets.load("ui/myskin.json", Skin.class);
	game.assets.load("graphics/testPack.atlas",TextureAtlas.class);
	game.assets.load("ui/test.fnt",BitmapFont.class);
	
}

Damit die Assets asynchron geladen werden, muss man in der render() Methode assets.update() aufrufen. Diese liefert netterweise direkt true zurück, wenn die Assets fertig geladen sind.

if(game.assets.update()){
	// all the assets are loaded
	game.setScreen(new SplashScreen(game));
}

In den anderen Screens kann man dann mit assets.get() die vorher geladenen Daten holen.

atlas = game.assets.get("graphics/testPack.atlas", TextureAtlas.class);

Damit während der (momentan noch sehr kurzen) Ladezeit nicht einfach ein leerer Bildschirm ist, hab ich mir mit diesen zwei NinePatches einen Ladebalken gebaut:

Die nötigen Assets muss ich dann natürlich im LoadingScreen auf alte Weise laden:

// load the assets for the loading screen :D
font=new BitmapFont();
batch=new SpriteBatch();
emptyT=new Texture(Gdx.files.internal("load/empty.png"));
fullT=new Texture(Gdx.files.internal("load/full.png"));
empty=new NinePatch(new TextureRegion(emptyT,24,24),8,8,8,8);
full=new NinePatch(new TextureRegion(fullT,24,24),8,8,8,8);

// [...] render():
batch.begin();
empty.draw(batch, 40, 225, 720, 30);
full.draw(batch, 40, 225, game.assets.getProgress()*720, 30);
font.drawMultiLine(batch,(int)(game.assets.getProgress()*100)+"% loaded",400,247,0, BitmapFont.HAlignment.CENTER);
batch.end();

Und schon erhält man diesen coolen Ladebildschirm.

geposted in libgdx

6 Antworten zu “Tag 11 – Ladebildschirm”

  1. Jan sagt:

    Hey bitowl,

    ich bin es mal wieder 🙂
    Ich habe deinen Ladebalken mal zu einem Image gemacht, damit ich anschließend als Actor in die Szene einfügen kann:
    Image fullImage = new Image(full);
    fullImage.addAction(Actions.sizeTo(byfgame.assets.getProgress()*440, 40));
    stage.addActor(fullImage);

    Nun verändert sich aber die Größe des Ladebalkens nicht. Ich gehe jetzt mal davon aus, dass die Action nur einmal ausgeführt wird, richtig? Wie kann man daraus eine Animation machen?

    Grüße Jan

    • bitowl sagt:

      wenn du die Größe des Ladenbalkens über eine bestimmte Zeit verändern wolltest, könnest du fullImage.addAction(Actions.sizeTo(440, 40,4.0f)); nutzen (für vier Sekunden). [einfach nur nützlich zu wissen]

      da du aber in jedem Frame den aktuellen Status des Ladens abfragen willst und das Bild dementsprechend verändern, musst du diese Zeile in die render()-Methode packen, damit eine „Animation“ entsteht.

  2. Jan sagt:

    Hm klingt einfach, bekomme ich leider trotzdem nicht hin 🙁 Ich habe jetzt so lang in der render methode rumgeschoben bis kaum noch etwas läuft. bisher konnte ich immer nur verzeichnen, dass die progresszahl richtig angegeben wird jedoch die anzeige immer auf 0 stehen blieb (obwohl ja von der gleichen variable gefütter):

    batch.setProjectionMatrix(camera.combined); // tells the batch, where to draw
    stage.getSpriteBatch().begin();
    stage.getSpriteBatch().end();
    batch.begin();
    stage.setViewport(byfgame.resulutionX,byfgame.resulutionY,false);

    // empty.draw(batch, 10, 30, 460, 25);
    // full.draw(batch, 10, 30, byfgame.assets.getProgress()*460, 25);
    int progress = (int)(byfgame.assets.getProgress()*100);
    fullImage.addAction(Actions.sizeTo(progress*440, 40));
    font.drawMultiLine(batch,progress+“% „,240,60,0, BitmapFont.HAlignment.CENTER);
    stage.act(delta);
    stage.draw();
    batch.end();

    • Jan sagt:

      Hab es zum laufen bekommen. Nach dem setzen der neuen Größe noch ein invalidate() dann klappt es

      • tommybee sagt:

        I am a fan of your articls nowadays…
        I thank you for all of these stuffs

        In LoadingScreen … All the stuffs are mixed up while loading progress bar processing…
        So, my idea is now to just clear screen first in the render method in the file like below
        @Override
        public void render(float delta) {
        //clears the buffer
        Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
        ….rest of codes
        thanks

  3. John Master sagt:

    Great Tutorial!

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.