stock with concept - game stage/scene

Hello guys …
I have been programming my first game in lwjgl and I get stuck thinking how to make some sort of game stage/scene management in the main class (who create the Display and AL)

I make the following Interface


package interfaces;

import gametools.TimerTool;

public interface Stage {

	public void setUpObjects();
	
	public void draw();

	public void update(TimerTool timer);

	public void input();

	public void unloadObjects();

}

and an Abstract class for my game stages classes…
but Im not sure how to manage the navigation between one stage to another …

I follow some tutorials that propose making something like this in the main class


public enum GameState {
		INTRO, MAIN_MENU, GAME;
	}

private void checkInput() {
		switch (state) {
		case INTRO:
			if(Keyboard.isKeyDown(Keyboard.KEY_RETURN)){
				state=State.MAIN_MENU;
			}
			if(Keyboard.isKeyDown(Keyboard.KEY_ESCAPE)){
				Display.destroy();
				System.exit(0);
			}
			break;
		case GAME:
			if(Keyboard.isKeyDown(Keyboard.KEY_BACK)){
				state=State.MAIN_MENU;
			}
			break;
		case MAIN_MENU:
			if(Keyboard.isKeyDown(Keyboard.KEY_RETURN)){
				state=State.GAME;
			}
			if(Keyboard.isKeyDown(Keyboard.KEY_SPACE)){
				state=State.INTRO;
			}
			break;
		}
	}

and rendering and updating different stuff depending on the current stage … but it is pretty basic …
How can i manage this transition when each stage have his own class (extending my Abstract Stage class) and make each class capable to say to the main class go to n stage, unload his content and the main class load the next stage?, and if its possible want to render and update two stages at the same time (like OPTION over MAIN_MENU, and OPTIONS over GAME).

Has been thinking in static stages or something like that but nothing accomplish what I want … :clue:

can anyone make me some suggestions …
thank you a lot…

by the way … forgive me if my english is a bit primitive … its not my native language

I didn’t see anything specific to OpenGL, so if I missed it then let me know.
That aside here are my thoughts on your predicament.

One Way of Doing This
I think the best way to do it is to split it up into 3 different classes or rather 2 classes and the all your sub classes who extend the abstract class.
Basically you have a handler class who is responsible for handling the basic graphics, like initializing any OpenGL and LWJGL Display settings.
It would also handle the transitioning between your stages.

For the stages themselves, they would contain all the objects you need to load, unload and how you want to draw stuff for that stage.

But let’s take a look at the code first. It should make a bit more sense. Though do keep in mind I’m sure there’s more ways to do this and I make no claims to being a pinnacle of proper programming practices.

Here’s the stage Handler

public class StageHandler{
	public static final int STAGE1 =1;
	public static final int STAGE2 =2;
	public static final int STAGE3 =3;
	public static final int OPTIONS =4;

	public Map<Integer, AbstractStage> stage = null; //A map of all your abstract stages	

	public boolean running = false; //If the rendering of the engine is running		
	
	private AbstractStage currentstage= null; //The current stage you want to draw
	
	private boolean change = false;	//If you need to change the stage
	private int newstage = 0; //The id value for a stage you want to change to	
	
	public void StageHandlder(){
		this.stage = new HashMap<Integer, AbstractStage>();
		
		this.stage.put(StageHandler.STAGE1, new Stage_One(this));
		this.stage.put(StageHandler.STAGE1, new Stage_Two(this));
		this.stage.put(StageHandler.STAGE1, new Stage_Three(this));
		this.stage.put(StageHandler.STAGE1, new Stage_Options(this));
	}		

	public void startRender(){ //Start the render loop
		this.running = true;
		this.changeStage(StageHandler.Stage1);

		while(running){ //Your drawing loop
			if(change){
				this.changeStage(this.newstage); //Change the stage
			}
			
			this.currentstage.draw(); //Draw all the stuff in your stage
		}
	}

	public void postStageChange(int stageid){ //Prep for a stage change
		this.change = true;
		this.newstage = stageid;
	}

	private void changeStage(int stageid){ //Change to a new stage
		if(this.currentstage!= null){ //Avoid the start up null
			this.currentstage.unload(); //Unload the stage you are transitioning from
		}
		this.currentstage = stage.get(stageid); //Get the stage you are transitioning to
		this.currentstage.load(); //Load all the stuff for the stage
		this.change = false;
	}
}

And here’s the Abstract class

public abstract class AbstractStage{
	
	private StageHandler stagehandler = null; //Used as a reference back to the handler
	
	public AbstractStage(StageHandler stagehandler){
		this.stagehandler = stagehandler;
	)
	
	//Load, unload and drawing stuff
	public abstract void load();
	public abstract void unload();
	public abstract void draw();

	void changeStage(int stageid){
		this.stagehandler.postStageChange(stageid);
	}
}

Now in order to change stages, all you have to do from your extended abstract sub is call the stage you want to change to (let’s use Stage3 as an example):

this.changeStage(StageHandler.STAGE3);

This setup does leave the door open for calling out a stage and rendering it from within anywhere; the catch being it needs to already be loaded. For example, you would need load the Options stage when the options are entered and then unload them after they’re exited. (I’m not a big fan of this, see below).
To do that, all you need to do this from wthin a stage:

this.stagehandler.stage.get(StageHandler.OPTIONS).draw();

Some Things to Keep in Mind
I’m not really sure you would want to draw 2 stages at the same time. Particularly with the options menu. That seems like something which should be taken care of with a class which handles the drawing of windows. Trying to combine window logic with stage logic could get messy.

This is only the tip of inter-class communication. If you’re running a multi-threaded application, you’ll need to take care when passing messages back and forth.

You might want to see how the Stage implementation works in LibGDX’s scene2d. The code is all very readable. Your Stage is an interface, so you’re already doing GDX one better there.

So … another class as a stage handler … what a clever idea, i will try to implement this and see if its results to me … thank you :smiley: