简体   繁体   English

在javascript中重启Simon Game

[英]Restart Simon Game in javascript

How I can make the game restart from the beginning by clicking start button except reloading the whole page? 除了重新加载整个页面外,如何通过单击开始按钮使游戏从头开始重新启动?
The problem occurs because when user clicks Start playGame function is called, but the a previous instance of playGame function is still running. 发生此问题的原因是,当用户单击“ 开始 ”时,将调用playGame函数,但playGame函数的先前实例仍在运行。 I even thought about to kill a previous instance of function but in JS it can not be implemented except using webworker.terminate(). 我什至曾想杀死以前的函数实例,但在JS中,除非使用webworker.terminate(),否则无法实现。
Here's the code: 这是代码:

 document.addEventListener("DOMContentLoaded", function() { 'use strict'; var checkOn = document.querySelector("input[type=checkbox]"); var gameCount = document.getElementsByClassName("innerCount")[0]; var startButton = document.getElementById("innerStart"); var strictButton = document.getElementById("strictButton"); var strictInd = document.getElementById("strictIndicator"); var strictMode = false; var soundArray = document.getElementsByTagName("audio"); var buttons = document.querySelectorAll(".bigButton"); var buttonArray = [].slice.call(buttons, 0); checkOn.addEventListener("change", function() { if (checkOn.checked) { gameCount.innerHTML = "--"; } else { gameCount.innerHTML = ""; } }); strictButton.addEventListener("click", function() { if (checkOn.checked) { strictMode = !strictMode; strictMode ? strictInd.style.backgroundColor = "#FF0000" : strictInd.style.backgroundColor = "#850000"; } }); function getRandArray() { var array = []; for (var i = 0; i < 22; i++) { array[i] = Math.floor(Math.random() * 4); } return array; } startButton.addEventListener("click", function() { if (checkOn.checked) { var level = 0; var randIndexArr = getRandArray(); sleep(700).then(function() { playGame(randIndexArr, level); }); } }); function sleep(time) { return new Promise(resolve => { setTimeout(resolve, time) }) } function checkButton(randIndexArr, counter) { var indexButton = 0; var checker = function checker(e) { var clickedButtonId = e.target.dataset.sound; lightenButton(clickedButtonId); if (+(clickedButtonId) === randIndexArr[indexButton]) { if (indexButton === counter) { counter++; for (let i = 0; i < 4; i++) { buttonArray[i].removeEventListener("click", checker, false) } sleep(2000).then(function() { playGame(randIndexArr, counter); }); } indexButton++; } else { gameCount.innerHTML = "--"; if (strictMode) { indexButton = 0; counter = 0; } else { indexButton = 0; } for (let i = 0; i < 4; i++) { buttonArray[i].removeEventListener("click", checker, false) } sleep(2000).then(function() { playGame(randIndexArr, counter); }); } }; for (var i = 0; i < 4; i++) { buttonArray[i].addEventListener("click", checker, false) } } function playGame(randIndexArr, counter) { if (counter === 22) { return; } //Show the level of the Game gameCount.innerHTML = counter + 1; //Light and play user's input then check if input is correct randIndexArr.slice(0, counter + 1).reduce(function(promise, div, index) { return promise.then(function() { lightenButton(div); return new Promise(function(resolve, reject) { setTimeout(function() { resolve(); }, 1000); }) }) }, Promise.resolve()).then(function() { checkButton(randIndexArr, counter); }); } function lightenButton(id) { var lightColorsArr = ["liteGreen", "liteRed", "liteYell", "liteBlue"]; soundArray[id].play(); buttonArray[id].classList.add(lightColorsArr[id]); sleep(500).then(function() { buttonArray[id].classList.remove(lightColorsArr[id]) }); } }); 
 @font-face { font-family: myDirector; src: url('https://raw.githubusercontent.com/Y-Taras/FreeCodeCamp/master/Simon/fonts/myDirector-Bold.otf'); } body { background-color: #5f5f5f; } #outerCircle { display: flex; flex-wrap: wrap; margin: 0 auto; width: 560px; border: 2px dotted grey; position: relative; box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), 0 6px 20px 0 rgba(0, 0, 0, 0.19); } .bigButton { height: 250px; width: 250px; border: solid #464646; transition: all 1s; -webkit-transition: all 1s; -moz-transition: all 1s; -o-transition: background-color 0.5s ease; } #greenButton { background-color: rgb(9, 174, 37); border-radius: 100% 0 0 0; border-width: 20px 10px 10px 20px; } .liteGreen#greenButton { background-color: #86f999; } #redButton { background-color: rgb(174, 9, 15); border-radius: 0 100% 0 0; border-width: 20px 20px 10px 10px; } .liteRed#redButton { background-color: #f9868a; } #yellowButton { background-color: rgb(174, 174, 9); border-radius: 0 0 0 100%; border-width: 10px 10px 20px 20px; } .liteYell#yellowButton { background-color: #f9f986; } #blueButton { background-color: rgb(9, 37, 174); border-radius: 0 0 100% 0; border-width: 10px 20px 20px 10px; } .liteBlue#blueButton { background-color: #8699f9; } div#innerCircle { border: 15px solid #464646; border-radius: 50%; position: absolute; top: 25%; right: 25%; background-color: #c4c7ce; } div.additionalBorder { margin: 4px; border-radius: 50%; height: 242px; width: 242px; overflow: hidden; } p#tradeMark { margin: auto; height: 104px; text-align: center; font-size: 68px; font-family: myDirector; color: #c4c7ce; background-color: black; border-color: antiquewhite; line-height: 162px; } span#reg { font-size: 12px; } .partition { height: 6px; } .buttons { height: 128px; border-radius: 0 0 128px 128px; border: 2px solid black; } /* Start and Strict buttons*/ table { margin-left: 5px; } td { text-align: center; width: auto; padding: 2px 10px; vertical-align: bottom; } div.innerCount { width: 54px; height: 40px; background-color: #34000e; color: crimson; border-radius: 11px; font-size: 28px; line-height: 42px; text-align: center; font-family: 'Segment7Standard', italic; } button#innerStart { width: 27px; height: 27px; border: 4px solid #404241; border-radius: 50%; background: #a50005; box-shadow: 0 0 3px gray; cursor: pointer; } div.strict { display: flex; flex-direction: column; justify-content: center; align-items: center; } button#strictButton { width: 27px; height: 27px; border: 4px solid #404241; border-radius: 50%; background: yellow; box-shadow: 0 0 3px gray; cursor: pointer; } div#strictIndicator { width: 6px; height: 6px; margin-bottom: 2px; background-color: #850000; border-radius: 50%; border: 1px solid #5f5f5f; } #switcher { display: flex; justify-content: center; align-items: center; } .labels { font-family: 'Roboto', sans-serif; margin: 4px; } /* toggle switch */ .checkbox > input[type=checkbox] { visibility: hidden; } .checkbox { display: inline-block; position: relative; width: 60px; height: 30px; border: 2px solid #424242; } .checkbox > label { position: absolute; width: 30px; height: 26px; top: 2px; right: 2px; background-color: #a50005; cursor: pointer; } .checkbox > input[type=checkbox]:checked + label { right: 28px; } 
 <div id="outerCircle"> <div class="bigButton" id="greenButton" data-sound="0"> <audio src="https://s3.amazonaws.com/freecodecamp/simonSound1.mp3"></audio> </div> <div class="bigButton" id="redButton" data-sound="1"> <audio src="https://s3.amazonaws.com/freecodecamp/simonSound2.mp3"></audio> </div> <div class="bigButton" id="yellowButton" data-sound="2"> <audio src="https://s3.amazonaws.com/freecodecamp/simonSound3.mp3"></audio> </div> <div class="bigButton" id="blueButton" data-sound="3"> <audio src="https://s3.amazonaws.com/freecodecamp/simonSound4.mp3"></audio> </div> <div id="innerCircle"> <div class="additionalBorder"> <p id="tradeMark">simon<span id="reg">&reg;</span> </p> <div class="partition"></div> <div class="buttons"> <table> <tr class="firstRow"> <td> <div class="innerCount"></div> </td> <td> <button type="button" id="innerStart"></button> </td> <td> <div class="strict"> <div id="strictIndicator"></div> <button type="button" id="strictButton"></button> </div> </td> </tr> <tr class="labels"> <td> <div id="countLabel">COUNT</div> </td> <td> <div id="startLabel">START</div> </td> <td> <div id="strictLabel">STRICT</div> </td> </tr> </table> <div id="switcher"> <span class="labels">ON</span> <div class="checkbox"> <input id="checkMe" type="checkbox"> <label for="checkMe"></label> </div> <span class="labels">OFF</span> </div> </div> </div> </div> </div> 

I didn't dig super deep into your code, but it looks like the crux of it is you're using setTimeout() , and that timeout may still be running when you restart. 我没有深入研究您的代码,但似乎关键在于您正在使用setTimeout() ,并且重新启动时可能仍在运行超时。

What you need to do is store the return value of setTimeout() which is actually an id you can then pass to clearTimeout() , which will stop that timeout. 您需要做的是存储setTimeout()的返回值,它实际上是一个ID,然后您可以将其传递给clearTimeout() ,它将停止该超时。

So, on your sleep() function, store the id: 因此,在您的sleep()函数上,存储ID:

function sleep(time) {
   return new Promise(resolve => {
     this.timeoutId = setTimeout(resolve, time)
   });
}

And when you go to restart your game: 当您重新启动游戏时:

// ...
if (this.timeoutId) {
    clearTimeout(this.timeoutId);
    this.timeoutId = null;
}
//...

And then also just make sure you don't have any other code that will get more than two timeouts running at the same time (or you'll lose one of the ids). 然后还要确保没有其他代码可以同时运行两个以上的超时(否则您将丢失其中一个ID)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM