Pause functionality in game works only once

Started by
19 comments, last by Khatharr 11 years, 2 months ago

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.

Advertisement


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.

..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=-).

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

..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.

..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=-)

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

..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.

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!

..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.

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.

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

This topic is closed to new replies.

Advertisement