繁体   English   中英

在javascript中重启Simon Game

[英]Restart Simon Game in javascript

除了重新加载整个页面外,如何通过单击开始按钮使游戏从头开始重新启动?
发生此问题的原因是,当用户单击“ 开始 ”时,将调用playGame函数,但playGame函数的先前实例仍在运行。 我什至曾想杀死以前的函数实例,但在JS中,除非使用webworker.terminate(),否则无法实现。
这是代码:

 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> 

我没有深入研究您的代码,但似乎关键在于您正在使用setTimeout() ,并且重新启动时可能仍在运行超时。

您需要做的是存储setTimeout()的返回值,它实际上是一个ID,然后您可以将其传递给clearTimeout() ,它将停止该超时。

因此,在您的sleep()函数上,存储ID:

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

当您重新启动游戏时:

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

然后还要确保没有其他代码可以同时运行两个以上的超时(否则您将丢失其中一个ID)。

暂无
暂无

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

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