Commits

Regiden  committed 23a6740

- added Pauseable interface for pausing update or render calls
- added Pauseable to GameState and StateBasedGame
- states can now be paused (update or render)
- added test for new paues feature

  • Participants
  • Parent commits 1422545
  • Branches development

Comments (0)

Files changed (5)

File trunk/Slick/src/org/newdawn/slick/state/BasicGameState.java

  * @author kevin
  */
 public abstract class BasicGameState implements GameState {
+	
+	/** Pause boolean for the update call on the current state */
+	private boolean pauseUpdate = false;
+	/** Pause boolean for the render call on the current state */
+	private boolean pauseRender = false;
+	
 	/**
 	 * @see org.newdawn.slick.ControlledInputReciever#inputStarted()
 	 */
 	public void mouseWheelMoved(int newValue) {
 	}
 
+	/**
+	 * Pauses the update call on the this state.
+	 */
+	public void pauseUpdate() {
+		pauseUpdate = true;
+	}
+	/**
+	 * Pauses the render call on the this state.
+	 */
+	public void pauseRender() {
+		pauseRender = true;
+	}
+	/**
+	 * Unpauses the update call on the this state.
+	 */
+	public void unpauseUpdate() {
+		pauseUpdate = false;
+	}
+	/**
+	 * Unpauses the render call on the this state.
+	 */
+	public void unpauseRender() {
+		pauseRender = false;
+	}
+	/**
+	 * @see org.newdawn.slick.util.Pauseable#isUpdatePaused()
+	 */
+	public boolean isUpdatePaused() {
+		return pauseUpdate;
+	}
+	/**
+	 * @see org.newdawn.slick.util.Pauseable#isRenderPaused()
+	 */
+	public boolean isRenderPaused() {
+		return pauseRender;
+	}
+	/**
+	 * Pauses the update call on the this state if <code>pause</code> is true.
+	 */
+	public void setUpdatePaused(boolean pause) {
+		pauseUpdate = pause;
+	}
+	/**
+	 * Pauses the render call on the this state if <code>pause</code> is true.
+	 */
+	public void setRenderPaused(boolean pause) {
+		pauseRender = pause;
+	}
+	
 }

File trunk/Slick/src/org/newdawn/slick/state/GameState.java

 import org.newdawn.slick.Graphics;
 import org.newdawn.slick.InputListener;
 import org.newdawn.slick.SlickException;
+import org.newdawn.slick.util.Pauseable;
 
 /**
  * A single state building up part of the game. The state include rendering, logic and input handling
  *
  * @author kevin
  */
-public interface GameState extends InputListener {
+public interface GameState extends InputListener, Pauseable {
 	/**
 	 * Get the ID of this state
 	 * 

File trunk/Slick/src/org/newdawn/slick/state/StateBasedGame.java

 import org.newdawn.slick.SlickException;
 import org.newdawn.slick.state.transition.EmptyTransition;
 import org.newdawn.slick.state.transition.Transition;
+import org.newdawn.slick.util.Pauseable;
 
 /**
  * A state based game isolated different stages of the game (menu, ingame, hiscores, etc) into 
  *
  * @author kevin
  */
-public abstract class StateBasedGame implements Game, InputListener {
+public abstract class StateBasedGame implements Game, InputListener, Pauseable {
 	/** The list of states making up this game */
 	private HashMap states = new HashMap();
 	/** The current state */
 	/** The transition being used to leave the state */
 	private Transition leaveTransition;
 	
+	/** Pause boolean for the update call on the current state */
+	private boolean pauseUpdate = false;
+	/** Pause boolean for the render call on the current state */
+	private boolean pauseRender = false;
+	
 	/**
 	 * Create a new state based game
 	 * 
 	/**
 	 * @see org.newdawn.slick.Game#render(org.newdawn.slick.GameContainer, org.newdawn.slick.Graphics)
 	 */
-	public final void render(GameContainer container, Graphics g) throws SlickException {
+	public void render(GameContainer container, Graphics g) throws SlickException {
 		preRenderState(container, g);
 		
 		if (leaveTransition != null) {
 			enterTransition.preRender(this, container, g);
 		}
 		
-		currentState.render(container, this, g);
+		if(!pauseRender) {
+			if(!currentState.isRenderPaused()) {
+				currentState.render(container, this, g);
+			}
+		}
 		
 		if (leaveTransition != null) {
 			leaveTransition.postRender(this, container, g);
 	/**
 	 * @see org.newdawn.slick.BasicGame#update(org.newdawn.slick.GameContainer, int)
 	 */
-	public final void update(GameContainer container, int delta) throws SlickException {
+	public void update(GameContainer container, int delta) throws SlickException {
 		preUpdateState(container, delta);
 		
 		if (leaveTransition != null) {
 			}
 		}
 		
-		currentState.update(container, this, delta);
+		if(!pauseUpdate) {
+			if(!currentState.isUpdatePaused()) {
+				currentState.update(container, this, delta);
+			}
+		}
 		
 		postUpdateState(container, delta);
 	}
 	}
 	
 	/**
-	 * Check if the game is transitioning between states
+	 * Check if the game is transitioning between states or if it's paused
 	 * 
-	 * @return True if we're transitioning between states 
+	 * @return True if we're transitioning between states or if it's paused
 	 */
-	private boolean transitioning() {
-		return (leaveTransition != null) || (enterTransition != null);
+	private boolean transitioningOrPaused() {
+		return (leaveTransition != null) || (enterTransition != null) || isUpdatePaused();
 	}
 	
 	/**
 	 * @see org.newdawn.slick.InputListener#controllerButtonPressed(int, int)
 	 */
 	public void controllerButtonPressed(int controller, int button) {
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return;
 		}
 		
 	 * @see org.newdawn.slick.InputListener#controllerButtonReleased(int, int)
 	 */
 	public void controllerButtonReleased(int controller, int button) {
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return;
 		}
 		
 	 * @see org.newdawn.slick.InputListener#controllerDownPressed(int)
 	 */
 	public void controllerDownPressed(int controller) {
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return;
 		}
 		
 	 * @see org.newdawn.slick.InputListener#controllerDownReleased(int)
 	 */
 	public void controllerDownReleased(int controller) {
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return;
 		}
 		
 	 * @see org.newdawn.slick.InputListener#controllerLeftPressed(int)
 	 */
 	public void controllerLeftPressed(int controller) {
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return;
 		}
 		
 	 * @see org.newdawn.slick.InputListener#controllerLeftReleased(int)
 	 */
 	public void controllerLeftReleased(int controller) {
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return;
 		}
 		
 	 * @see org.newdawn.slick.InputListener#controllerRightPressed(int)
 	 */
 	public void controllerRightPressed(int controller) {
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return;
 		}
 		
 	 * @see org.newdawn.slick.InputListener#controllerRightReleased(int)
 	 */
 	public void controllerRightReleased(int controller) {
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return;
 		}
 		
 	 * @see org.newdawn.slick.InputListener#controllerUpPressed(int)
 	 */
 	public void controllerUpPressed(int controller) {
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return;
 		}
 		
 	 * @see org.newdawn.slick.InputListener#controllerUpReleased(int)
 	 */
 	public void controllerUpReleased(int controller) {
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return;
 		}
 		
 	 * @see org.newdawn.slick.InputListener#keyPressed(int, char)
 	 */
 	public void keyPressed(int key, char c) {
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return;
 		}
 		
 	 * @see org.newdawn.slick.InputListener#keyReleased(int, char)
 	 */
 	public void keyReleased(int key, char c) {
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return;
 		}
 		
 	 * @see org.newdawn.slick.InputListener#mouseMoved(int, int, int, int)
 	 */
 	public void mouseMoved(int oldx, int oldy, int newx, int newy) {
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return;
 		}
 		
 	 * @see org.newdawn.slick.InputListener#mouseDragged(int, int, int, int)
 	 */
 	public void mouseDragged(int oldx, int oldy, int newx, int newy) {
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return;
 		}
 		
 	 * @see org.newdawn.slick.InputListener#mouseClicked(int, int, int, int)
 	 */
 	public void mouseClicked(int button, int x, int y, int clickCount) {
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return;
 		}
 		
 	 * @see org.newdawn.slick.InputListener#mousePressed(int, int, int)
 	 */
 	public void mousePressed(int button, int x, int y) {
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return;
 		}
 		
 	 * @see org.newdawn.slick.InputListener#mouseReleased(int, int, int)
 	 */
 	public void mouseReleased(int button, int x, int y) {
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return;
 		}
 		
 	 * @see org.newdawn.slick.InputListener#isAcceptingInput()
 	 */
 	public boolean isAcceptingInput() {		
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return false;
 		}
 
 	 * @see org.newdawn.slick.InputListener#mouseWheelMoved(int)
 	 */
 	public void mouseWheelMoved(int newValue) {
-		if (transitioning()) {
+		if (transitioningOrPaused()) {
 			return;
 		}
 		
 		currentState.mouseWheelMoved(newValue);
 	}
 
+	/**
+	 * Pauses the update call on the current state (Transitions are still possible).
+	 */
+	public void pauseUpdate() {
+		pauseUpdate = true;
+	}
+	/**
+	 * Pauses the render call on the current state (Transitions are still possible).
+	 */
+	public void pauseRender() {
+		pauseRender = true;
+	}
+	/**
+	 * Unpauses the update call on the current state (Transitions are still possible).
+	 */
+	public void unpauseUpdate() {
+		pauseUpdate = false;
+	}
+	/**
+	 * Unpauses the render call on the current state (Transitions are still possible).
+	 */
+	public void unpauseRender() {
+		pauseRender = false;
+	}
+	/**
+	 * @see org.newdawn.slick.util.Pauseable#isUpdatePaused()
+	 */
+	public boolean isUpdatePaused() {
+		return pauseUpdate;
+	}
+	/**
+	 * @see org.newdawn.slick.util.Pauseable#isRenderPaused()
+	 */
+	public boolean isRenderPaused() {
+		return pauseRender;
+	}
+	/**
+	 * Pauses the update call on the current state (Transitions are still possible) if <code>pause</code> is true.
+	 */
+	public void setUpdatePaused(boolean pause) {
+		pauseUpdate = pause;
+	}
+	/**
+	 * Pauses the render call on the current state (Transitions are still possible) if <code>pause</code> is true.
+	 */
+	public void setRenderPaused(boolean pause) {
+		pauseRender = pause;
+	}
+	
 }

File trunk/Slick/src/org/newdawn/slick/tests/StateBasedPauseTest.java

+package org.newdawn.slick.tests;
+
+import org.newdawn.slick.AppGameContainer;
+import org.newdawn.slick.Color;
+import org.newdawn.slick.GameContainer;
+import org.newdawn.slick.Graphics;
+import org.newdawn.slick.Input;
+import org.newdawn.slick.SlickException;
+import org.newdawn.slick.state.StateBasedGame;
+import org.newdawn.slick.tests.states.TestState1;
+import org.newdawn.slick.tests.states.TestState2;
+import org.newdawn.slick.tests.states.TestState3;
+import org.newdawn.slick.util.Log;
+
+/**
+ * A test for pausing states
+ * 
+ * @author kevin
+ */
+public class StateBasedPauseTest extends StateBasedGame {
+	
+	/**
+	 * Create a new test
+	 */
+	public StateBasedPauseTest() {
+		super("State Based Test");
+	}
+	
+	/**
+	 * @see org.newdawn.slick.state.StateBasedGame#initStatesList(org.newdawn.slick.GameContainer)
+	 */
+	public void initStatesList(GameContainer container) {
+		addState(new TestState1());
+		addState(new TestState2());
+		addState(new TestState3());
+	}
+	
+	protected void preUpdateState(GameContainer container, int delta) throws SlickException {
+		
+		// if A is pressed we toggle to update or not update any states. this means you can still switch states but the
+		// update method of the current state will never be called.
+		if(container.getInput().isKeyPressed(Input.KEY_A)) {
+			setUpdatePaused(!isUpdatePaused());
+		}
+		// same goes for render
+		if(container.getInput().isKeyPressed(Input.KEY_S)) {
+			setRenderPaused(!isRenderPaused());
+		}
+		
+		// now we just stop the second state. The other will still update
+		if(container.getInput().isKeyPressed(Input.KEY_D)) {
+			getState(2).setUpdatePaused(!getState(2).isUpdatePaused());
+			
+		}
+		
+		// with this we stop rendering on the third state.
+		if(container.getInput().isKeyPressed(Input.KEY_F)) {
+			getState(3).setRenderPaused(!getState(3).isRenderPaused());
+			
+		}
+	}
+	
+	protected void postRenderState(GameContainer container, Graphics g) throws SlickException {
+		// draw some info
+		g.resetTransform();
+		g.resetFont();
+		g.setColor(Color.white);
+		
+		g.drawString("Current State:" + getCurrentStateID(), 10, 25);
+		
+		g.drawString("Press A to pause/unpause update calls on the current state. Paused: " + isUpdatePaused(), 10, container.getHeight() - 100);
+		g.drawString("Press S to pause/unpause render calls on the current state. Paused: " + isRenderPaused(), 10, container.getHeight() - 85);
+		g.drawString("Press D to pause/unpause update on the state #2. Paused: " + getState(2).isUpdatePaused(), 10, container.getHeight() - 70);
+		g.drawString("Press F to pause/unpause render on the state #3. Paused: " + getState(3).isRenderPaused(), 10, container.getHeight() - 55);
+	}
+	
+	/**
+	 * Entry point
+	 * 
+	 * @param argv
+	 *            The arguments to pass into the test
+	 */
+	public static void main(String[] argv) {
+		try {
+			AppGameContainer container = new AppGameContainer(new StateBasedPauseTest());
+			container.setDisplayMode(800, 600, false);
+			container.start();
+		} catch (SlickException e) {
+			e.printStackTrace();
+		}
+	}
+}

File trunk/Slick/src/org/newdawn/slick/util/Pauseable.java

+package org.newdawn.slick.util;
+
+/**
+ * Interface for a pauseable state
+ * 
+ * @author regiden
+ */
+public interface Pauseable {
+	
+	/**
+	 * pauses update.
+	 */
+	public void pauseUpdate();
+	/**
+	 * pauses render.
+	 */
+	public void pauseRender();
+	/**
+	 * unpauses update.
+	 */
+	public void unpauseUpdate();
+	/**
+	 * unpauses update.
+	 */
+	public void unpauseRender();
+	
+	/**
+	 * @return true if update is paused.
+	 */
+	public boolean isUpdatePaused();
+	/**
+	 * @return true if render is paused.
+	 */
+	public boolean isRenderPaused();
+	
+	/**
+	 * @param pause true if update should be paused.
+	 */
+	public void setUpdatePaused(boolean pause);
+	/**
+	 * @param pause true if render should be paused.
+	 */
+	public void setRenderPaused(boolean pause);
+	
+}