How to pause a game (Part 2)?

Started by
7 comments, last by eektor 17 years, 8 months ago
Thanks for all the help so far. I was able to get the pause working alright except for one bug. If a person press p sometimes it stops like its supposed to but other times it pauses and then resumes. I believe somehow the program reads the p key being pressed down more than once when you only pressed it down once. How can I avoid this? I use SDL and I was trying to put a SDL_Delay like this:

// If user presses 'p' pause or unpause the game
if (g_input->getInput(SDLK_p))
{
	if (g_pause == false)
		g_pause = true;
	else
		g_pause = false;

	SDL_Delay(75);
}
I've been trying to vary the SDL_Delay as well but with no success. Any ideas?
Advertisement
You probably want to put that pause logic in the SDL key down event handler rather than polling the key down state.
Ok, I think I understand what you're saying.

This is what I have for readInput which I do this before and then getInput:

void SDL_Input::readInput(){   if (SDL_PollEvent(&m_event))   {      if (m_event.type == SDL_QUIT)      {         m_windowClosed = true;      }      if (m_event.type == SDL_KEYDOWN)      {         m_keysHeld[m_event.key.keysym.sym] = true;      }      if (m_event.type == SDL_KEYUP)      {         m_keysHeld[m_event.key.keysym.sym] = false;      }   }}bool SDL_Input::getInput(int numKey){   return m_keysHeld[numKey];}


Are you saying I should put a delay in the readInput function?
No, I'm saying do something like:
      if (m_event.type == SDL_KEYDOWN)      {         if (m_event.key.keysym.sym == SDLK_p) {           g_pause = !g_pause;         }         m_keysHeld[m_event.key.keysym.sym] = true;      }
I was afraid you were going to say that. The problem is I use 'p' for other stuff. In the main menu screen I use it to play the game. Unless I put that code in the game state but that would look like an ugly hack (although at this point I think I wouldn't mind now, I'm ready to go on to a new project). Any ideas?

Another thing I tried using the g_pause = !g_pause; and I got a compiler error. Maybe I might have misspelled something, but I'll try it again.

Edit: It worked I guess I must have misspelled it when I tried.
If you depend on polling for your input handling than acting on the same keypress 0, 1 or more times is just something you're going to have to learn to live with. If you need to associate a single action with a single keypress then you'll need to associate that action with the keydown event. Given this fact, you might want to expose the key down event to all your states and let them handle them in addition to your polling mechanism.
This was my first time setting this up and I ran into problems like that before so I tried to fix it so it wasn't that noticeable. I figure for my next project I need to redo everything because I think I have a better idea of organizing things and I do realize I need to improve that Input class.

Just so I know whether I understand you. If I want a turbo like action (like how I want the user paddle to move) I need to poll like I'm doing. If I want one action to associate with one key press I need to assign it to the keydown state?
Well, this is how I handle such a situation: in my Input class's getKey() function (or input handling function, or whatever), which returns a boolean specifying whether a certain key is pressed:

bool getKey( SDLKey key ) { return m_Keys[(int)key] && !m_Lock[(int)key]; }

So a key is only 'pressed' if the corresponding index in the lock array is not. Both arrays are boolean arrays. When a key is pressed down:

if ( event.type == SDL_KEYDOWN ){  m_Keys[(int)event.key.keysym.sym] = true;}

And when a key is released:

if ( event.type == SDL_KEYUP ){  m_Keys[(int)event.key.keysym.sym] = false;  m_Lock[(int)event.key.keysym.sym] = false;}

The final step in this is, in your game loop (or wherever you put this):

if ( Input.getKey( SDLK_p ) == true ){  // Pause the game  Input.setLock( SDLK_p );}

So basically, keys can be "locked", so that once you've processed the key once, you won't have to process it again until it is pressed again (because releasing a key also releases its lock automatically). The lock must be activated from the function that tests for the keypress and acts upon it. There's probably a better way of doing it, but mine works, so whatever :). Hope it helps!
- fyhuang [ site ]
Thank you very much fyhuang. That works and it fits into nicely with what I have so far.

Thanks SiCrane for helping me out.

This topic is closed to new replies.

Advertisement