How to pause simple canvas game, made with js and html5?
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
}
Julanu
Trying to make the best out of everything and learn more than yesterday.
Updated on June 13, 2022Comments
-
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 almost 7 yearsSo 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 almost 7 yearsDon'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 almost 7 yearsI 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 almost 7 yearsWhy did you delete the
keyDown
function? You need it, it was correct. Also you mistypedgamePaused
leaving out the last letter. And of course, that line will do nothing if it is commented out ;-) -
Julanu almost 7 yearsI am currently struggling with the fac that after doing this, the canvas just stops loading... pastebin.com/j7xuLE9R
-
Michael Grinnell almost 7 yearsup 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 almost 7 yearsThank you! This made the rick, I am grateful for your help as this was important for me :D
-
Sachin HR about 5 yearsCan i achieve same pause with button click rather than toggle ?
-
Sachin HR about 5 yearsCan you please tell what is keydown here?
-
trincot about 5 years@SachinHR, if this question is directed to me: for the event: see
keydown
. For the functionkeyDown
: it was defined in the question.