How to pause simple canvas game, made with js and html5?

12,269

Solution 1

Create a Boolean variable called paused and set it to true if the player presses p, Then put an if statement around the loop that runs your game. and say if (!paused){run loop}

You can create a toggle pause function for when p is pressed.

function togglePause()
{
    if (!paused)
    {
        paused = true;
    } else if (paused)
    {
       paused= false;
    }

}

You also need to create an event listener for when p is pressed Like this

window.addEventListener('keydown', function (e) {
var key = e.keyCode;
if (key === 80)// p key
{
    togglePause();
}
});

up the top where you have Game objects and constants put in paused = false, and in your loop function do this

 draw(); 
if(!paused)
{ 
update(); 
}

Solution 2

Game state managment

Games will usually have various game states. Pause, End game, Press key to start, etc... As the optimal way to run a game is via a single main loop the easiest way to manage game states is to have variable hold the current state function and just assign that variable the appropriate function to handle the current state.

BTW you should use requestAnimationFrame instead of setTimeout or setinterval and keyCode should not be used as it is depreciated use keyEvent.code (see example for details)

requestAnimationFrame(mainLoop);  // start when code below done.
// set up keyboard IO
const keys = {
    KeyP : false,
    Enter : false,
    listener(e){
       if(keys[e.code] !== undefined){
           keys[e.code] = e.type === "keydown";
           e.preventDefault();
        }
    }
}
addEventListener("keydown",keys.listener);
addEventListener("keyup",keys.listener);

// the current game state
var currentState = startGame;

function startGame (){
    // code to do a single frame of start game
   // display press enter to start
   if(keys.Enter){
      keys.Enter = false;
      currentState = game;  // start the game
   }
}
function pause(){
    // code to do a single frame of pause
   // display pause
    if(keys.KeyP){
       keys.KeyP = false; // turn off key
       currentState = game;   // resume game
    }

}
function game(){
    // code to do a single frame of game
    if(keys.KeyP){
       keys.KeyP = false; // turn off key
       currentState = pause;  // pause game
    }
}
function mainLoop(time){
    currentState(); // call the current game state
    requestAnimationFrame(mainLoop);
}

Reference: https://developer.mozilla.org/es/docs/Web/API/KeyboardEvent

Solution 3

Your game loop is not based on setTimeout, but on requestAnimationFrame. So setting and clearing a timer will not change anything.

Secondly, you did not bind your keyDown function to any event, so it will never get invoked.

Solution:

Have a look at your loop function: it calls itself asynchronously, which provides the animation. You need to stop that loop to effectively introduce a pause:

function loop() {
    if (gamePaused) return; // <--- stop looping
    update();
    draw();
    window.requestAnimationFrame(loop, canvas);
}

Define the new variable upon page load, and bind your function to the keyDown event:

var gamePaused = false;
document.addEventListener('keydown', keyDown);

And your pauseGame function would look like this:

function pauseGame() {
    gamePaused = !gamePaused; // toggle the gamePaused value (false <-> true)
    if (!gamePaused) loop(); // restart loop
}
Share:
12,269
Julanu
Author by

Julanu

Trying to make the best out of everything and learn more than yesterday.

Updated on June 13, 2022

Comments

  • Julanu
    Julanu almost 2 years

    I created a simple snake game after following some simple tutorials on YouTube.

    The problem is that the game does not have a pause function (e.g. when pressing P the game should pause/resume) and when the snake hits the border of the canvas the game restarts itself (but that is another problem).

    Here is the complete code I have of the game: https://pastebin.com/URaDxSvF

    The pause-related functions I've created:

    function gamePaused{ /**i need help on this**/ }
    
    function keyDown(e) {
      if (e.keyCode == 80) pauseGame();
    }
    
    function pauseGame() {
      if (!gamePaused) {
        game = clearTimeout(game);
        gamePaused = true;
      } else if (gamePaused) {
        game = setTimeout(loop, 1000 / 30);
        gamePaused = false;
      }
    }
    
  • Julanu
    Julanu almost 7 years
    So I've modified the keydown function to make the variable true if it's pressed-------> paused = new Boolean(false); function keyDown(e) { if (e.keyCode == 80) paused = true; pauseGame(); }------then I've put around my loop if(!paused){ update(); draw();} i will also need and else statement to pause it, how shoud i actually do that? Thank you in advance and sorry for disturbing
  • Michael Grinnell
    Michael Grinnell almost 7 years
    Don't make a new Boolean, when p is pressed. you should initially set pause to false when you star the game and the you can toggle with p
  • Julanu
    Julanu almost 7 years
    I feel like this might do the trick but i am struggling with binding the function as after defining the variables just stop loading and the page becomes blank. pastebin.com/zEAJc8xw , if it's not too much could you check to see if I did it right, thank you and sorry for disturbing again
  • trincot
    trincot almost 7 years
    Why did you delete the keyDown function? You need it, it was correct. Also you mistyped gamePaused leaving out the last letter. And of course, that line will do nothing if it is commented out ;-)
  • Julanu
    Julanu almost 7 years
    I am currently struggling with the fac that after doing this, the canvas just stops loading... pastebin.com/j7xuLE9R
  • Michael Grinnell
    Michael Grinnell almost 7 years
    up the top where you have Game objects and constants put in paused = false, and in your loop function do this draw(); if(!paused) { update(); }
  • Julanu
    Julanu almost 7 years
    Thank you! This made the rick, I am grateful for your help as this was important for me :D
  • Sachin HR
    Sachin HR about 5 years
    Can i achieve same pause with button click rather than toggle ?
  • Sachin HR
    Sachin HR about 5 years
    Can you please tell what is keydown here?
  • trincot
    trincot about 5 years
    @SachinHR, if this question is directed to me: for the event: see keydown. For the function keyDown: it was defined in the question.