• Sponsored Links

Step 11 : Step by Step libGDX Tutorial : Exploring States and Game State Manager

Share this :

Step by Step libGDX Tutorial : Exploring States and Game State Manager

We understand what is Game world and what are Game states . Lets begin to code and start creating the States for our game .

Open the State Class we created in last section and declare following as :

OrthographicCamera is a camera with orthographic projection and we will use it to locate a position in our Game world . Its API Docs can be read here

protected OrthographicCamera cam;

Vector3 object mouse will be used as a pointing device

protected Vector3 mouse;

GameStateManager will be used to manage our states and hence we can put a state over a state , pause a state , resume state etc  . We will create a new class named GameStateManager shortly , so in case you are getting errors on writing these lines . Just bear for some time

protected GameStateManager gsm;

Creating a constructor for this state

protected State(GameStateManager gsm){
this.gsm = gsm;
cam = new OrthographicCamera();
mouse = new Vector3();

After Constructor code lets set some methods here

handleInput method will be used to handle any iput being sent by user , for example tapping etc

public abstract void handleInput();

update method Its takes in Delta time , i.e. time between 2 frames rendered
public abstract void update(float dt);

render method is used to draw things on the screen . A SpriteBatch is a container for anything that we need to render on our screen
public abstract void render(SpriteBatch sb);

This method will be used to dispose all the textures , music etc when a state is closed to avoid memory leaks
public abstract void dispose();

Game State Manager is basically used to manage our states i.e. lets say player is playing the game and we have current running state as Play State and
lets say Player presses pause and then Game state manager will help us to put pause state over Play state , So Game State manager is basically a Stack of states and it renders the one at the top and hence to put a new state as current state we it , to take out current state and put previous state as running state we can pop current state .

Lets create a new Class Called GameStateManager under package States which we are going to use to manage our states as below . See the Description of each line just above the line

public class GameStateManager {
//a private Stack object for states 
private Stack states;

//constructor for GameStateManager
public GameStateManager(){
 states = new Stack();
 }

//Method push to a new State onto this stack.
public void push(State state){
states.push(state);
}

//This method call returns the object at the top of this stack.
public void pop(){
states.pop();
}

//New method when we want to pop some state and instantly push a new state
public void set(State state){
states.pop();
states.push(state);

}

//dt is delta time , i.e. change in time between 2 renders
public void update(float dt){ 
states.peek().update(dt);
}
//Method to render SpriteBatch on the screen .It look at the top of the stack using peek method and 
//then it renders it on the screen
public void render (SpriteBatch sb){
states.peek().render(sb);
}

}

Lets Now open BriskyDemo.java

It has a render methods which renders in loop over and over again and in this method we want our Game state manager to update first and then render our game states  . Change following in this Class :

  1. Create a Game state manager in this program as well as lets make the SpriteBatch as private variable .
    private GameStateManager gsm;
    private SpriteBatch batch;
  2. edit Create Method and create the gsm there
    1. gsm = new GameStateManager();
  3. remove the line  "img = new Texture("badlogic.jpg");"  from Create method as this is default badlogic file
  4. Add a new MenuState there , we will be creating it shortly
    1. gsm.push(new MenuState(gsm));
  5. In Render method , add update method which should update in delta time and the it should render our batch
    1. gsm.update(Gdx.graphics.getDeltaTime());
    2. gsm.render(batch);
  6. Remove line Gdx.gl.glClearColor(1, 0, 0, 1); from render method and put it in Create method
  7.  remove the batch begin/draw and end lines from the code at this point

Lets Create our first State  - Menu State

Create a new Java Class Named Menu State inside State package and extend it with State and Override all the methods we created in State Class as below :

  1. Create a New Class Named MenuState under States Package
  2. extend MenuState Class with State abstract class we created in above section
  3. Generate Constructor from Super Class

    Generate Constructorsf rom Super Class Eclipse

    Generate Constructorsf rom Super Class Eclipse

  4. Generate Override methods
    Generate Override methods Eclipse

    Generate Override methods Eclipse

    Generate Override methods Selection

    Generate Override methods Selection

  5. Execute run and see what it shows , it should show just red screen now as we have removed the badlogic image as of now , basically we are showing our menu state which is empty .

    Empty Menu State

    Empty Menu State

If its not running and you are seeing some errors . Dont worry might be if you have missed and imports . I will provide full code of classes which we have changed today .

Lets make it a real menu screen now and for that we need a background image and a play button .

  1. Get one image for background and one for play button and put it in your android assets directory i.e.
    BriskyDemo\android\assets   because libgdx takes all the resources form this directory as default . You can use the below Images for this Tutorial
  2. create these 2 images as textures in MenuState Class
    1. Declare these 2 private texture variables
      1. private Texture background;
      2. private Texture playBtn;
    2. Set Values to these textures of the file name which you have put in your android asset directory
      1. background = new Texture("playBg_menu.png");
      2. playBtn= new Texture("playButton.png");
  3.   Render these images in the screen
    1. Add following in Render method
      1. sb.begin();
      2. sb.draw(background, 0, 0, BriksyDemo.WIDTH, BriksyDemo.HEIGHT);
      3. sb.draw(playBtn,(BriksyDemo.WIDTH/2) - (playBtn.getWidth() / 2), BriksyDemo.HEIGHT/2);
      4. sb.end();
    2. Dispose these 2 textures in dispose method
      1. background.dispose();
      2. playBtn.dispose();

Just Run button and you will see now menu state rendered to the screen . Wonderful ! it seems we are doing something ...

Menu State With Button

Menu State With Button

Today We have created / made changes in below files

  •  State.java
  • GameStateManager.java
  • MenuState.java
  • BriskyDemo.java

Code for each f these s as below

State.java

package States;

import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Vector3;

public abstract class State {

	protected OrthographicCamera cam;
	protected Vector3 mouse;
	protected GameStateManager gsm;

	protected State(GameStateManager gsm) {
		this.gsm = gsm;
		cam = new OrthographicCamera();
		mouse = new Vector3();
	}

	public abstract void handleInput();

	public abstract void update(float dt);

	public abstract void render(SpriteBatch sb);

	public abstract void dispose();

}

GameStateManager.java

package States;

import java.util.Stack;

import com.badlogic.gdx.graphics.g2d.SpriteBatch;

public class GameStateManager {
	private Stack states;

	public GameStateManager() {
		states = new Stack();
	}

	public void push(State state) {
		states.push(state);
	}

	public void pop() {
		states.pop();
	}

	public void set(State state) {
		states.pop();
		states.push(state);

	}

	public void update(float dt) {
		states.peek().update(dt);

	}

	public void render(SpriteBatch sb) {
		states.peek().render(sb);
	}
}

MenuState.java

package States;

import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.versionpb.briskybird.BriskyDemo;

public class MenuState extends State {
	
	private Texture background;            //New Texture explained here 
    private Texture playBtn;
    
    public MenuState(GameStateManager gsm) {
		super(gsm);
		background = new Texture("playBg_menu.png");
		playBtn = new Texture("playButton.png");
		
	}
    
	@Override
	public void handleInput() {
	
		
	}

	@Override
	public void update(float dt) {
		
		
	}

	@Override
	public void render(SpriteBatch sb) {
		sb.begin(); 
		sb.draw(background, 0, 0, BriskyDemo.WIDTH, BriskyDemo.HEIGHT);
		sb.draw(playBtn,(BriskyDemo.WIDTH/2) - (playBtn.getWidth() / 2), BriskyDemo.HEIGHT/2);
		sb.end(); 
		
	}

	@Override
	public void dispose() {
		background.dispose();
        playBtn.dispose();
		
	}

	

}

BriskyDemo.java

package com.versionpb.briskybird;

import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;

import States.GameStateManager;
import States.MenuState;

public class BriskyDemo extends ApplicationAdapter {
	public static final int WIDTH = 480;
	public static final int HEIGHT = 600;
	public static final String TITLE = "Brisky Bird Demo";

	Texture img;
	private GameStateManager gsm;
    private SpriteBatch batch;
	
	@Override
	public void create () {
		gsm = new GameStateManager();
		batch = new SpriteBatch();
		Gdx.gl.glClearColor(1, 0, 0, 1);
		gsm.push(new MenuState(gsm));
	}

	@Override
	public void render () {
		
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);

		gsm.update(Gdx.graphics.getDeltaTime());
        gsm.render(batch);
	}
}

Leave a Reply

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

+ 47 = 56