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 ThisI 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 Handler1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| 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;
public boolean running = false; private AbstractStage currentstage= null; private boolean change = false; private int newstage = 0; 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(){ this.running = true; this.changeStage(StageHandler.Stage1);
while(running){ if(change){ this.changeStage(this.newstage); } this.currentstage.draw(); } }
public void postStageChange(int stageid){ this.change = true; this.newstage = stageid; }
private void changeStage(int stageid){ if(this.currentstage!= null){ this.currentstage.unload(); } this.currentstage = stage.get(stageid); this.currentstage.load(); this.change = false; } } |
And here's the Abstract class1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| public abstract class AbstractStage{ private StageHandler stagehandler = null; public AbstractStage(StageHandler stagehandler){ this.stagehandler = stagehandler; ) 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):
1
| 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:
1
| this.stagehandler.stage.get(StageHandler.OPTIONS).draw(); |
Some Things to Keep in MindI'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.