Javascript 如何暂停使用js和html5制作的简单画布游戏?

Javascript 如何暂停使用js和html5制作的简单画布游戏?,javascript,html,canvas,Javascript,Html,Canvas,根据YouTube上的一些简单教程,我创建了一个简单的蛇游戏 问题是游戏没有暂停功能(例如,当按下p键时,游戏应该暂停/恢复),当蛇碰到画布的边界时,游戏会自动重新启动(但这是另一个问题) 以下是我拥有的游戏完整代码: 我创建的与暂停相关的函数: function gamePaused{ /**i need help on this**/ } function keyDown(e) { if (e.keyCode == 80) pauseGame(); } function pauseG

根据YouTube上的一些简单教程,我创建了一个简单的蛇游戏

问题是游戏没有暂停功能(例如,当按下p键时,游戏应该暂停/恢复),当蛇碰到画布的边界时,游戏会自动重新启动(但这是另一个问题)

以下是我拥有的游戏完整代码:

我创建的与暂停相关的函数:

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;
  }
}

创建一个名为paused的布尔变量,如果玩家按下p,则将其设置为true,然后在运行游戏的循环周围放置if语句。如果(!暂停){run loop}

您可以在按下p时创建切换暂停功能

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

}
您还需要为按下p时创建事件侦听器 像这样

window.addEventListener('keydown', function (e) {
var key = e.keyCode;
if (key === 80)// p key
{
    togglePause();
}
});
将游戏对象和常量放在paused=false中,并在循环函数中执行此操作

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

您的游戏循环不是基于
setTimeout
,而是基于
requestAnimationFrame
。因此,设置和清除计时器不会改变任何事情

其次,您没有将
keyDown
函数绑定到任何事件,因此它永远不会被调用

解决方案: 看看你的
循环
函数:它异步调用自己,提供了动画。您需要停止该循环以有效地引入暂停:

function loop() {
    if (gamePaused) return; // <--- stop looping
    update();
    draw();
    window.requestAnimationFrame(loop, canvas);
}
您的
pauseGame
函数如下所示:

function pauseGame() {
    gamePaused = !gamePaused; // toggle the gamePaused value (false <-> true)
    if (!gamePaused) loop(); // restart loop
}
函数pauseGame(){
gamePaused=!gamePaused;//切换gamePaused值(false-true)
如果(!gamePaused)循环();//重新启动循环
}
游戏状态管理 游戏通常会有不同的游戏状态。暂停、结束游戏、按键开始等。。。由于运行游戏的最佳方法是通过单个主循环,因此管理游戏状态的最简单方法是让变量保留当前状态函数,并只为该变量分配适当的函数来处理当前状态

BTW您应该使用
requestAnimationFrame
而不是
setTimeout
setinterval
并且
keyCode
不应该被使用,因为它被折旧了使用
keyEvent.code
(详细信息请参见示例)

参考:

因此,我修改了keydown函数,使变量在按下时为true------->paused=new Boolean(false);函数keyDown(e){if(e.keyCode==80)paused=true;pauseGame();}----然后我在我的循环中放置了if(!paused){update();draw();}我还需要和else语句来暂停它,我实际上应该怎么做呢?请提前向您表示感谢,并对打扰您表示抱歉。按p键时,请勿创建新的布尔值。你应该首先设置暂停为假,当你明星的游戏,你可以切换与pI am目前正在与fac,在这样做后,画布只是停止加载。。。将游戏对象和常量放在paused=false的顶部,并在循环函数中执行此draw();如果(!暂停){update();}谢谢!这让rick很高兴,我很感谢你的帮助,因为这对我很重要:我觉得这可能会起作用,但我正在努力绑定函数,因为定义变量后就停止加载,页面变为空白,如果不是太多的话,你能检查一下我是否做对了,谢谢你,很抱歉再次打扰你为什么要删除
按键功能?你需要它,它是正确的。您还错误地键入了
gamePaused
,漏掉了最后一个字母。当然,如果该行被注释掉,它将不会起任何作用;-)你能告诉我这里的按键是什么吗?@SachinHR,如果这个问题是针对我的:对于事件:请参阅。对于功能
keyDown
:它在问题中定义。
function pauseGame() {
    gamePaused = !gamePaused; // toggle the gamePaused value (false <-> true)
    if (!gamePaused) loop(); // restart loop
}
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);
}