Using transitions between game screens is a great way to provide smoothness between screen changes, for example, fade out one screen and then fade in the next one. The next video shows an example of those effects our Vampire Runner game.

In this post, we will show a possible implementation of transitions between screens using LibGDX, however the code should be independent enough to be easily ported to other frameworks.

Although we implemented it using the our own concept of GameState, we will try to use LibGDX Screen concept in this post to simplify understandability.

Implementation

The implementation is based in the concept of TransitionEffect. A TransitionEffect holds the render logic of one of the effects of the transition being performed.

class TransitionEffect {

	// returns a value between 0 and 1 representing the level of completion of the transition.
	protected float getAlpha() { .. }

	void update(float delta) { .. } 

	void render(Screen current, Screen next);

	boolean isFinished() { .. }

	TransitionEffect(float duration) { .. }
}

An implementation example of a TransitionEffect is a FadeOutTransitionEffect to perform a fade out effect:

class FadeOutTransitionEffect extends TransitionEffect {

	Color color = new Color();

	@Override
	public void render(Screen current, Screen next) {
		current.render();
		color.set(0f, 0f, 0f, getAlpha());
		// draw a quad over the screen using the color
	}

}

Then, in order to perform a transition between Screens, we need a custom Screen with the logic to apply render each transition effect and to set the next Screen when the transition is over. This is a possible implementation:

class TransitionScreen implements Screen {
	Game game;

	Screen current;
	Screen next;

	int currentTransitionEffect;
	ArrayList<TransitionEffect> transitionEffects;

	TransitionScreen(Game game, Screen current, Screen next, ArrayList<TransitionEffect> transitionEffects) {
		this.current = current;
		this.next = next;
		this.transitionEffects = transitionEffects;
		this.currentTransitionEffect = 0;
		this.game = game;
	}

	void render() {
		if (currentTransitionEffect >= transitionEffects.size()) {
			game.setScreen(next);
			return;
		}

		transitionEffects.get(currentTransitionEffect).update(getDelta());
		transitionEffects.get(currentTransitionEffect).render(current, next);

		if (transitionEffects.get(currentTransitionEffect).isFinished())
			currentTransitionEffect++;
	}
}

Finally, each time we want to perform a transition between two screens, we have to create a new TransitionScreen with the current and next Screens and a collection of effects we want. For example:

Screen current = game.getScreen();
	Screen next = new HighscoresScreen();

	ArrayList<TransitionEffect> effects = new ArrayList<TransitionEffect>();

	effects.add(new FadeOutTransitionEffect(1f));
	effects.add(new FadeInTransitionEffect(1f));

	Screen transitionScreen = new TransitionScreen(game, current, next, effects);

	game.setScreen(transitionScreen);

As we mention before, we use our own concepts in our implementation. If you want to see our code take a look at the classes ApplicationListenerGameStateBasedImpl, GameState and GameStateTransitionImpl (do not expect the best code in the world).

Conclusion

Adding transitions between the game screens gives users a feeling of smoothness, and we believe it worth the effort.

Also, we like the current design lets you implement different effects for the transitions, we only shown fade out and fade in as example because they are really simple to implement and we are using only those for our games.

As always, hope you like the post.


For our latest Vampire Runner update we changed to use LibGDX scene2d instead Android GUI. The main reason for the change is that we wanted to use a common GUI API for Android and PC, and sadly we can’t do that using Android API. With LibGDX scene2d we can code once and run in both platforms.

In particular, the toast feature of the Android API was really interesting to have and we want to share how we implemented it using LibGDX scene2d.

Toasting

A toast is defined as a scene2d Window that shows some text and disappear after a while, this is a pseudo code to give the idea of how to create that toast window:

Actor toast(String text, float time, Skin skin) {
	Window window = new Window(skin);
	window.add(new Label(text, skin));
	...
	window.action(new Action() {
		act(float delta) {
			// update the animation
			// if the animation is finished, we remove the window from the stage.
		}
	});
	...
	return window;
}

To animate the toast, we create a TimelineAnimation using animation4j defining that the window should move from outside the screen to inside the screen, wait some time and then go out of the screen again. The code looks like this:

TimelineAnimation toastAnimation = Builders.animation( //
	Builders.timeline() //
		.value(Builders.timelineValue(window, Scene2dConverters.actorPositionTypeConverter) //
			.keyFrame(0f, new float[] { window.x, outsideY }) //
			.keyFrame(1f, new float[] { window.x, insideY }) //
			.keyFrame(4f, new float[] { window.x, insideY }) //
			.keyFrame(5f, new float[] { window.x, outsideY }) //
		) //
	) //
	.started(true) //
	.delay(0f) //
	.speed(5f / time) //
	.build();

That code creates a new animation which modifies the position of the Window each time update() method is called.

Of course, you can animate the Window using LibGDX custom Actions or another animation framework like Universal Tween Engine, that is up to you.

If you want to see the code itself, you can see the Actor factory named Actors at our Github of commons-gdx.

In our subclass of Game, we added an empty Stage updated in each render() method, and a toast(string) method which creates a toast as explained before using default Skin and time.

MyGame extends Game {

	Stage stage;
	float defaultTime;
	Skin defaultSkin;

	render() {
		// all our game update and render logic
		...
		stage.act(delta);
		stage.draw();
	}

	toast(String text) {
		stage.add(Actors.toast(text, defaultTime, defaultSkin);
	}
}

So, if we want to toast about something, we only have to call game.toast(“something”) and voilá.

You can see a running example of this, you can run the Gui.Scene2dToastPrototype of our prototypes webstart (recommended), or watch the next video:

Conclusion

Despite being a bit incomplete and buggy yet, scene2d API is almost easy to use and it is great if you want to do simple stuff.

Using scene2d is great for our simple need of GUI interfaces because we can quickly test all the stuff in PC. In Vampire Runner we are using scene2d for the feedback dialog, the new version available dialog and for the change username screen.

An interesting thing to have in mind when using scene2d API is that you can make your own Skin to achieve a more integrated look and feel.

As always, hope you like the post and could be of help.


There is a new version of Vampire Runner available, we changed to use a custom solution to store high scores and removed OpenFeint from the game.

One reason for that change was, we were experiencing a long delay when OF dialog loaded for the first time, and we believe some players preferred to close the game instead waiting for the OF dialog to show up. We wanted a seamless system which doesn’t damage the user experience in any way.

Another reason for removing OF was that we wanted to have best scores by day, week, month and we couldn’t do that easily using OF.

Finally, we can use now the scores server in both PC and Android devices without having to make custom code for each platform, something not so good when using OF (could be great if they add a desktop backend).

Don’t get us wrong, OpenFeint is a great solution, it gives a lot of features (scores, achievements, friends and more) and it is not so hard to integrate in your Android project (although the typical way is not so clean). However, for now, we prefer to use our custom solution for our simple and casual games.

Since Christmas happened long ago now, we decided to remove all related decoration and add new one, hope you like it.

Here is the list of changes of the update:

  • Removed OpenFeint, using custom solution for scores with support for today, weekly and monthly best scores.
  • Removed Christmas theme.
  • Added alert to show new updates available (for future versions).

Here is the QR-code if you want to easy access from your Android device:

Enjoy it.


As you may know from our previous posts or from your personal knowledge (obviously), Box2D is a 2D physics engine and Artemis is an Entity System Framework. Box2D is used to add physics behavior to games however it could be used only to detect collisions if you want (that means no dynamic behavior). In this post, we want to share a bit how we are using both frameworks together.

Introduction

The main idea is to react to physics events, like two bodies colliding, to perform some game logic. For example, whenever the main character ship touches an asteroid, it explodes.

When you use Artemis, the game logic is done in an Artemis System or a Script (custom), if you use our customization. The ideal situation would be if you could check in your game logic which entities are in contact or not. In order to make that work, you have to find a way to link a Box2D contact with an Artemis Entity and vice versa.

Our solution

The first thing we do is, to each Artemis Entity we want to have a physics behavior, we add a PhysicsComponent the Box2D Body of the Entity and a Contacts instance where all the Box2D contacts for that Body are stored. Also, in order to get the Entity from the Body, we set the its userData pointing to the Entity.

The Contacts concept gives us useful methods to get information about contacts and the API looks like this:

getContactsCount() : int - returns the contacts quantity
    getContact(index: int) : Contact - returns the contact information

And our Contact concept API, returned by the Contacts getContact() method, looks like this:

getMyFixture() : Fixture - returns the fixture in contact of the Contacts owner Entity.
    getOtherFixture() : Fixture - returns the fixture of the other Entity.
    getNormal() : Vector2 - returns the normal of the contact.

(note: we decided to make a deep copy of the contacts information since it is recommended in the Box2D manual if you use a ContactsListener)

Then, we have a ContactsListener (named PhysicsListener) which, whenever a contact is reported (begin or end), it gets the bodies from the contact and gets the entities from each body userData and then adds or removes the contact data to/from each Entity’s PhysicsComponent using its Contacts instance.

(note: we decided to use a custom ContactListener since it is recommended in the Box2D manual)

Finally, in each Artemis System or Script, we use the Entity’s PhysicsComponent to get the contacts data and we proceed to do the logic we want, for example, destroy the character or enable some special ability, etc.

Here is an example of how we use it inside a Script from our Leave me Alone game:

public void update(World world, Entity e) {
	PhysicsComponent physicsComponent = Components.getPhysicsComponent(e);
	
	Contacts contacts = physicsComponent.getContact();
	
	if (!contacts.isInContact())
		return;
	
	boolean shouldExplode = false;
	
	for (int i = 0; i < contacts.getContactCount(); i++) {
		
		Contact contact = contacts.getContact(i);
		Entity otherEntity = (Entity) contact.getOtherFixture().getBody().getUserData();
		
		GroupComponent groupComponent = Components.getGroupComponent(otherEntity);
		
		if (groupComponent == null)
			continue;
		
		if (groupComponent.group.equals(Groups.EnemyCharacter)) {
			shouldExplode= true;
			break;
		}
		
	}
	
	if (shouldExplode)
		eventManager.dispatch(Events.MainExploded, e);
}

If you use Box2D and you are starting to use Artemis or vice versa, hope this post could help you. Otherwise, I hope you like it.

Also, if you use Artemis with Box2D in another way, would be great to have your point of view.

Thanks.


Uruguay decided to join the Global Game Jam 2012 (GGJ12) for the first time and we (as Gemserk) decided to join them.

The <a href=http://globalgamejam.org>Global Game Jam</a> is an event where all around the world people get together in different locations and split into teams in order to make games in 48 hours following a theme set by the organizers.

This year, the theme was this picture:

Ouroboros

That image represents the Ouroboros which represents the perpetual cyclic renewal of life, the eternal return, and represents the cycle of life, death and rebirth, leading to immortality, as in the phoenix.

The Team

Our team was composed game by José Pedro Gioscia (The Artist), Washington Miranda (Programmer) and us (both Programmers). Hernán Gonzales Martinez from Tono Sound Production provided the music and sound effects for our game, he did the same thing for most of the other teams on our location.

The Game

The game was named Medusa - “La viborita multiloca”, you play the game as a serpent on space and you move horizontally around a cave eating or being hit by other monsters. Whenever the monsters or the obstacles hit your body it breaks from that point. If the remaining part of your body is too short, you are weakened and can’t eat monsters anymore. You die if you hit an obstacle or hit a monster while you are weakened.

The interesting part of the game is that after death comes rebirth. When you die, you revive at the start of the level with an echo of your past lives. They will help you in your journey eating the monsters in their path but they will leave parts of their bodies as new obstacles when they are injured.

Right now the game has no defined objective, it is more an experimental test of the mechanics and when you play you make your own objectives enjoying going through the random level and interacting with your past lives on the world.

Play the game online, or download a runnable jar to play it. Control the snake with the arrow keys.

Conclusions about the Global Game Jam

What went wrong

  • Ironically even though the venue was in a building of the biggest ISP on Uruguay (Antel) the wifi sucked, it used a captive portal method of authentication and forced you to reauthenticate all the time, luckily we could steal the LAN connection from some unused PCs.

What went right

  • We delivered a finished game
  • We were able to meet and talk with lots of people that are working locally in the video games industry (Batoví, Powerful Robot, Belfry Games, Sebagames).
  • We were finally able to get to talk a little with Pablo Realini from IronHide Game Studio makers of the awesome Kindom Rush, who confessed that he is the biggest fan of Gemserk 😉
  • The whole organization and the people who coordinated the GGJ in Uruguay were awesome, the venue was really nice, we had food and drinks available (from the second best carbonated beverage and the second best big burger chain).
  • Everyone on the jam was really nice, included our team members, there were no problems between the participants, and it was great meeting all of them.
  • This was the first time we worked face to face with an artist.
  • We had fun 🙂

Advice for other jams

  • Take your time to refine your game idea, don’t just start implementing right away, think a little about how will the gameplay work, what will the player do, how will he feel when playing, are the mechanics natural, how will you explain them, etc.
  • A good way to split work between programmers is to make small prototypes of different parts of the game (in our case we started prototyping the snake behaviour while we were building the skeleton for the rest of the game)
  • Try to rest, trying to stay up both nights of the event will be too much for your body to handle, and you will be tired and it will be difficult to concentrate, making you make lots of mistakes. In our case we went home to sleep on Friday night after we had defined the game idea, and we started Saturday morning well rested. Play the other games for the GGJ12 from Uruguay here.

We hope you like it.