I'm implementing a game in Java, using the classes shown below to control the game logic. I try to be very clear when explaining my question.
GamePanel
I use this class to start the game loop with a thread (only game loop)
public void run() {
init(); //initialize gamePanel components
// game loop
while (running) {
      start = System.nanoTime();
      gameManager.update();
      KeyInput.update();
      MouseInput.update();
      gameManager.draw(graphic);
      Graphics g2 = getGraphics();
      g2.drawImage(image, 0, 0, null);
      g2.dispose();
      elapsed = System.nanoTime() - start;
      wait = targetTime - elapsed / 1000000;
      if (wait < 0)
    wait = 5;
     try {
         Thread.sleep(wait);
     } catch (Exception e) {
     e.printStackTrace();
   }
}
GameManager
I made this class to control each aspect of the game as (update,graphics)
private void loadState(int state) {
if (state == States.MENU.getValue())
gameState = new Menu(this);
else if (state == States.GAME.getValue())
gameState = new Game(this);
else if (state == States.PATHSELECT.getValue())
gameState = new SelectPath(this);
}
public void update() {
if (gameState != null)
gameState.update();
}
public void draw(java.awt.Graphics2D graphic) {
 if (gameState != null)
gameState.draw(graphic);
 else {
JOptionPane.showMessageDialog(null, JOptionPane.ERROR_MESSAGE);
     }
}
Gamestate
GameState is an abstract class that receives, as a constructor parameter, an instance of GameManager and it has abstract methods implemented in each GameState (Menu,Game,MultiPlayer,etc..)
this class has these abstract methods:
controller() -> that verify the state logic
update() -> in case of the currentState is a MultyPlayer , this method call the update method of the class Player , etc...
draw(Graphics g) -> draw to screen the objects of the currentState
I thought of making a utility class singleton that implements all the draw() of each state, but it is very nasty to insert all in a single class.
Example:
instead of calling gameState.draw(graphic); I call Render.getRenderInstance().draw(graphic,gameState);
this solutions works, but I don't like it.
So how can I divide the draw method from the rest of the logic in a pretty way?
Some advice? Thank you.
The usual approach is to divide the game into two parts:
the logic, which looks to be done OK in your case
the scene, where things are drawn
Here in pseudocode is how I do it:
the main loop:
  gamestate.update()
  scene.render();
In the scene you should have all your graphics operations. You should be able to add new graphics to the scene using a call similar to this:
scene.addObject(SomeGraphic graphic);
So the scene would render that graphic every main loop iteration.
To let this happen you should keep a list or another collection inside the Scene class and render every object every tick. So the actuall scene.render() would look like so:
public void render() {
  for(SomeGraphic graphic : objects) {
    graphic.draw()
  }
}
You will be able then to control what is on the scene from the game logic - you will be able to add and delete objects etc.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With