2016-11-09 2 views
0

전체 페이지를 다시로드하는 것 외에는 시작 버튼을 클릭하여 게임을 처음부터 다시 시작할 수 있습니까?
사용자가 을 클릭하면 시작 playGame 함수가 호출되었지만 playGame 함수의 이전 인스턴스가 여전히 실행 중이기 때문에 문제가 발생합니다. 나는 심지어 이전의 함수 인스턴스를 죽이려고했지만 JS에서는 webworker.terminate()를 사용하는 것 외에는 구현할 수 없다.
여기에 코드입니다 : 나는 당신의 코드에 슈퍼 깊이 파고하지 않았다Simon 게임을 자바 스크립트로 다시 시작하십시오.

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>

+0

게임의 켜기/끄기 상태 (켜기/끄기 버튼의 클릭 이벤트를 통해 설정 됨)를 추적하고 다음 버튼 시퀀스가 ​​생성되는 코드 섹션에서 모듈 부울 변수를 설정하는 방법은 무엇입니까? 변수? –

+0

@ScottMarcus 고마워요. 당신의 충고에 따라 해 봤습니다만, 그 전에는 개인 var의 전역을 만들기 위해 코드를 변경해야합니다. –

답변

0

하지만, 그것의 요점은 당신이 setTimeout()을 사용하고있는 것 같습니다, 그 제한은 여전히 ​​수도 다시 시작할 때 실행 중이어야합니다.

당신이해야 할 일은 실제로 clearTimeout()에 전달할 수있는 ID 인 setTimeout()의 반환 값을 저장하는 것입니다. 그러면 해당 시간 초과가 중지됩니다.

그래서, 당신의 sleep() 기능에, 아이디 저장 :

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

을 그리고 당신은 당신의 게임을 다시 시작 갈 때 : 다음

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

그리고이 또한 단지 있는지 확인 당신은 어떤이 없습니다 동시에 두 개 이상의 타임 아웃을 실행하는 다른 코드 (또는 ID 중 하나를 잃어 버릴 수 있음).

관련 문제