An Introduction to: State Based Games using the Slick2D Library

Simple State machine

I’ve been using the LWJGL library for quite some time to make simple games in Java. For those who don’t know the LWJGL library is used in the indie title Minecraft so it’s quite reliable.

Originally I’d have to copy and past a lot of the structure from project to project as they were all laid our virtually the same, that is until I discovered another library that works in conjunction with LWJGL called Slick.

The Slick library adds a whole lot of extra functionality to LWJGL including:

  • A simple 2D API; meaning you don’t need to spend ages learning OpenGL.
  • Lots of tools straight out of the box that will help you get started developing games.
    • One thing I had fun with was particle effects.
    • And it has easy methods of loading resources like sounds, sprites and images
  • A good framework to build games on so you get started almost immediately.

The feature I am going to talk about in this blog post is part of the API and frameworks for making a game, it’s a class called StateBasedGame.

 

Let’s get to it

First I should describe what a state based game is:

A state based game is a game designed around the idea that at any point in time the game should be in one of several states, and that we can transition between these states when certain conditions are met. In other words we are treating the game as a finite state machine.

The example image below is a quick diagram I have made describing the game Higher Or Lower. I have modelled the different screens of the games as states, but you don’t have to limited by that, you could model outcome of an action as a state if you wanted.

Simple State machine

The two circles represent the entrance and exit to the game.

As you can see I have decided upon having 3 distinct states, one for the menu, another for the scores and one final one for the actual game itself. I have labelled each transition accordingly, hopefully it’s relatively simple to work out what these labels mean.

Enough of the design for now; I know a lot of people are disinterested in it but it can be vital to starting and finishing a project.

 

To the code!

Below you can see the basic skeleton code for a class that implements StateBasedGame:

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.StateBasedGame;

public class HigherOrLower extends StateBasedGame{

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
	}

	public HigherOrLower(String name) {
		super(name);
		// TODO Auto-generated constructor stub
	}

	@Override
	public void initStatesList(GameContainer container) throws SlickException {
		// TODO Auto-generated method stub

	}

}

Not much so far but all the fun stuff to do with StateBasedGame actually happens within the states themselves so let’s add one!

First we need to create one, so let’s make the skeleton code for the menu:

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;

public class Menu extends BasicGameState{

	@Override
	public void init(GameContainer container, StateBasedGame game)
			throws SlickException {
		// TODO Auto-generated method stub

	}

	@Override
	public void render(GameContainer container, StateBasedGame game, Graphics g)
			throws SlickException {
		// TODO Auto-generated method stub

	}

	@Override
	public void update(GameContainer container, StateBasedGame game, int delta)
			throws SlickException {
		// TODO Auto-generated method stub

	}

	@Override
	public int getID() {
		// TODO Auto-generated method stub
		return 0;
	}

}

Note that if you have an IDE like Eclipse it will automatically create these method stubs for you as they are required (declared as abstract in the parent implementation).

Now we have a state, it’s still looking pretty boring. Not only that but it still isn’t even part of the game yet! We need to add it to the states back in HigherOrLower:

	public void initStatesList(GameContainer container) throws SlickException {
		addState(new Menu());
	}

There now it’s part of the game, still it’s missing a few things. Specifically it needs a unique ID to be referred to by, so we shall declare a variable for it named ID and in the getID method return it (I’m not showing the code for this, it’s simple enough). It’s also missing something to display so in the render function I am going to render some basic text on the screen:

	public void render(GameContainer container, StateBasedGame game, Graphics g)
			throws SlickException {
		g.setColor(Color.white);
		g.drawString("Higher or Lower", 50, 10);

		g.drawString("1. Play Game", 50, 100);
		g.drawString("2. High Scores", 50, 120);
		g.drawString("3. Quit", 50, 140);

	}

This is just using some of the basic functionality Slick offers. My resulting output looks like this when I run the game:

Menu State

Not very artsy but you can do wonders with Slick if you choose to

Now let’s add another state, the game state. And we shall also add the code to transition from the menu to it.

I will go through the same process as before; making a new class based on BasicGameState and adding it to our game using the addState method inside initStatesList. Now to add the transition code I have opted for a simple key press but mouse menu options are available and doable within Slick. Within my Menu class I added the following code:

	public void keyReleased(int key, char c) {
		switch(key) {
		case Input.KEY_1:
			game.enterState(Game.ID, new FadeOutTransition(Color.black), new FadeInTransition(Color.black));
			break;
		case Input.KEY_2:
			// TODO: Implement later
			break;
		case Input.KEY_3:
			// TODO: Implement later
			break;
		default:
			break;
		}
	}

Now you may notice the variable game, and wonder what that is. Well within Menu’s init function I added a line to store the game object being passed into the function as an object variable so I could refer back to it later:

	private StateBasedGame game; // stored for later use

	public void init(GameContainer container, StateBasedGame game)
			throws SlickException {
		this.game = game;
	}

Anyway, back to what you will be interested in, the transition:

enterState(Game.ID, new FadeOutTransition(Color.black), new FadeInTransition(Color.black));

If wanted I can omit the last two parameters and just pass in the ID of the state I want to enter, however these last two parameters allow you to customise how changing between states looks, along with if you need any specific code to run between them (like cleaning up of resources in a large game, or automatically saving the game).

Now upon pressing the 1 key I am taken to the main game screen!

 

More to come

And that’s all for now!

I have shown you the basics on how to get started with State Based Games using the Slick library, now I urge you to look at the examples on the Slick website, and to ask any questions you have here, reddit, stackoverflow or the Slick Forums.

I will make a follow up to this introduction detailing an actual implementation of the Higher or Lower game and also how I use the StateBasedGame class in my Tower Defence Game in the near future, until then:

Happy Coding!

4 Comments

  1. Alexis says:

    Text shadow in your code blocks is broken, try something like:

    text-shadow: 1px 1px 2px rgba(0, 0, 0, 0.5);

    for body{}

    • Lyndon says:

      Thanks will give it a go! I am not a big fan of this theme in general am hoping to make my own when I get the time.
      Edit: Looks so much better!

  2. […] again, in this post I intend to pick up where I left off in my last post on State Based games using Slick2D. In my previous post I showed you how to implement up to the […]

  3. […] to stick with a newer library that I have worked in before called Slick2D (See my tutorial on Game States as an example of my use of it before). I also decided to stick with 2D instead of 3D as the book […]

Leave a Reply