Jump to content

  • Log In with Google      Sign In   
  • Create Account


Pause functionality in game works only once


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
20 replies to this topic

#1 warnexus   Prime Members   -  Reputation: 1390

Like
0Likes
Like

Posted 09 February 2013 - 06:32 PM

The idea was making the gameLoop false to pause the game and unpause the game by making the gameLoop true again. It was able to pause and unpause once before the only way to close the game was to use Eclipse's terminate button instead of the x button in the top corner of the game window. 
 
public class Game extends Canvas implements KeyListener{
 
      private boolean isRunning;   
      
      public static void main(String[] args){
        getInstance().run();
      }   
      
      // Singleton pattern get instance
    public static Game getInstance(){
        if (instance == null){
            instance = new Game();
            
        }
        return instance;
        
    }  
 
      private Game(){  
      isRunning = true;  
      }
 
      public void run(){
         // basic game loop
         while(isRunning){
         // draws objects here
         }
      }
 
          @Override
    public void keyPressed(KeyEvent e) {
        // TODO Auto-generated method stub
        switch (e.getKeyCode()) 
        {
        
        // pause the game 
        case (KeyEvent.VK_P):
            
        getInstance().setIsRunning(false);
                    
        break;
        // unpause the game
        case (KeyEvent.VK_U):
 
        getInstance().setIsRunning(true);
        run();
 
        break;
        }
    }
 
}

Edited by warnexus, 09 February 2013 - 08:10 PM.


Sponsor:

#2 slicer4ever   Crossbones+   -  Reputation: 3479

Like
0Likes
Like

Posted 09 February 2013 - 06:51 PM

why are you calling run after you setIsRunning(true)?(now your in a loop inside the input function)

 

if that's not the problem, idk because you barely posted any real code.

 

what we need to see is:

 

Initialization code

--Main game loop(is this controlled by "isRunning", because if so, setting it to false should break the loop.)

---Where you check for input(is this inside your main loop, which is controlled by the "isRunning" flag?)


Edited by slicer4ever, 09 February 2013 - 06:54 PM.

Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

#3 nfactorial   Members   -  Reputation: 729

Like
0Likes
Like

Posted 09 February 2013 - 07:14 PM

Paused and unpaused are typically considered game ''states''. Many represent these states as enumerations, but I would generally represent a game state as an object, I have a whole theory behind my own design for how a game state should be represented but it's a bit ''out of the box'' compared to what is generally considered a game state (from my  experience). Throwing that out the window for now (it's still in the 'theory' phase that I'm testing in a home engine atm, maybe my theory is entirely bogus), you can typically represent a game state with two functions:

 

struct IGameState
{
    virtual void update( const UpdateArgs &updateArgs ) = 0;
    virtual void render( RenderArgs &renderArgs ) = 0;
};

If you consider your states as a stack, your normal game state would perform its rendering and update as normal. You could then 'push' a ''paused''' state onto the stack that forwarded the render state up the stack and simply consumed the update state. Which would give you a perfectly working paused state, you could extend this design further with a menu state etc. But the basics remain the same.

 

I'm not 100% sober atm sorry so please ignore any typo's or weird phrasing, but if there are any queries or questions on that let me know. My current design is much further evolved than this, but this seems like the most simplified to start with, without a huge posting smile.png

 

n!


Edited by nfactorial, 09 February 2013 - 07:16 PM.


#4 warnexus   Prime Members   -  Reputation: 1390

Like
0Likes
Like

Posted 09 February 2013 - 08:12 PM

why are you calling run after you setIsRunning(true)?(now your in a loop inside the input function)

 

if that's not the problem, idk because you barely posted any real code.

 

what we need to see is:

 

Initialization code

--Main game loop(is this controlled by "isRunning", because if so, setting it to false should break the loop.)

---Where you check for input(is this inside your main loop, which is controlled by the "isRunning" flag?)

because my approach was to pause the game. The only way to do it is to break out of the gameLoop. If I unpause the game, I need to call the run method which execute the game loop to keep things drawing again. the run method needs to be called by the programmer. the key events are in the keyPressed method of the Game class since the Game class will be responsible for controlling the pause/unpause nature of the game.

 

Are you sure you saw my code? blink.png


Edited by warnexus, 09 February 2013 - 08:21 PM.


#5 warnexus   Prime Members   -  Reputation: 1390

Like
0Likes
Like

Posted 09 February 2013 - 08:17 PM

Paused and unpaused are typically considered game ''states''. Many represent these states as enumerations, but I would generally represent a game state as an object, I have a whole theory behind my own design for how a game state should be represented but it's a bit ''out of the box'' compared to what is generally considered a game state (from my  experience). Throwing that out the window for now (it's still in the 'theory' phase that I'm testing in a home engine atm, maybe my theory is entirely bogus), you can typically represent a game state with two functions:

 

struct IGameState
{
    virtual void update( const UpdateArgs &updateArgs ) = 0;
    virtual void render( RenderArgs &renderArgs ) = 0;
};

If you consider your states as a stack, your normal game state would perform its rendering and update as normal. You could then 'push' a ''paused''' state onto the stack that forwarded the render state up the stack and simply consumed the update state. Which would give you a perfectly working paused state, you could extend this design further with a menu state etc. But the basics remain the same.

 

I'm not 100% sober atm sorry so please ignore any typo's or weird phrasing, but if there are any queries or questions on that let me know. My current design is much further evolved than this, but this seems like the most simplified to start with, without a huge posting smile.png

 

n!

I am coding my game in Java. I don't think C++ OOP will help me since I never touched much of C++ OOP



#6 slicer4ever   Crossbones+   -  Reputation: 3479

Like
2Likes
Like

Posted 09 February 2013 - 08:33 PM


why are you calling run after you setIsRunning(true)?(now your in a loop inside the input function)

 

if that's not the problem, idk because you barely posted any real code.

 

what we need to see is:

 

Initialization code

--Main game loop(is this controlled by "isRunning", because if so, setting it to false should break the loop.)

---Where you check for input(is this inside your main loop, which is controlled by the "isRunning" flag?)

because my approach was to pause the game. The only way to do it is to break out of the gameLoop. If I unpause the game, I need to call the run method which execute the game loop to keep things drawing again. the run method needs to be called by the programmer. the key events are in the keyPressed method of the Game class since the Game class will be responsible for controlling the pause/unpause nature of the game.

 

Are you sure you saw my code? blink.png

think about what it means to start an infinite loop inside your input logic thread.  and as far as i can see, that infinite loop does not check your input.

 

so yes, we need to see more code(unless my above assumption is correct, and that is why you can only pause/unpause once)

 

insead of doing:

 

 

void run(void){
  while(isRunning){
  }
}

 

try:

 

 

void run(void){
 while(!isDone){
  if(isRunning){
   //game logic here
  }
}

Edited by slicer4ever, 09 February 2013 - 08:37 PM.

Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

#7 warnexus   Prime Members   -  Reputation: 1390

Like
0Likes
Like

Posted 09 February 2013 - 10:16 PM

 


why are you calling run after you setIsRunning(true)?(now your in a loop inside the input function)

 

if that's not the problem, idk because you barely posted any real code.

 

what we need to see is:

 

Initialization code

--Main game loop(is this controlled by "isRunning", because if so, setting it to false should break the loop.)

---Where you check for input(is this inside your main loop, which is controlled by the "isRunning" flag?)

because my approach was to pause the game. The only way to do it is to break out of the gameLoop. If I unpause the game, I need to call the run method which execute the game loop to keep things drawing again. the run method needs to be called by the programmer. the key events are in the keyPressed method of the Game class since the Game class will be responsible for controlling the pause/unpause nature of the game.

 

Are you sure you saw my code? blink.png

think about what it means to start an infinite loop inside your input logic thread.  and as far as i can see, that infinite loop does not check your input.

 

so yes, we need to see more code(unless my above assumption is correct, and that is why you can only pause/unpause once)

 

insead of doing:

 

 

void run(void){
  while(isRunning){
  }
}

 

try:

 

 

void run(void){
 while(!isDone){
  if(isRunning){
   //game logic here
  }
}

why is void a parameter and is not given a data type? I posted my game loop below since I cannot longer edit my initial post. smile.png

 

 

 

public void run(){
        // basic game loop
        while(isRunning){
            // calculate the time since the last loop
            long milliseconds = System.currentTimeMillis() - lastTick;
            lastTick = System.currentTimeMillis();
            
            // set the focus to the panel
            panel.requestFocus();
            
            // get graphics context
            Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
            clearBuffer(g);
            
            // update all game items
            for(GameComponent component : gameObjects){
                component.update(milliseconds);
                
            }
            
            // handle the dynamic objects
            addNewGameComponents();
            removeOldGameComponents();
            
            // draw all game items
            for(GameComponent component: gameObjects){
                component.draw(g);
            }
            
                /* do a bounding box collision of the laser with the
                *  oneEye monster's bounding box every game loop
                *  which is basically every time the game redraws
                *  itself. 
                *  Collision test applies to ALL laser being drawn on screen!
                *  
                *  The easiest way is to check every instance of type Laser in the
                *  ArrayList and tell them to do monster collision detection
                */
                
            // laser check for every OneEye monsters in the ArrayList
            for(GameComponent component: gameObjects){
                if(component instanceof Laser)
                {
                    ((Laser) component).checkMonsterCollision(gameObjects);
                        
                }
                if(component instanceof OneEyeSlashSkill)
                {
                    ((OneEyeSlashSkill) component).checkShipCollision(gameObjects);
                    
                    
                }    
                
            
                
            }
            
            
            
            flipBuffer(g);
            
            // pause for a bit so we don't consume 100% CPU
           
            try { Thread.sleep(10); } catch (Exception e) {}
        
            
        }
    }

Edited by warnexus, 09 February 2013 - 10:30 PM.


#8 epicpunnum   Members   -  Reputation: 454

Like
1Likes
Like

Posted 09 February 2013 - 10:31 PM

Feel free to correct me if I'm wrong (still learning C++, having learned Java, and some C#), but I believe this is what it is...

In C-based languages, void is simply nothingness, as I'm sure you know. Commonly (thought not seen in Java much - at least I don't to use it) void is an unnecessary parameter in functions if used as above. This is merely just a matter of taste from what I know.
Therefore, this:

void run (void){
  //Filler code
}

should compile the same as this:

void run (){
  //Filler code
}

 

Really the only thing that the extra void does is fill in the parameter parenthesis, and make it a bit clearer to the programmer that the function has no intent to take arguments. However, depending on your level of comments & documentation, it may be completely unnecessary. tldr: Don't worry about it.

There may be some subtleties between them, but nothing very significant.


EDIT: Looking at your loop, I'd recommend doing what slicer4ever suggested. That could very likely be the root of your problem. Granted I can't see all of your custom methods (eg: your update() and all that jazz), but looking at it, it doesn't seem like you're doing all too much with your milliseconds variable, rather than using it in one method. Instead of invoking Thread.sleep(), you might be better enclosing your drawing code within an if statement that checks the time.
To give you an idea, take this basic structure:

public void run(){
  //basic game loop
  while (isRunning){
    //calculate time since last loop
    long milliseconds = System.currentTimeMillis() - lastTick;
    
    //This would be the change here
    //replace (1000/framesPersecond) if you prefer ticks in ms
    if (framesPerSecond> 0 && milliseconds > (1000/framesPerSecond)){
      //GAME LOGIC & DRAWING

      lastTick = System.currentTimeMillis(); //moved into the if statement
    }
  }
}

I believe that a structure more like this would save yourself the time of your interpreter having to call a method outside of your class. It also should be a bit more accurate and constant for your game, as the sleep() and wait() methods can be a bit off at times, or have occasionally failed.
An article here could explain the inaccuracy a bit more than I could.


Edited by epicpunnum, 09 February 2013 - 10:58 PM.


#9 slicer4ever   Crossbones+   -  Reputation: 3479

Like
1Likes
Like

Posted 09 February 2013 - 10:52 PM

 

 


why are you calling run after you setIsRunning(true)?(now your in a loop inside the input function)

 

if that's not the problem, idk because you barely posted any real code.

 

what we need to see is:

 

Initialization code

--Main game loop(is this controlled by "isRunning", because if so, setting it to false should break the loop.)

---Where you check for input(is this inside your main loop, which is controlled by the "isRunning" flag?)

because my approach was to pause the game. The only way to do it is to break out of the gameLoop. If I unpause the game, I need to call the run method which execute the game loop to keep things drawing again. the run method needs to be called by the programmer. the key events are in the keyPressed method of the Game class since the Game class will be responsible for controlling the pause/unpause nature of the game.

 

Are you sure you saw my code? blink.png

think about what it means to start an infinite loop inside your input logic thread.  and as far as i can see, that infinite loop does not check your input.

 

so yes, we need to see more code(unless my above assumption is correct, and that is why you can only pause/unpause once)

 

insead of doing:

 

 

void run(void){
  while(isRunning){
  }
}

 

try:

 

 

void run(void){
 while(!isDone){
  if(isRunning){
   //game logic here
  }
}

why is void a parameter and is not given a data type? I posted my game loop below since I cannot longer edit my initial post. smile.png

 

 

 

public void run(){
        // basic game loop
        while(isRunning){
            // calculate the time since the last loop
            long milliseconds = System.currentTimeMillis() - lastTick;
            lastTick = System.currentTimeMillis();
            
            // set the focus to the panel
            panel.requestFocus();
            
            // get graphics context
            Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
            clearBuffer(g);
            
            // update all game items
            for(GameComponent component : gameObjects){
                component.update(milliseconds);
                
            }
            
            // handle the dynamic objects
            addNewGameComponents();
            removeOldGameComponents();
            
            // draw all game items
            for(GameComponent component: gameObjects){
                component.draw(g);
            }
            
                /* do a bounding box collision of the laser with the
                *  oneEye monster's bounding box every game loop
                *  which is basically every time the game redraws
                *  itself. 
                *  Collision test applies to ALL laser being drawn on screen!
                *  
                *  The easiest way is to check every instance of type Laser in the
                *  ArrayList and tell them to do monster collision detection
                */
                
            // laser check for every OneEye monsters in the ArrayList
            for(GameComponent component: gameObjects){
                if(component instanceof Laser)
                {
                    ((Laser) component).checkMonsterCollision(gameObjects);
                        
                }
                if(component instanceof OneEyeSlashSkill)
                {
                    ((OneEyeSlashSkill) component).checkShipCollision(gameObjects);
                    
                    
                }    
                
            
                
            }
            
            
            
            flipBuffer(g);
            
            // pause for a bit so we don't consume 100% CPU
           
            try { Thread.sleep(10); } catch (Exception e) {}
        
            
        }
    }

 

 

ok, so i'm fairly certain(note: i've used little java, so i might be wrong in how java handle's things) the problem is as i described, you are calling run inside your input logic, this means that you essentially never get back to check input again.

 

the void inside the run is just indicating that their are no parameters to pass to the function(as epicpunnum said), so you can freely think of run() and run(void) as the same thing.

 

in short, don't break the loop inside run, just do a conditional check inside the loop that if(isRunning==true), and put your logic inside that.

alternatively, you coud do:

 

void run(){
  while(!isDone){
   if(!isRunning) continue; //goes back to the beginning of the loop.
   //your code here!
  }
};

 

basically, your core problem is that you call run() inside your input code, instead you need to re-think how you manage your main loop with pause/unpause.


Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

#10 warnexus   Prime Members   -  Reputation: 1390

Like
0Likes
Like

Posted 09 February 2013 - 10:55 PM

Feel free to correct me if I'm wrong (still learning C++, having learned Java, and some C#), but I believe this is what it is...

In C-based languages, void is simply nothingness, as I'm sure you know. Commonly (thought not seen in Java much - at least I don't to use it) void is an unnecessary parameter in functions if used as above. This is merely just a matter of taste from what I know.
Therefore, this:

void run (void){
  //Filler code
}

should compile the same as this:

void run (){
  //Filler code
}

 

Really the only thing that the extra void does is fill in the parameter parenthesis, and make it a bit clearer to the programmer that the function has no intent to take arguments. However, depending on your level of comments & documentation, it may be completely unnecessary. tldr: Don't worry about it.

There may be some subtleties between them, but nothing very significant.

Java does not allow void in the parameter. Maybe for other languages but not Java. I tested it just now


Edited by warnexus, 09 February 2013 - 11:02 PM.


#11 epicpunnum   Members   -  Reputation: 454

Like
0Likes
Like

Posted 09 February 2013 - 11:00 PM

Feel free to correct me if I'm wrong (still learning C++, having learned Java, and some C#), but I believe this is what it is...

In C-based languages, void is simply nothingness, as I'm sure you know. Commonly (thought not seen in Java much - at least I don't to use it) void is an unnecessary parameter in functions if used as above. This is merely just a matter of taste from what I know.
Therefore, this:

void run (void){
  //Filler code
}

should compile the same as this:

void run (){
  //Filler code
}

 

Really the only thing that the extra void does is fill in the parameter parenthesis, and make it a bit clearer to the programmer that the function has no intent to take arguments. However, depending on your level of comments & documentation, it may be completely unnecessary. tldr: Don't worry about it.

There may be some subtleties between them, but nothing very significant.

Java does not allow void in the parameter. Maybe for other languages but not Java. I tested it for now

That would easily explain why I don't use it. Wasn't near Eclipse to test myself.



#12 warnexus   Prime Members   -  Reputation: 1390

Like
0Likes
Like

Posted 09 February 2013 - 11:04 PM

 

 

 


why are you calling run after you setIsRunning(true)?(now your in a loop inside the input function)

 

if that's not the problem, idk because you barely posted any real code.

 

what we need to see is:

 

Initialization code

--Main game loop(is this controlled by "isRunning", because if so, setting it to false should break the loop.)

---Where you check for input(is this inside your main loop, which is controlled by the "isRunning" flag?)

because my approach was to pause the game. The only way to do it is to break out of the gameLoop. If I unpause the game, I need to call the run method which execute the game loop to keep things drawing again. the run method needs to be called by the programmer. the key events are in the keyPressed method of the Game class since the Game class will be responsible for controlling the pause/unpause nature of the game.

 

Are you sure you saw my code? blink.png

think about what it means to start an infinite loop inside your input logic thread.  and as far as i can see, that infinite loop does not check your input.

 

so yes, we need to see more code(unless my above assumption is correct, and that is why you can only pause/unpause once)

 

insead of doing:

 

 

void run(void){
  while(isRunning){
  }
}

 

try:

 

 

void run(void){
 while(!isDone){
  if(isRunning){
   //game logic here
  }
}

why is void a parameter and is not given a data type? I posted my game loop below since I cannot longer edit my initial post. smile.png

 

 

 

public void run(){
        // basic game loop
        while(isRunning){
            // calculate the time since the last loop
            long milliseconds = System.currentTimeMillis() - lastTick;
            lastTick = System.currentTimeMillis();
            
            // set the focus to the panel
            panel.requestFocus();
            
            // get graphics context
            Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
            clearBuffer(g);
            
            // update all game items
            for(GameComponent component : gameObjects){
                component.update(milliseconds);
                
            }
            
            // handle the dynamic objects
            addNewGameComponents();
            removeOldGameComponents();
            
            // draw all game items
            for(GameComponent component: gameObjects){
                component.draw(g);
            }
            
                /* do a bounding box collision of the laser with the
                *  oneEye monster's bounding box every game loop
                *  which is basically every time the game redraws
                *  itself. 
                *  Collision test applies to ALL laser being drawn on screen!
                *  
                *  The easiest way is to check every instance of type Laser in the
                *  ArrayList and tell them to do monster collision detection
                */
                
            // laser check for every OneEye monsters in the ArrayList
            for(GameComponent component: gameObjects){
                if(component instanceof Laser)
                {
                    ((Laser) component).checkMonsterCollision(gameObjects);
                        
                }
                if(component instanceof OneEyeSlashSkill)
                {
                    ((OneEyeSlashSkill) component).checkShipCollision(gameObjects);
                    
                    
                }    
                
            
                
            }
            
            
            
            flipBuffer(g);
            
            // pause for a bit so we don't consume 100% CPU
           
            try { Thread.sleep(10); } catch (Exception e) {}
        
            
        }
    }

 

 

ok, so i'm fairly certain(note: i've used little java, so i might be wrong in how java handle's things) the problem is as i described, you are calling run inside your input logic, this means that you essentially never get back to check input again.

 

the void inside the run is just indicating that their are no parameters to pass to the function(as epicpunnum said), so you can freely think of run() and run(void) as the same thing.

 

in short, don't break the loop inside run, just do a conditional check inside the loop that if(isRunning==true), and put your logic inside that.

alternatively, you coud do:

 

 

void run(){
  while(!isDone){
   if(!isRunning) continue; //goes back to the beginning of the loop.
   //your code here!
  }
};

 

basically, your core problem is that you call run() inside your input code, instead you need to re-think how you manage your main loop with pause/unpause.

what do you mean by input logic? on a side note, isn't a game loop consider to be an infinite loop if runs constantly to do handling tasks like drawing objects and testing collisions?

 

but the game loop keeps running and the game class has keylisteners added. It is not that I removed the listeners.


Edited by warnexus, 09 February 2013 - 11:12 PM.


#13 slicer4ever   Crossbones+   -  Reputation: 3479

Like
0Likes
Like

Posted 09 February 2013 - 11:19 PM

..snip...

what do you mean by input logic? on a side note, isn't a game loop consider to be an infinite loop if runs constantly to do handling tasks like drawing objects and testing collisions?

looking at you main game loop, you make absolutly zero calls to the function keyPress, or any indication that your call a function which query's input to potentially call the keyPress function.

 

so what does that mean? it means that in your initializing code, java spawned another thread that catch's input, and call's the keyPress function when you've done some type of input.

 

so, basically, you have 2 threads going:

 

thread 1: drawing/updating objects.

thread 2: getting input.

 

so, when you set the isRunning flag to false to pause, this is what your threads look like:

 

thread 1: finished(since you broke out of the loop, it completed the run() function, and the thread finished running since it reached the bottom of execution of run, and then reached the end of main).

thread 2: still looking for input.

 

so, when you go to unpause, this is what happens:

 

thread 1: still finished

thread 2: is now in a loop, doing what thread 1 used to do.

 

their are two problems with this.

 

first of all, you no longer get input.

 

second, openGL is built to receive commands from a single thread, and only one thread, this is the default thread that main is executed in. because it is now submitting commands from thread 2, the commands are essentially invalidated, and don't do anything.  this is why once you unpause the game, you have to force it to close, the game is still technically updating, it just can't draw anything, because openGL refuses all commands from the second thread.

you also can't break out of it because you no longer can receive inputs, since you've stalled the input managed since you never go back to it.

 

hope this helps you understand what's going on better=-).


Edited by slicer4ever, 09 February 2013 - 11:22 PM.

Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

#14 warnexus   Prime Members   -  Reputation: 1390

Like
0Likes
Like

Posted 09 February 2013 - 11:40 PM

 

..snip...

what do you mean by input logic? on a side note, isn't a game loop consider to be an infinite loop if runs constantly to do handling tasks like drawing objects and testing collisions?

looking at you main game loop, you make absolutly zero calls to the function keyPress, or any indication that your call a function which query's input to potentially call the keyPress function.

 

so what does that mean? it means that in your initializing code, java spawned another thread that catch's input, and call's the keyPress function when you've done some type of input.

 

so, basically, you have 2 threads going:

 

thread 1: drawing/updating objects.

thread 2: getting input.

 

so, when you set the isRunning flag to false to pause, this is what your threads look like:

 

thread 1: finished(since you broke out of the loop, it completed the run() function, and the thread finished running since it reached the bottom of execution of run, and then reached the end of main).

thread 2: still looking for input.

 

so, when you go to unpause, this is what happens:

 

thread 1: still finished

thread 2: is now in a loop, doing what thread 1 used to do.

 

their are two problems with this.

 

first of all, you no longer get input.

 

second, openGL is built to receive commands from a single thread, and only one thread, this is the default thread that main is executed in. because it is now submitting commands from thread 2, the commands are essentially invalidated, and don't do anything.  this is why once you unpause the game, you have to force it to close, the game is still technically updating, it just can't draw anything, because openGL refuses all commands from the second thread.

you also can't break out of it because you no longer can receive inputs, since you've stalled the input managed since you never go back to it.

 

hope this helps you understand what's going on better=-).

I never used openGL. Is openGl related to Java? May I send you my game in an email so you can test the problem? If you can test my game, let me know. I will check back on this thread tomorrow. 


Edited by warnexus, 09 February 2013 - 11:52 PM.


#15 slicer4ever   Crossbones+   -  Reputation: 3479

Like
0Likes
Like

Posted 10 February 2013 - 12:06 AM

 

 

..snip...

what do you mean by input logic? on a side note, isn't a game loop consider to be an infinite loop if runs constantly to do handling tasks like drawing objects and testing collisions?

looking at you main game loop, you make absolutly zero calls to the function keyPress, or any indication that your call a function which query's input to potentially call the keyPress function.

 

so what does that mean? it means that in your initializing code, java spawned another thread that catch's input, and call's the keyPress function when you've done some type of input.

 

so, basically, you have 2 threads going:

 

thread 1: drawing/updating objects.

thread 2: getting input.

 

so, when you set the isRunning flag to false to pause, this is what your threads look like:

 

thread 1: finished(since you broke out of the loop, it completed the run() function, and the thread finished running since it reached the bottom of execution of run, and then reached the end of main).

thread 2: still looking for input.

 

so, when you go to unpause, this is what happens:

 

thread 1: still finished

thread 2: is now in a loop, doing what thread 1 used to do.

 

their are two problems with this.

 

first of all, you no longer get input.

 

second, openGL is built to receive commands from a single thread, and only one thread, this is the default thread that main is executed in. because it is now submitting commands from thread 2, the commands are essentially invalidated, and don't do anything.  this is why once you unpause the game, you have to force it to close, the game is still technically updating, it just can't draw anything, because openGL refuses all commands from the second thread.

you also can't break out of it because you no longer can receive inputs, since you've stalled the input managed since you never go back to it.

 

hope this helps you understand what's going on better=-).

I never used openGL. Is openGl related to Java? May I send you my game in an email so you can test the problem? If you can test my game, let me know. I will check back on this thread tomorrow. 

that's what you took away from my post?

 

i'm assuming your draw code uses openGL underneath(but i can't know for 100%)

 

their's no reason for me to test the problem(nor am i equipped to compile java code at the moment), i've told you several time's what the problem is, and plenty of code on how to fix it.

 

remove calling run from inside your input logic(the code inside the KeyPress function), and re-write your main game loop to not break out of the loop when you change the state of isRunning.

 

edit: hit the sack, come back tommorow, read this again, and you'll probably realize what i'm talking about=-)


Edited by slicer4ever, 10 February 2013 - 12:13 AM.

Check out https://www.facebook.com/LiquidGames for some great games made by me on the Playstation Mobile market.

#16 warnexus   Prime Members   -  Reputation: 1390

Like
0Likes
Like

Posted 10 February 2013 - 12:24 AM

 

 

 

..snip...

what do you mean by input logic? on a side note, isn't a game loop consider to be an infinite loop if runs constantly to do handling tasks like drawing objects and testing collisions?

looking at you main game loop, you make absolutly zero calls to the function keyPress, or any indication that your call a function which query's input to potentially call the keyPress function.

 

so what does that mean? it means that in your initializing code, java spawned another thread that catch's input, and call's the keyPress function when you've done some type of input.

 

so, basically, you have 2 threads going:

 

thread 1: drawing/updating objects.

thread 2: getting input.

 

so, when you set the isRunning flag to false to pause, this is what your threads look like:

 

thread 1: finished(since you broke out of the loop, it completed the run() function, and the thread finished running since it reached the bottom of execution of run, and then reached the end of main).

thread 2: still looking for input.

 

so, when you go to unpause, this is what happens:

 

thread 1: still finished

thread 2: is now in a loop, doing what thread 1 used to do.

 

their are two problems with this.

 

first of all, you no longer get input.

 

second, openGL is built to receive commands from a single thread, and only one thread, this is the default thread that main is executed in. because it is now submitting commands from thread 2, the commands are essentially invalidated, and don't do anything.  this is why once you unpause the game, you have to force it to close, the game is still technically updating, it just can't draw anything, because openGL refuses all commands from the second thread.

you also can't break out of it because you no longer can receive inputs, since you've stalled the input managed since you never go back to it.

 

hope this helps you understand what's going on better=-).

I never used openGL. Is openGl related to Java? May I send you my game in an email so you can test the problem? If you can test my game, let me know. I will check back on this thread tomorrow. 

that's what you took away from my post?

 

i'm assuming your draw code uses openGL underneath(but i can't know for 100%)

 

their's no reason for me to test the problem(nor am i equipped to compile java code at the moment), i've told you several time's what the problem is, and plenty of code on how to fix it.

 

remove calling run from inside your input logic(the code inside the KeyPress function), and re-write your main game loop to not break out of the loop when you change the state of isRunning.

 

edit: hit the sack, come back tommorow, read this again, and you'll probably realize what i'm talking about=-)

thanks, slicer. I will check back tomorrow. I need a clear head.



#17 nfactorial   Members   -  Reputation: 729

Like
0Likes
Like

Posted 10 February 2013 - 03:41 AM

Paused and unpaused are typically considered game ''states''. Many represent these states as enumerations, but I would generally represent a game state as an object, I have a whole theory behind my own design for how a game state should be represented but it's a bit ''out of the box'' compared to what is generally considered a game state (from my  experience). Throwing that out the window for now (it's still in the 'theory' phase that I'm testing in a home engine atm, maybe my theory is entirely bogus), you can typically represent a game state with two functions:

 

struct IGameState
{
    virtual void update( const UpdateArgs &updateArgs ) = 0;
    virtual void render( RenderArgs &renderArgs ) = 0;
};

If you consider your states as a stack, your normal game state would perform its rendering and update as normal. You could then 'push' a ''paused''' state onto the stack that forwarded the render state up the stack and simply consumed the update state. Which would give you a perfectly working paused state, you could extend this design further with a menu state etc. But the basics remain the same.

 

I'm not 100% sober atm sorry so please ignore any typo's or weird phrasing, but if there are any queries or questions on that let me know. My current design is much further evolved than this, but this seems like the most simplified to start with, without a huge posting smile.png

 

n!

I am coding my game in Java. I don't think C++ OOP will help me since I never touched much of C++ OOP

 

Whether you are using Java or any other language OOP is still OOP. I don't see anything in my post that cannot be applied to Java code.

 

n!



#18 warnexus   Prime Members   -  Reputation: 1390

Like
0Likes
Like

Posted 10 February 2013 - 03:38 PM

 

..snip...

what do you mean by input logic? on a side note, isn't a game loop consider to be an infinite loop if runs constantly to do handling tasks like drawing objects and testing collisions?
looking at you main game loop, you make absolutly zero calls to the function keyPress, or any indication that your call a function which query's input to potentially call the keyPress function.

so what does that mean? it means that in your initializing code, java spawned another thread that catch's input, and call's the keyPress function when you've done some type of input.

so, basically, you have 2 threads going:

thread 1: drawing/updating objects.
thread 2: getting input.

so, when you set the isRunning flag to false to pause, this is what your threads look like:

thread 1: finished(since you broke out of the loop, it completed the run() function, and the thread finished running since it reached the bottom of execution of run, and then reached the end of main).
thread 2: still looking for input.

so, when you go to unpause, this is what happens:

thread 1: still finished
thread 2: is now in a loop, doing what thread 1 used to do.

their are two problems with this.

first of all, you no longer get input.

second, openGL is built to receive commands from a single thread, and only one thread, this is the default thread that main is executed in. because it is now submitting commands from thread 2, the commands are essentially invalidated, and don't do anything. this is why once you unpause the game, you have to force it to close, the game is still technically updating, it just can't draw anything, because openGL refuses all commands from the second thread.
you also can't break out of it because you no longer can receive inputs, since you've stalled the input managed since you never go back to it.

hope this helps you understand what's going on better=-).

Now that I have a clear head, I understand it and got it to work. Thanks! Lesson learned: Never code with a tired mind.


Edited by warnexus, 10 February 2013 - 04:29 PM.


#19 Ectara   Crossbones+   -  Reputation: 2916

Like
0Likes
Like

Posted 11 February 2013 - 12:14 PM

This is merely just a matter of taste from what I know.


In C, void foo() is a function that takes an indeterminate amount of parameters. To explicitly state that a function has no parameters, you declare it as void foo(void). In C++, they both mean that the function has no parameters.

http://stackoverflow.com/questions/693788/c-void-arguments

I use void foo(void) for consistency, and also because I don't like how declaring the function without a void parameter list looks too much like how the function is called.

#20 MisterFuzzy   Banned   -  Reputation: 161

Like
0Likes
Like

Posted 11 February 2013 - 12:29 PM

Why are you ending your gameloop? In your loop, it would be far more efficient to have a boolean value DoUpdate that defaults to true. All motion and calculation would be done only if DoUpdate is true, else everything becomes static - just sits there. It still draws (You could use the boolean to control this, too), but nothing will move until DoUpdate was set back to true. Bam! Paused.


"Only idiots quote themselves" - MisterFuzzy

 





Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS