我正在从事“Simon Game”项目。
我希望它以适当的顺序点亮按钮。但是到目前为止,代码可以正常工作到第二级。
如果我是对的,应将checkButton(randIndexArr, counter)
包含在promise中,以便如果使用counter === index
,则应调用checkButton
,也许还有更多我错过的错误。
这是视频的链接:代码应该如何工作以使其更加清晰Zipline: Build a Simon Game
这是我的代码:
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 () {
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);
}
document.getElementsByClassName("randArray")[0].innerHTML = array;
return array;
}
startButton.addEventListener("click", function () {
var level = 0;
var randIndexArr = getRandArray();
playGame(randIndexArr, level);
});
function sleep(time) {
return new Promise(resolve => {
setTimeout(resolve, time)
})
}
function checkButton(randIndexArr, counter) {
console.log('checkButton');
var checker = function checker(e) {
var clickedButtonId = e.target.dataset.sound;
lightenButton(clickedButtonId);
sleep(1000);
for (let index = 0; index <= counter; index++) {
if (+(clickedButtonId) === randIndexArr[index]) {
if (index === counter) {
console.log('checking passed - next level :', (counter + 1));
counter++;
for (var i = 0; i < 4; i++) {
buttonArray[i].removeEventListener("click", checker, false)
}
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 random buttons according to the level
//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 () {
console.log("slice reduce");
lightenButton(div);
return new Promise(function (resolve, reject) {
setTimeout(function () {
resolve("reduce Resolve");
}, 1000);
})
})
}, Promise.resolve()).then(function (value) {
console.log(value);
checkButton(randIndexArr, counter);
});
}
function lightenButton(id) {
var lightColorsArr = ["liteGreen", "liteRed", "liteYell", "liteBlue"];
var promise = new Promise((resolve, reject) => {
soundArray[id].play();
buttonArray[id].classList.add(lightColorsArr[id]);
setTimeout(function () {
resolve("lighten");
}, 500);
});
promise.then(function (value) {
console.log(value);
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');
}
#outerCircle {
display: flex;
flex-wrap: wrap;
margin: 0 auto;
width: 560px;
border: 2px dotted grey;
position: relative;
}
.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" >0
<audio src="https://s3.amazonaws.com/freecodecamp/simonSound1.mp3"></audio>
</div>
<div class="bigButton" id="redButton" data-sound = "1">1
<audio src="https://s3.amazonaws.com/freecodecamp/simonSound2.mp3" ></audio>
</div>
<div class="bigButton" id="yellowButton" data-sound = "2">2
<audio src="https://s3.amazonaws.com/freecodecamp/simonSound3.mp3"></audio>
</div>
<div class="bigButton" id="blueButton" data-sound = "3">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">®</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>
<div class="randArray"></div>
最佳答案
问题之一(以及其他许多问题)是checkButton
函数本身,您可以在其中检查数组中的按钮,但不检查按钮按下或“尝试”的一系列操作。
例如,如果randIndexArr
包含值[2,2,1,1...]
,则您的代码可以将数组的前两个值都与值clickeBbuttonId
的2
进行比较,以此类推。
我只重写了一个函数checkButton
只是为了向您展示一种可能的方法:
var currentAttempt = 1
function checkButton(randIndexArr, counter) {
var checker = function checker(e) {
var clickedButtonId = e.target.dataset.sound;
lightenButton(clickedButtonId);
if (randIndexArr[currentAttempt -1] === +(clickedButtonId)){
if (currentAttempt - 1 === counter) {
counter++
currentAttempt = 1
for (var i = 0; i < 4; i++) {
buttonArray[i].removeEventListener("click", checker, false)
}
playGame(randIndexArr, counter);
}
currentAttempt++
} else {
currentAttempt = 1
}
};
for (var i = 0; i < 4; i++) {
buttonArray[i].addEventListener("click", checker, false)
}
}
但老实说,应该重新设计整个代码。