javalibgdxscene2d

Java/libGDX - issues with Actions.fadeIn() and Actions.fadeOut()


it's my first time posting and I'm self taught so be please gentle!

I've been building a bomberman replica game in libGDX using Game and Screen classes:

public class Main extends Game {
...

@Override
public void create() {
    levelScreen = new LevelScreen(playerCount, new int[playerCount]);
    levelScreen.level.addAction(Actions.sequence(Actions.alpha(0), Actions.fadeIn(2f)));
    this.setScreen(levelScreen);
}

However when the game launches there is no fade effect.

public class LevelScreen implements Screen {
...

@Override
public void render(float delta) {
    Gdx.gl.glClearColor(1, 0.1f, 0.5f, 0);
    Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
    batch.begin();
    level.act();
    level.draw();
    batch.end();
}

I want this levelScreen to fade in from black but it just doesn't!

When the round is over I want to fadeOut of this levelScreen to black, then fadeIn to a trophyScreen from black:

(From Main Class)

@Override
public void render() {

    super.render();

        if (endRoundTimer <= 0) {
            trophyScreen = new TrophyScreen(playerCount, levelScreen.getScore());
            levelScreen.level.addAction(Actions.sequence(Actions.fadeOut(1), Actions.run(new Runnable() {
                @Override
                public void run() {
                    setScreen(trophyScreen);
                }
            })));
    }
}

And I've tried using the show() method in the TrophyScreen:

public class TrophyScreen implements Screen {
...
@Override
public void show()  {
    stage.addAction(Actions.sequence(Actions.alpha(0), Actions.fadeIn(1)));
}

I've done loads of searching and tried various things but no joy. I'm sure I'm missing something somewhere in a draw() or render() method that is preventing the fade Action from taking place.

UPDATE1

@Override public void draw() { 
super.draw();
if (roundOver) {
this.getBatch().begin(); String s = String.format("%s", message);
font_text.draw(this.getBatch(), s, (90 + (2 * 30)), (this.getHeight() / 2));
this.getBatch().end();
}

Solution

  • For fading to work on actors, they must properly apply their own color's alpha in the draw method. And for an entire hierarchy of objects to fade at once, they must all also apply the parentAlpha parameter from the draw method signature.

    So your draw method in any custom Actor subclass should look like this:

    public void draw (Batch batch, float parentAlpha) {
        Color color = getColor();
        batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);
        //..do drawing
    }
    

    If you are using a Sprite in your Actor instead of a TextureRegion (which I don't recommend due to redundancies) you must apply the color to the Sprite instead of Batch.

    Note that this method of fading the whole game is not a "clean" fade. Any actors that are overlapping other actors will show through each other when the parent alpha is less than 1 during the fade. An alternative that would provide a clean-looking fade would be to draw a copy of your background (or black) over your entire scene and fade that instead.