我是Javascript领域的新手,我正在开发一个蛇游戏,我一直面临一个不寻常的问题:在我通过按下画布板上的“重新启动”按钮重新启动游戏之后,蛇开始自己移动,记住游戏结束前的最后一个键输入。
请记住,当您第一次开始游戏时,蛇通过按任意键开始移动,而在我修复事件侦听器触发器(当按得太快时,蛇从相反的方向撞到自己)之后,游戏重置后的问题发生了。
我将附上下面的代码,以展示我迄今所做的工作,非常感谢您的时间!
代码
<!-- the snake game section -->
<div class="snake-game" data-hover="Press any key to start">
<div class="score">
Score: <p id="score-number">0</p>
</div>
<canvas id="game-board">
</canvas>
</div>JS代码
const gameBoard = document.getElementById("game-board");
const context = gameBoard.getContext("2d");
let rows = 20;
let cols = 20;
let gridBoard = 20; // per row 30 grids
let gameOver = false;
let snakeSize = 1; // initializing snake's body size
let x = new Array(900);
let y = new Array(900);
gameBoard.height = rows * gridBoard;
gameBoard.width = cols * gridBoard;
for (let i = 0; i < snakeSize; i++){
x[i] = 40 - i*20
y[i] = 40 //the head of the snake
}
// to come up with a random position for the apple
let eatenApple = true;
let appleX;
let appleY;
let score = 0;
let scoreNumber = document.getElementById("score-number");
const path = new Path2D(); // for the reset button
function mainGame(){
//when the snake eats the apple and grows
eatApple();
//movement validation and check the collision
movementValidation();
// keep record of head&body in canvas for movement
move(); // or change the snake position
//to display the snake's head, body, and the apple
display();
setTimeout(mainGame, 150);
}
function display(){
context.clearRect(0,0, gameBoard.width, gameBoard.height);
if(gameOver){
isGameOver();
} else {
//apple
if(eatenApple){
appleRandomPlace();
eatenApple = false;
}
//the apple's head
context.beginPath()
context.fillStyle = "red";
context.fillRect(appleX, appleY, gridBoard / 1, gridBoard / 1);
context.closePath();
for (let i = 0; i < snakeSize; i++){
//the snake's head
if(i === 0){
const snake_head = new Path2D();
context.fillStyle = "#86626E";
snake_head.rect(x[0], y[0], gridBoard / 1, gridBoard / 1);
context.fill(snake_head);
} else {
//the snake's body
const snake_body = new Path2D();
context.fillStyle = "#201335";
context.strokeStyle = "#fff";
context.lineWidth = 3;
snake_body.rect(x[i], y[i], gridBoard / 1, gridBoard / 1);
context.fill(snake_body);
context.stroke(snake_body);
}
}
}
}
function isGameOver(){
//game over text
context.fillStyle = "black";
context.textBaseline = "middle";
context.textAlign = "center";
context.font = "35px Adonay";
context.fillText("game over", gameBoard.width / 2, gameBoard.height / 2);
// the reset button and text
path.rect(150,240,100,40); //x, y, width, height
path.closePath();
context.fillStyle = "black";
context.textBaseline = "middle";
context.textAlign = "center";
context.font = "20px Adonay";
context.strokeStyle = "#0B1D51";
context.lineWidth = 1;
context.fillText("restart", 200, 261, 111, 40);
context.stroke(path);
}
function eatApple(){
if(x[0] === appleX && y[0] === appleY){
snakeSize++
eatenApple = true;
score += 1;
scoreNumber.innerText = score;
}
}
function appleRandomPlace(){
appleX = Math.floor(Math.random() * (cols - 5)) * gridBoard + 20;
appleY = Math.floor(Math.random() * (rows - 5)) * gridBoard + 20;
}
let direction;
let nextDirection;
document.addEventListener("keydown", function(event){
if(event.keyCode === 38 && direction !== "down") {
nextDirection = "up";
}
else if(event.keyCode === 40 && direction !== "up"){
nextDirection = "down";
}
else if(event.keyCode === 37 && direction !== "right"){
nextDirection = "left";
}
else if(event.keyCode === 39 && direction !== "left"){
nextDirection = "right";
}
});
function movementValidation(){
// snake's collision with the walls
if(y[0] >= gameBoard.height / 1.1) {
gameOver = true;
} else if(y[0] < 1) {
gameOver = true;
} else if(x[0] >= gameBoard.width / 1.1) {
gameOver = true;
} else if(x[0] < 1) {
gameOver = true;
}
//x[0] and y[0] represent the head of the snake
// snake eats its own body
for (let i = 1; i < snakeSize; i+=1){
if(x[0] === x[i] && y[0] === y[i]){
gameOver = true;
}
}
}
function move(){
// for snake's body
for (let i = snakeSize; i > 0; i--){
x[i] = x[(i-1)];
y[i] = y[(i-1)];
}
// for snake's head
if(nextDirection === "left"){
x[0] -= gridBoard;
}
else if(nextDirection === "right"){
x[0] += gridBoard;
}
else if(nextDirection === "up"){
y[0] -= gridBoard;
}
else if(nextDirection === "down"){
y[0] += gridBoard;
}
direction = nextDirection;
}
function buttonReset(gameBoard, event){
const rect = gameBoard.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
return {x:x, y:y};
}
document.addEventListener("click", function (e){
const x_y = buttonReset(gameBoard, e);
if(context.isPointInPath(path, x_y.x, x_y.y)){
gameOver = false;
snakeSize = 1; // initializing snake's body size
x = new Array(900);
y = new Array(900);
gameBoard.height = rows * gridBoard;
gameBoard.width = cols * gridBoard;
for (let i = 0; i < snakeSize; i++){
x[i] = 40 - i*10
y[i] = 40 //the head of the snake
}
eatenApple = false;
appleX;
appleY;
score = 0;
scoreNumber.innerText = score;
direction;
nextDirection;
display();
move();
eatApple();
movementValidation();
}
}, false);
mainGame();发布于 2022-10-05 09:46:09
在“新游戏”函数开始时重置与运动相关的变量,在其中设置gameOver = false等等。
direction = undefined;
nextDirection = undefined;https://stackoverflow.com/questions/73958570
复制相似问题