Using Tween engine to create a splash screen for your game or app

The Tween Engine is a small library developed by Aureliene Ribon that enables the interpolation of every attribute from any object in any Java project (being Swing, SWT, OpenGL or even Console-based). By implementing the TweenAccessor interface and registering it to the engine you can animate anything you want!

You can download the basic jar and other versions here .
In this post I’ll explain how to use the Tween Engine to make a cool splash screen for your Android applications based on (or using) LibGDX, but it can be used with any Java object.

First we need to start by creating a new class implementing the TweenAccessor templated with the Sprite LibGDX class.

public class SpriteAccessor implements TweenAccessor<Sprite> {

	public static final int ALPHA = 1;

	@Override
	public int getValues(Sprite target, int tweenType, float[] returnValues) {
		switch (tweenType) {
			case ALPHA:
				returnValues[0] = target.getColor().a;
				return 1;
			default:
				return 0;
		}
	}

	@Override
	public void setValues(Sprite target, int tweenType, float[] newValues) {
		switch (tweenType) {
			case ALPHA:
				target.setColor(1, 1, 1, newValues[0]);
			break;
		}
	}
}

As you can see the snippet is easy to understand. Since we will be only changing the alpha values in order to make an appear-disappear effect we will need to deal with the alpha value of the Sprite object. When creating a TweenAccessor, retrieve the values that you want modified from the Object you are changing, and place them into an array. Let the Tween Engine do its work. Then, you receive the modified values and assign them back to the Object you are changing.
It’s time to write the SplashScreen class. It is just a Screen that will take our logo sprite, start it at 0 opacity, increase it to 1 (100%) and bring it back down to zero. This is the entire SplashScreen class. Later on we will go through all the methods.

public abstract class SplashScreen implements Screen {

	private TweenManager manager;
	private SpriteBatch batcher;
	private Sprite sprite;

	public SplashScreen() {
	}

	public abstract Texture getLogo();
	public abstract Game getGame();
	public abstract Screen getGameScreen();

	@Override
	public void show() {
		sprite = new Sprite(getLogo());
		sprite.setColor(1, 1, 1, 0);

		float width = Gdx.graphics.getWidth();
		float height = Gdx.graphics.getHeight();
		float desiredWidth = width * .7f;
		float scale = desiredWidth / sprite.getWidth();

		sprite.setSize(sprite.getWidth() * scale, sprite.getHeight() * scale);
		sprite.setPosition((width / 2) - (sprite.getWidth() / 2), (height / 2)- (sprite.getHeight() / 2));
		setupTween();
		batcher = new SpriteBatch();
	}

	private void setupTween() {
		Tween.registerAccessor(Sprite.class, new SpriteAccessor());
		manager = new TweenManager();

		TweenCallback cb = new TweenCallback() {
			@Override
			public void onEvent(int type, BaseTween<?> source) {
				getGame().setScreen(getGameScreen());
			}
		};

		Tween.to(sprite, SpriteAccessor.ALPHA, .8f).target(1)
			.ease(TweenEquations.easeInOutQuad).repeatYoyo(1, .4f)
			.setCallback(cb).setCallbackTriggers(TweenCallback.COMPLETE)
			.start(manager);
	}

	@Override
	public void render(float delta) {
		manager.update(delta);
		Gdx.gl.glClearColor(57/255f, 146/255f, 231/255f, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
		batcher.begin();
		sprite.draw(batcher);
		batcher.end();
	}

}

Let’s see first the setupTween method.

private void setupTween() {
	Tween.registerAccessor(Sprite.class, new SpriteAccessor());
	manager = new TweenManager();

	TweenCallback cb = new TweenCallback() {
		@Override
		public void onEvent(int type, BaseTween<?> source) {
			getGame().setScreen(getGameScreen());
		}
	};

	Tween.to(sprite, SpriteAccessor.ALPHA, .8f).target(1)
		.ease(TweenEquations.easeInOutQuad).repeatYoyo(1, .4f)
		.setCallback(cb).setCallbackTriggers(TweenCallback.COMPLETE)
		.start(manager);
}

In the first line we register a new Accessor in order to modify a Sprite object using our custom recently created accesor.
In the second line we create a TweenManager, which is updated in our render method with the delta time value (see below). This manager will then handle the interpolation for us using our SpriteAccessor.

Then we can create something called a TweenCallback, which is an object whose methods are called when Tweening is complete.
In this case, we create a new TweenCallback whose onEvent method implementation will send us to the Game screen.

Let’s look at the last chunk of code.

Tween.to(sprite, SpriteAccessor.ALPHA, .8f).target(1)
	.ease(TweenEquations.easeInOutQuad).repeatYoyo(1, .4f)
	.setCallback(cb).setCallbackTriggers(TweenCallback.COMPLETE)
	.start(manager);

The first line says we are going to tween the sprite object using the SpriteAccessor’s ALPHA tweenType. We want this to take 0.8 seconds and to modify the starting alpha value (this is specified in the SpriteAccessor class) to the desired target value of 1.

The second line defines the interpolation method. In this case we are using a quadratic interpolation and repeat it in Yoyo mode with a period of 0.4 seconds between repetitions. This way we will accomplish the effect of bringing our opacity back to zero when it reaches its maximum value.

In the last two lines we define which callbacks we want to activate (in our case the onComplete callback) and start the manager.
About the other methods, they are quite simple. In the show method, which is the first method called when the screen is started, we just make some calculations to fit our logo in the desired size and position and call the setupTween method.

In the render screen method the tween manager is updated and the buffers cleared. In this case I am using a sky blue background color. Remember of course to draw your logo!

Finally, in order to make this class reusable, you must implement three simple methods:

public abstract Texture getLogo();

Return the image you want to use in your splash screen.

public abstract Game getGame();

Return your Game class so the SplashScreen class can launch the next screen when the tweening is finished.

public abstract Screen getGameScreen();

Return the next screen in the game flow. It is used in the tween finish callback to make the transition.

That’s it. Remember that it is not necessary to use LibGDX in order to use the Tween engine and it can be used for example with Android View elements instead of Android native animations, Swing elements and many more.

If you have any question, correction or anything to add to this post, please feel free to leave a comment or get in touch!

Leave a Reply

Your email address will not be published. Required fields are marked *


*