Add fade out/in transition between screens
This commit is contained in:
parent
a8dc942bc2
commit
eeb43d5e4f
5 changed files with 160 additions and 12 deletions
|
@ -4,12 +4,14 @@ import com.badlogic.gdx.Application;
|
||||||
import com.badlogic.gdx.Game;
|
import com.badlogic.gdx.Game;
|
||||||
import com.badlogic.gdx.Gdx;
|
import com.badlogic.gdx.Gdx;
|
||||||
import com.badlogic.gdx.Preferences;
|
import com.badlogic.gdx.Preferences;
|
||||||
|
import com.badlogic.gdx.Screen;
|
||||||
import com.badlogic.gdx.graphics.Texture;
|
import com.badlogic.gdx.graphics.Texture;
|
||||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||||
import com.badlogic.gdx.graphics.g2d.NinePatch;
|
import com.badlogic.gdx.graphics.g2d.NinePatch;
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||||
|
|
||||||
import io.github.lonamiwebs.klooni.screens.MainMenuScreen;
|
import io.github.lonamiwebs.klooni.screens.MainMenuScreen;
|
||||||
|
import io.github.lonamiwebs.klooni.screens.TransitionScreen;
|
||||||
|
|
||||||
public class Klooni extends Game {
|
public class Klooni extends Game {
|
||||||
|
|
||||||
|
@ -82,6 +84,15 @@ public class Klooni extends Game {
|
||||||
super.render();
|
super.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TransitionScreen will also dispose by default the previous screen
|
||||||
|
public void transitionTo(Screen screen) {
|
||||||
|
transitionTo(screen, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void transitionTo(Screen screen, boolean disposeAfter) {
|
||||||
|
setScreen(new TransitionScreen(this, getScreen(), screen, disposeAfter));
|
||||||
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
//region Disposing
|
//region Disposing
|
||||||
|
|
|
@ -145,8 +145,7 @@ class CustomizeScreen implements Screen {
|
||||||
//region Private methods
|
//region Private methods
|
||||||
|
|
||||||
private void goBack() {
|
private void goBack() {
|
||||||
CustomizeScreen.this.game.setScreen(lastScreen);
|
CustomizeScreen.this.game.transitionTo(lastScreen);
|
||||||
dispose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
|
@ -46,9 +46,8 @@ public class MainMenuScreen extends InputListener implements Screen {
|
||||||
0, GameScreen.hasSavedData() ? "play_saved_texture" : "play_texture");
|
0, GameScreen.hasSavedData() ? "play_saved_texture" : "play_texture");
|
||||||
playButton.addListener(new ChangeListener() {
|
playButton.addListener(new ChangeListener() {
|
||||||
public void changed (ChangeEvent event, Actor actor) {
|
public void changed (ChangeEvent event, Actor actor) {
|
||||||
MainMenuScreen.this.game.setScreen(
|
MainMenuScreen.this.game.transitionTo(
|
||||||
new GameScreen(MainMenuScreen.this.game, GameScreen.GAME_MODE_SCORE));
|
new GameScreen(MainMenuScreen.this.game, GameScreen.GAME_MODE_SCORE));
|
||||||
dispose();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
table.add(playButton).colspan(3).fill().space(16);
|
table.add(playButton).colspan(3).fill().space(16);
|
||||||
|
@ -70,9 +69,8 @@ public class MainMenuScreen extends InputListener implements Screen {
|
||||||
statsButton.addListener(new ChangeListener() {
|
statsButton.addListener(new ChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void changed(ChangeEvent event, Actor actor) {
|
public void changed(ChangeEvent event, Actor actor) {
|
||||||
MainMenuScreen.this.game.setScreen(
|
MainMenuScreen.this.game.transitionTo(
|
||||||
new GameScreen(MainMenuScreen.this.game, GameScreen.GAME_MODE_TIME));
|
new GameScreen(MainMenuScreen.this.game, GameScreen.GAME_MODE_TIME));
|
||||||
dispose();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
table.add(statsButton).space(16);
|
table.add(statsButton).space(16);
|
||||||
|
@ -81,8 +79,9 @@ public class MainMenuScreen extends InputListener implements Screen {
|
||||||
final SoftButton paletteButton = new SoftButton(3, "palette_texture");
|
final SoftButton paletteButton = new SoftButton(3, "palette_texture");
|
||||||
paletteButton.addListener(new ChangeListener() {
|
paletteButton.addListener(new ChangeListener() {
|
||||||
public void changed (ChangeEvent event, Actor actor) {
|
public void changed (ChangeEvent event, Actor actor) {
|
||||||
MainMenuScreen.this.game.setScreen(new CustomizeScreen(MainMenuScreen.this.game, MainMenuScreen.this.game.getScreen()));
|
|
||||||
// Don't dispose because then it needs to take us to the previous screen
|
// Don't dispose because then it needs to take us to the previous screen
|
||||||
|
MainMenuScreen.this.game.transitionTo(new CustomizeScreen(
|
||||||
|
MainMenuScreen.this.game, MainMenuScreen.this.game.getScreen()), false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
table.add(paletteButton).space(16);
|
table.add(paletteButton).space(16);
|
||||||
|
|
|
@ -59,8 +59,7 @@ class PauseMenuStage extends Stage {
|
||||||
|
|
||||||
homeButton.addListener(new ChangeListener() {
|
homeButton.addListener(new ChangeListener() {
|
||||||
public void changed (ChangeEvent event, Actor actor) {
|
public void changed (ChangeEvent event, Actor actor) {
|
||||||
game.setScreen(new MainMenuScreen(game));
|
game.transitionTo(new MainMenuScreen(game));
|
||||||
dispose();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -72,8 +71,7 @@ class PauseMenuStage extends Stage {
|
||||||
@Override
|
@Override
|
||||||
public void changed(ChangeEvent event, Actor actor) {
|
public void changed(ChangeEvent event, Actor actor) {
|
||||||
// false, don't load the saved game state; we do want to replay
|
// false, don't load the saved game state; we do want to replay
|
||||||
game.setScreen(new GameScreen(game, gameMode, false));
|
game.transitionTo(new GameScreen(game, gameMode, false));
|
||||||
dispose();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -86,8 +84,8 @@ class PauseMenuStage extends Stage {
|
||||||
paletteButton.addListener(new ChangeListener() {
|
paletteButton.addListener(new ChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public void changed(ChangeEvent event, Actor actor) {
|
public void changed(ChangeEvent event, Actor actor) {
|
||||||
game.setScreen(new CustomizeScreen(game, game.getScreen()));
|
|
||||||
// Don't dispose because then it needs to take us to the previous screen
|
// Don't dispose because then it needs to take us to the previous screen
|
||||||
|
game.transitionTo(new CustomizeScreen(game, game.getScreen()), false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,141 @@
|
||||||
|
package io.github.lonamiwebs.klooni.screens;
|
||||||
|
|
||||||
|
import com.badlogic.gdx.Gdx;
|
||||||
|
import com.badlogic.gdx.Screen;
|
||||||
|
import com.badlogic.gdx.graphics.GL20;
|
||||||
|
import com.badlogic.gdx.graphics.Pixmap;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
|
||||||
|
import com.badlogic.gdx.graphics.g2d.TextureRegion;
|
||||||
|
import com.badlogic.gdx.graphics.glutils.FrameBuffer;
|
||||||
|
|
||||||
|
import io.github.lonamiwebs.klooni.Klooni;
|
||||||
|
|
||||||
|
public class TransitionScreen implements Screen {
|
||||||
|
|
||||||
|
//region Members
|
||||||
|
|
||||||
|
// Rendering
|
||||||
|
private FrameBuffer frameBuffer;
|
||||||
|
private TextureRegion bufferTexture;
|
||||||
|
private final SpriteBatch spriteBatch;
|
||||||
|
private float fadedElapsed;
|
||||||
|
private boolean fadingOut;
|
||||||
|
private int width, height;
|
||||||
|
|
||||||
|
// From, to, and game to change the screen after the transition finishes
|
||||||
|
private final Screen fromScreen, toScreen;
|
||||||
|
private final Klooni game;
|
||||||
|
|
||||||
|
// Should the previous screen be disposed afterwards? Not desirable
|
||||||
|
// if it was stored somewhere else, for example, to return to it later
|
||||||
|
private final boolean disposeAfter;
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
//region Static variables
|
||||||
|
|
||||||
|
// Time it takes to fade out and in, 0.15s (0.3s total)
|
||||||
|
private static final float FADE_INVERSE_DELAY = 1f / 0.15f;
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
//region Constructor
|
||||||
|
|
||||||
|
public TransitionScreen(Klooni game, Screen from, Screen to, boolean disposeAfter) {
|
||||||
|
this.disposeAfter = disposeAfter;
|
||||||
|
this.game = game;
|
||||||
|
fromScreen = from;
|
||||||
|
toScreen = to;
|
||||||
|
|
||||||
|
spriteBatch = new SpriteBatch();
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
//region Rendering
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void show() {
|
||||||
|
fadedElapsed = 0f;
|
||||||
|
fadingOut = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void render(float delta) {
|
||||||
|
// Black background since we're fading to black
|
||||||
|
Gdx.gl.glClearColor(0, 0, 0, 1);
|
||||||
|
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
|
||||||
|
|
||||||
|
// Render on another buffer so then we can set its opacity. This
|
||||||
|
// second buffer also would allow us to do more stuff, since then
|
||||||
|
// we can use a texture, which we could move across the screen.
|
||||||
|
frameBuffer.begin();
|
||||||
|
|
||||||
|
float opacity;
|
||||||
|
if (fadingOut) {
|
||||||
|
fromScreen.render(delta);
|
||||||
|
opacity = 1 - Math.min(fadedElapsed * FADE_INVERSE_DELAY, 1);
|
||||||
|
if (opacity == 0) {
|
||||||
|
fadedElapsed = 0;
|
||||||
|
fadingOut = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
toScreen.render(delta);
|
||||||
|
opacity = Math.min(fadedElapsed * FADE_INVERSE_DELAY, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
frameBuffer.end();
|
||||||
|
|
||||||
|
// Render the faded texture
|
||||||
|
spriteBatch.begin();
|
||||||
|
spriteBatch.setColor(1, 1, 1, opacity);
|
||||||
|
spriteBatch.draw(bufferTexture, 0, 0, width, height);
|
||||||
|
spriteBatch.end();
|
||||||
|
fadedElapsed += delta;
|
||||||
|
|
||||||
|
// We might have finished fading if the opacity is full
|
||||||
|
if (opacity == 1 && !fadingOut) {
|
||||||
|
game.setScreen(toScreen);
|
||||||
|
dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resize(int width, int height) {
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
if (frameBuffer != null)
|
||||||
|
frameBuffer.dispose();
|
||||||
|
|
||||||
|
frameBuffer = new FrameBuffer(Pixmap.Format.RGB565, width, height, false);
|
||||||
|
bufferTexture = new TextureRegion(frameBuffer.getColorBufferTexture());
|
||||||
|
bufferTexture.flip(false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
//region Disposing
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void dispose() {
|
||||||
|
frameBuffer.dispose();
|
||||||
|
if (disposeAfter)
|
||||||
|
fromScreen.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
|
||||||
|
//region Unused methods
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void pause() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void resume() { }
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void hide() { }
|
||||||
|
|
||||||
|
//endregion
|
||||||
|
}
|
Loading…
Reference in a new issue