Opening an inventory Screen

Hey guys, I’m working on making an inventory screen that pops up and pauses the game in the backround, heres what I have.

In one class named Inventory I have this boolean

static boolean inventoryOpen = false;

obviously when that value is false that means that the inventory is closed.

and if it is false than the game should run like normal in my gameloop, you can see that on line 24.
The problem I’m having is that even though if I change “inventoryOpen” to true or even leave it at false, the game is just paused right from when I first launch it.

 public void run() {
    //initialize
    Background.initialize();
    Background.entityAdder();
    //------------------------
    addKeyListener(this); 
    double lastGameplayTime= System.currentTimeMillis();
    double now;
    double counting = 0;
    
    while(running)
    { 
      //this enables frame skipping
      now = System.currentTimeMillis();
      if(now>lastGameplayTime){
        counting=0;
        while (now>lastGameplayTime)
        {
          counting++;
          if(counting>=10){
            lastGameplayTime=System.currentTimeMillis();
            break;
          }
          if(Inventory.inventoryOpen=false){
          for(Entity a: Background.entities) //this loop executes each action in the entities array in the background class.
            a.Action();
          lastGameplayTime+=gameplayFrequency;      
          }
        }
        repaint();                         //this refreshes the screen
      }
    }
    now=System.currentTimeMillis();
    if(now>lastGameplayTime){
      try {Thread.sleep((long) (now-lastGameplayTime));}
      catch (InterruptedException e) {e.printStackTrace();} 
    }
  }

Your if is wrong, just see the =


if(Inventory.inventoryOpen=false)

instead of the ==


if(Inventory.inventoryOpen==false)

oh wow, thanks so much :stuck_out_tongue:

Or (so you can’t do it wrong)
if(!Inventory.inventoryOpen) :slight_smile:

Mike

Another way to do this could be that you make a State System.
With that approach you could easily add more States like a game menu or battle menu, etc.
Could look like this pseudo code snippets:


public interface State {
   public void update();
   public void render();
}


public class InventoryState implements State {
   public void update() {
      // insert update code here
   }

   public void render() {
      // insert render code here
   }
}


public class Game {
   private StateMachine stateMachine = new StateMachine();
   private boolean running;

   public void gameLoop() {
      // initialize etc.

      while(running) {
         // getting delta time and so on

         stateMachine.update();
         stateMachine.render();

         // some fps mechanism like Thread.sleep()
      }
   }
}

And for changing the State you could use a state machine:


public class StateMachine {
   private Map<String, State> states = new HashMap<String, State>();
   private State currentState;

   public StateMachine() {
      addState("MainGame", new MainGameState());
      addState("InventoryState", new InventoryState());
      changeState("MainGame");
   }

   public void update() {
      currentState.update();
   }

   public void render() {
      currentState.render();
   }

   public void changeState(String stateName) {
      currentState = states.get(stateName);
   }

   public void addState(String stateName, State state) {
      states.put(stateName, state);
   }
}

Free to use for anyone :slight_smile:

Thats pretty sweet, I actually might use it!

Well in that case you might consider using a state stack instead of a state machine, it could be somewhat more flexible:


public class StateStack{
   private Map<String, State> states = new HashMap<String, State>();
// private Stack<State> stack = new Stack<State>();
// But Stack<E> extends Vector<E>, so you should probably use Deque<E> instead:
   private Deque<State> stack = new ArrayDeque<State>();

   public StateStack() {
      addState("MainGame", new MainGameState());
      addState("InventoryState", new InventoryState());
      pushState("MainGame");
   }

   public void update() {
      State currentState = stack.peek();
      currentState.update();
   }

   public void render() {
      State currentState = stack.peek();
      currentState.render();
   }

   /** Enter new State */
   public void pushState(String stateName) {
      State newState = states.get(stateName);
      stack.push(newState);
   }

   /** Exit current State and return to the State before */
   public void popState() {
      stack.pop();
   }

   public void addState(String stateName, State state) {
      states.put(stateName, state);
   }
}

With that approach you don’t have to remember which State was before the current State :wink:
But with a few States (like about two) the state machine is entirely sufficient.
Glad if it helps :slight_smile:

Hey I’m trying to put in your StateStack right now and the issue I have is on line 8 where it reads " pushState(states.get(“MainGame”)); "
I get an error that reads
“The method pushState(String) in the type StateStack is not applicable for the arguments (State)”

however if I make it so that
the pushState Method in line 22 takes a state instead than it compiles, I cant really test it yet cause I dont have my inventory and all set up yet, but any idea on whats going on with that?

Oh… that’s my bad :-X
Of course it should be like this:


public StateStack() {
   addState("MainGame", new MainGameState());
   addState("InventoryState", new InventoryState());
   pushState("MainGame");
}

I messed it up when I copy&pasted the StateMachine and changed it to the StateStack ::slight_smile:
Maybe I should change it in the StackMachine as well so it looks similar :persecutioncomplex:
I’ll fix it in the code above! Thanks :wink:

No problem :stuck_out_tongue: