我是 JS 新手,正在做一个项目,但我一直在使用失败时重置游戏的功能时遇到问题。当您在记忆游戏中按错按钮时,它会重置,但随后游戏就会中断。
//varibles
const buttonColors = ['red', 'blue', 'green', 'yellow'];
let gamePattern = [];
let userClickedPattern = [];
let userChosenColor;
let level = 0;
let started = false;
function playSound(name) {
let sound = new Audio('./sounds/' + name + '.mp3');
sound.play();
}
function gameOver() {
playSound('wrong');
setTimeout(function() {
$('body').removeClass('game-over');
}, 500);
$('#level-title').text('Game Over, Press Any Key to Restart');
$('body').addClass('game-over');
started = false;
level = 0;
gamePattern = [];
}
//get a sequence
function nextSequence() {
userClickedPattern = [];
level++;
$('#level-title').text('Level ' + level);
let randomNumber = Math.floor(Math.random() * 4);
let randomColor = buttonColors[randomNumber];
gamePattern.push(randomColor);
for (let i = 0; i < gamePattern.length; i++) {
setTimeout(function() {
$('#' + gamePattern[i]).animate({
opacity: 0.25
}, 100);
setTimeout(function() {
$('#' + gamePattern[i]).animate({
opacity: 1
}, 100);
}, 25);
playSound(gamePattern[i]);
}, (500 * (i + 1)));
}
}
//get the user sequence stuff
function animatePress(currentColor) {
setTimeout(function() {
$('#' + currentColor).removeClass('pressed');
}, 100);
$('#' + currentColor).addClass('pressed');
}
function userSequence() {
$('.btn').click(function() {
userChosenColor = $(this).attr('id');
userClickedPattern.push(userChosenColor);
animatePress(userChosenColor);
playSound(userChosenColor);
checkAnswer(userClickedPattern.length);
});
}
//check if answer is right or wrong
function checkAnswer(currentLevel) {
// let rightCounter = 0;
// if (gamePattern.length == currentLevel) {
// for (let i = 0; i < gamePattern.length; i++) {
// if (gamePattern[i] == userClickedPattern[i]) {
// rightCounter++;
// } else {gameOver();}
// }
// if (rightCounter == gamePattern.length) {
// setTimeout(function () {
// userClickedPattern = [];
// nextSequence();
// }, 500);
// } else {gameOver();}
// }
if (gamePattern[currentLevel - 1] == userClickedPattern[currentLevel - 1]) {
if (gamePattern.length == currentLevel) {
setTimeout(function() {
nextSequence();
}, 500);
}
} else {
gameOver();
}
}
//start game
function startGame() {
nextSequence();
userSequence();
}
//start game
$('body').keydown(function() {
if (started == false) {
startGame();
started = true;
}
});
body {
text-align: center;
background-color: #011F3F;
}
#level-title {
font-family: 'Press Start 2P', cursive;
font-size: 3rem;
margin: 5%;
color: #FEF2BF;
}
.container {
display: block;
width: 50%;
margin: auto;
}
.btn {
margin: 25px;
display: inline-block;
height: 200px;
width: 200px;
border: 10px solid black;
border-radius: 20%;
}
.game-over {
background-color: red;
opacity: 0.8;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.blue {
background-color: blue;
}
.yellow {
background-color: yellow;
}
.pressed {
box-shadow: 0 0 20px white;
background-color: grey;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Simon</title>
<link rel="stylesheet" href="styles.css">
<link href="https://fonts.googleapis.com/css?family=Press+Start+2P" rel="stylesheet">
</head>
<body>
<h1 id="level-title">Press Any Key to Start</h1>
<div class="container">
<div lass="row">
<div type="button" id="green" class="btn green">
</div>
<div type="button" id="red" class="btn red">
</div>
</div>
<div class="row">
<div type="button" id="yellow" class="btn yellow">
</div>
<div type="button" id="blue" class="btn blue">
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="./game.js"></script>
</body>
</html>
我问过chatGPT,但它总是给我一些高级的东西,我不知道它做了什么,我想理解我的代码,所以如果我遇到类似的问题,我可以解决它。当您按下错误的按钮(div 元素)时,游戏就会结束,但会出现故障。任何时候你点击某个东西,即使是正确的,也总是错误的。我希望它能够正常运行。
我看了一下,这是我的观察结果。
首先,我检查了在
gameOver();
中调用checkAnswer();
时你的胜利条件的值。
console.log("gamePattern ", gamePattern[currentLevel - 1])
console.log("userClickedPattern ", userClickedPattern[currentLevel - 1])
gameOver();
在游戏的第一次迭代中,一切正常,但从第二次迭代开始,即第一次游戏结束后,确实存在问题。从那时起,你的
gamePattern
就变成了undefined
。但是,如果我登录您的 nextSequence();
函数,则会定义 gamePattern
。
问题似乎源于其他地方。正如 @JaromandaX 和 @Barmar 所解释的,您在每个游戏开始时调用
userSequence();
,这会导致单击一个按钮会产生多个条目。
如何避免这种情况?您目前有两种解决方案:
确保
userSequence();
仅被调用一次
再次调用 userSequence();
时删除之前的条目
对于第一个解决方案,您可以简单地执行以下操作:
//start game
function startGame() {
nextSequence();
}
//start game
$('body').keydown(function() {
if (started == false) {
startGame();
started = true;
}
});
userSequence();
off()
这样,$('.btn').click
就变成了$('.btn').off('click').click
。
这给了我们:
const buttonColors = ['red', 'blue', 'green', 'yellow'];
let gamePattern = [];
let userClickedPattern = [];
let userChosenColor;
let level = 0;
let started = false;
function playSound(name) {
let sound = new Audio('./sounds/' + name + '.mp3');
sound.play();
}
function gameOver() {
playSound('wrong');
setTimeout(function() {
$('body').removeClass('game-over');
}, 500);
$('#level-title').text('Game Over, Press Any Key to Restart');
$('body').addClass('game-over');
started = false;
level = 0;
gamePattern = [];
}
//get a sequence
function nextSequence() {
userClickedPattern = [];
level++;
$('#level-title').text('Level ' + level);
let randomNumber = Math.floor(Math.random() * 4);
let randomColor = buttonColors[randomNumber];
gamePattern.push(randomColor);
for (let i = 0; i < gamePattern.length; i++) {
setTimeout(function() {
$('#' + gamePattern[i]).animate({
opacity: 0.25
}, 100);
setTimeout(function() {
$('#' + gamePattern[i]).animate({
opacity: 1
}, 100);
}, 25);
playSound(gamePattern[i]);
}, (500 * (i + 1)));
}
}
//get the user sequence stuff
function animatePress(currentColor) {
setTimeout(function() {
$('#' + currentColor).removeClass('pressed');
}, 100);
$('#' + currentColor).addClass('pressed');
}
function userSequence() {
$('.btn').click(function() {
userChosenColor = $(this).attr('id');
userClickedPattern.push(userChosenColor);
animatePress(userChosenColor);
playSound(userChosenColor);
checkAnswer(userClickedPattern.length);
});
}
//check if answer is right or wrong
function checkAnswer(currentLevel) {
// let rightCounter = 0;
// if (gamePattern.length == currentLevel) {
// for (let i = 0; i < gamePattern.length; i++) {
// if (gamePattern[i] == userClickedPattern[i]) {
// rightCounter++;
// } else {gameOver();}
// }
// if (rightCounter == gamePattern.length) {
// setTimeout(function () {
// userClickedPattern = [];
// nextSequence();
// }, 500);
// } else {gameOver();}
// }
if (gamePattern[currentLevel - 1] == userClickedPattern[currentLevel - 1]) {
if (gamePattern.length == currentLevel) {
setTimeout(function() {
nextSequence();
}, 500);
}
} else {
gameOver();
}
}
//start game
function startGame() {
nextSequence();
}
//start game
$('body').keydown(function() {
if (started == false) {
startGame();
started = true;
}
});
userSequence(); // <-- Moved userSequence() here to fix the issue
body {
text-align: center;
background-color: #011F3F;
}
#level-title {
font-family: 'Press Start 2P', cursive;
font-size: 3rem;
margin: 5%;
color: #FEF2BF;
}
.container {
display: block;
width: 50%;
margin: auto;
}
.btn {
margin: 25px;
display: inline-block;
height: 200px;
width: 200px;
border: 10px solid black;
border-radius: 20%;
}
.game-over {
background-color: red;
opacity: 0.8;
}
.red {
background-color: red;
}
.green {
background-color: green;
}
.blue {
background-color: blue;
}
.yellow {
background-color: yellow;
}
.pressed {
box-shadow: 0 0 20px white;
background-color: grey;
}
<!DOCTYPE html>
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title>Simon</title>
<link rel="stylesheet" href="styles.css">
<link href="https://fonts.googleapis.com/css?family=Press+Start+2P" rel="stylesheet">
</head>
<body>
<h1 id="level-title">Press Any Key to Start</h1>
<div class="container">
<div lass="row">
<div type="button" id="green" class="btn green">
</div>
<div type="button" id="red" class="btn red">
</div>
</div>
<div class="row">
<div type="button" id="yellow" class="btn yellow">
</div>
<div type="button" id="blue" class="btn blue">
</div>
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script src="./game.js"></script>
</body>
</html>