Sign in to follow this  

SDL Pausing game help?

This topic is 1112 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I know this might sound stupid but what is the best way to go about pausing my game by pressing esc. I need it to pause everything then resume once i repress that key. Many thanks!

 

set paused = true when esc is pressed, don't update your game state if paused is true.

Share this post


Link to post
Share on other sites

 

I know this might sound stupid but what is the best way to go about pausing my game by pressing esc. I need it to pause everything then resume once i repress that key. Many thanks!

 

set paused = true when esc is pressed, don't update your game state if paused is true.

 

 

is paused already in the sdl library?

Share this post


Link to post
Share on other sites


is paused already in the sdl library?

No.

 

His suggestion is to create a bool variable called "paused".

Toggle the variable when Escape is pressed.

Check the state of the variable in your update loop to determine what updates.

Share this post


Link to post
Share on other sites

is paused already in the sdl library?

Most people think of pausing in the simple sense, it freezes the game, but in reality it never does. That may or may not be obvious, if you think about a game like the old Zelda games, pausing would take you to some kind of inventory screen. Obviously the game world was still paused in that case but many other elements of the screen had to still function.

Basically pausing doesn't simply halt the game, it halts the ingame logic. How you do that depends completely on the way you've structured your code, if you have your game calling some kind of tick function you probably want it to continue calling it, but maybe a layer under there where it is calling tick on the game objects like the AI, movement, etc, you would either designate some variable and basically stop updating them altogether if it was true, or you could just pass them a delta time of zero to get the same basic behavior.

A library is unlikely to have any kind of pause function unless it has some access to the game loop and actually "knows" where the logic is going to happen so it can stop calling updates on it.

Share this post


Link to post
Share on other sites

 

is paused already in the sdl library?

Most people think of pausing in the simple sense, it freezes the game, but in reality it never does. That may or may not be obvious, if you think about a game like the old Zelda games, pausing would take you to some kind of inventory screen. Obviously the game world was still paused in that case but many other elements of the screen had to still function.

Basically pausing doesn't simply halt the game, it halts the ingame logic. How you do that depends completely on the way you've structured your code, if you have your game calling some kind of tick function you probably want it to continue calling it, but maybe a layer under there where it is calling tick on the game objects like the AI, movement, etc, you would either designate some variable and basically stop updating them altogether if it was true, or you could just pass them a delta time of zero to get the same basic behavior.

A library is unlikely to have any kind of pause function unless it has some access to the game loop and actually "knows" where the logic is going to happen so it can stop calling updates on it.

 

ok so if i had my paused bool and resume bool, how would i actually go about pausing the game? I tried SDL_Delay() but it doesnt work as expected. It kinda just slows it down

Share this post


Link to post
Share on other sites

ok so if i had my paused bool and resume bool, how would i actually go about pausing the game? I tried SDL_Delay() but it doesnt work as expected. It kinda just slows it down


It's slowing down because SDL_Delay actually freezes your program for a specified amount of time. You only want to freeze your logic time.
You probably have a float elapsedTime or something like that. When paused is true you need to set this elapsedTime variable to zero. That way your application is able to do work (processing input, handle incoming events from the OS, ...) while your game logic does not progress.

Share this post


Link to post
Share on other sites

You know the part where you update() your game objects? When the game is paused, simply don't do that. You may wish to continue drawing them or running some animations, depending on the game.

i see many thanks

Share this post


Link to post
Share on other sites

Great.

 

Note we don't generally close posts. If a post is descending into a hostile environment, we close it, and if someone resurrects an old post we also close them.

 

Even at this point, someone could come along with another way to handle this.

 

As an example, one way I've handled this in the past for small to medium games is to treat the game as a series of "states". So you might have a MainMenuState, a PlayingState, a PausedState, among others.

 

So we might have something like:

class GameState
{
public:
    virtual ~GameState();
 
    virtual void update() = 0;
 
    virtual void display(Renderer &) = 0;
 
    virtual void handleEvent(const SDL_Event &event) = 0;
 
    virtual std::unique_ptr<GameState> nextState() = 0;
 
    // ...
};

 

So you could imagine for a basic game like Pong, you might have a PlayingGameState that looks something like this:

class PlayingPongState : GameState
{
public:
    virtual void update()
    {
        ball.update();
 
        leftPaddle.update();
        rightPaddle.update();
 
        handleCollision(ball, leftPaddle);
        handleCollision(ball, rightPaddle);
       
        checkForPoint(ball);
 
        // ...
    }
 
    virtual void display(Renderer &renderer)
    {
        renderer.drawCircle(ball.position, ball.radius);
        renderer.drawRect(leftPaddle.position, leftPaddle.dimensions);
        renderer.drawRect(rightPaddle.position, rightPaddle.dimensions);
    }
 
    virtual void handleEvent(const SDL_Event &event)
    {
        if (event.type == SDL_KEYDOWN)
        {
            if (event.key.keysym.sym == SDLK_UP)
            {
                rightPaddle.startMovingUp();
            }
            else if (event.key.keysym.sym == SDLK_DOWN)
            {
                rightPaddle.startMovingDOWN();
            }
            else if (event.key.keysym.sym == SDLK_W)
            {
                leftPaddle.startMovingUp();
            }
            else if (event.key.keysym.sym == SDLK_S)
            {
                leftPaddle.startMovingUp();
            }
        }
    }
};

 

Then in your top level loop, you have something like this:

bool running = true;
std::unique_ptr<GameState> currentState(new PlayingPongState());
while (running)
{
     SDL_Event event;
     while (SDL_PollEvent(&event))
     {
          if (event.key == SDL_QUIT)
          {
              running = false;
          }
          else
          {
              currentState->handleEvent(event);
          }
     }
 
     currentState->update();
     currentState->display(renderer);
     // ...
 
     // Forgive me if this won't compile, I've not used C++11 much.
     std::unique_ptr<GameState> nextState = currentState->nextState();
     if (nextState)
     {
         std::swap(currentState, nextState);
     }
}

 

So for pausing, you might handle this with a fake state that continues to display the gamestate, but avoids updating it:

class PausedState : GameState
{
public:
    PausedPongState(std::unique_ptr<GameState> underlyingState)
    :
           returnToGame(false),
           underlyingState(underlyingState)
    {
    }
 
    virtual void update()
    {
        // Nothing to do here.
    }
 
    virtual void display(Renderer &renderer)
    {
        underlyingState->display(renderer);
        renderer.displayText("Paused", renderer.screenCentre());
    }
 
    virtual void handleEvent(const SDL_Event &event)
    {
        if (event.type == SDL_KEYDOWN)
        {
            if (event.key.keysym.sym == SDLK_RETURN)
            {
                returnToGame = true;
            }
        }
    }
 
    virtual std::unique_ptr<GameState> nextState()
    {
          // Ditto on C++11
          std::unique_ptr<GameState> result;
          if (returnToGame)
          {
              std::swap(result, underlyingState);
          }
          return result;
    }
 
private:
    bool returnToGame;
    std::unique_ptr<GameState> underlyingState;
};

And add some code to pause to the event loop:

while (SDL_PollEvent(&event))
{
    if (event.type == SDL_QUIT)
    {
        running = false;
    }
    else if (event.type == SDL_KEYDOWN && event.key.keysym.sym == SDLK_p)
    {
        // Not sure this is totally necessary...
        std::unique_ptr<GameState> temp;
        std::swap(currentState, temp);
        std::unique_ptr<GameState> pausedState(new PausedState(std::move(temp)));
        std::swap(pausedState, currentState);
    }
    else
    {
        currentState->handleEvent(event);
    }
}

 

I'm not saying this is the best solution by any means, but it is an alternative to scattering a bunch of if() checks around.

Share this post


Link to post
Share on other sites

This topic is 1112 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this