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.Gdx;
|
||||
import com.badlogic.gdx.Preferences;
|
||||
import com.badlogic.gdx.Screen;
|
||||
import com.badlogic.gdx.graphics.Texture;
|
||||
import com.badlogic.gdx.graphics.g2d.BitmapFont;
|
||||
import com.badlogic.gdx.graphics.g2d.NinePatch;
|
||||
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
|
||||
|
||||
import io.github.lonamiwebs.klooni.screens.MainMenuScreen;
|
||||
import io.github.lonamiwebs.klooni.screens.TransitionScreen;
|
||||
|
||||
public class Klooni extends Game {
|
||||
|
||||
|
@ -82,6 +84,15 @@ public class Klooni extends Game {
|
|||
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
|
||||
|
||||
//region Disposing
|
||||
|
|
|
@ -145,8 +145,7 @@ class CustomizeScreen implements Screen {
|
|||
//region Private methods
|
||||
|
||||
private void goBack() {
|
||||
CustomizeScreen.this.game.setScreen(lastScreen);
|
||||
dispose();
|
||||
CustomizeScreen.this.game.transitionTo(lastScreen);
|
||||
}
|
||||
|
||||
//endregion
|
||||
|
|
|
@ -46,9 +46,8 @@ public class MainMenuScreen extends InputListener implements Screen {
|
|||
0, GameScreen.hasSavedData() ? "play_saved_texture" : "play_texture");
|
||||
playButton.addListener(new ChangeListener() {
|
||||
public void changed (ChangeEvent event, Actor actor) {
|
||||
MainMenuScreen.this.game.setScreen(
|
||||
MainMenuScreen.this.game.transitionTo(
|
||||
new GameScreen(MainMenuScreen.this.game, GameScreen.GAME_MODE_SCORE));
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
table.add(playButton).colspan(3).fill().space(16);
|
||||
|
@ -70,9 +69,8 @@ public class MainMenuScreen extends InputListener implements Screen {
|
|||
statsButton.addListener(new ChangeListener() {
|
||||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
MainMenuScreen.this.game.setScreen(
|
||||
MainMenuScreen.this.game.transitionTo(
|
||||
new GameScreen(MainMenuScreen.this.game, GameScreen.GAME_MODE_TIME));
|
||||
dispose();
|
||||
}
|
||||
});
|
||||
table.add(statsButton).space(16);
|
||||
|
@ -81,8 +79,9 @@ public class MainMenuScreen extends InputListener implements Screen {
|
|||
final SoftButton paletteButton = new SoftButton(3, "palette_texture");
|
||||
paletteButton.addListener(new ChangeListener() {
|
||||
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
|
||||
MainMenuScreen.this.game.transitionTo(new CustomizeScreen(
|
||||
MainMenuScreen.this.game, MainMenuScreen.this.game.getScreen()), false);
|
||||
}
|
||||
});
|
||||
table.add(paletteButton).space(16);
|
||||
|
|
|
@ -59,8 +59,7 @@ class PauseMenuStage extends Stage {
|
|||
|
||||
homeButton.addListener(new ChangeListener() {
|
||||
public void changed (ChangeEvent event, Actor actor) {
|
||||
game.setScreen(new MainMenuScreen(game));
|
||||
dispose();
|
||||
game.transitionTo(new MainMenuScreen(game));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -72,8 +71,7 @@ class PauseMenuStage extends Stage {
|
|||
@Override
|
||||
public void changed(ChangeEvent event, Actor actor) {
|
||||
// false, don't load the saved game state; we do want to replay
|
||||
game.setScreen(new GameScreen(game, gameMode, false));
|
||||
dispose();
|
||||
game.transitionTo(new GameScreen(game, gameMode, false));
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -86,8 +84,8 @@ class PauseMenuStage extends Stage {
|
|||
paletteButton.addListener(new ChangeListener() {
|
||||
@Override
|
||||
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
|
||||
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