首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >蛇记得游戏重新开始后的最后一个键输入- Javascript

蛇记得游戏重新开始后的最后一个键输入- Javascript
EN

Stack Overflow用户
提问于 2022-10-05 09:43:36
回答 1查看 30关注 0票数 -1

我是Javascript领域的新手,我正在开发一个蛇游戏,我一直面临一个不寻常的问题:在我通过按下画布板上的“重新启动”按钮重新启动游戏之后,蛇开始自己移动,记住游戏结束前的最后一个键输入。

请记住,当您第一次开始游戏时,蛇通过按任意键开始移动,而在我修复事件侦听器触发器(当按得太快时,蛇从相反的方向撞到自己)之后,游戏重置后的问题发生了。

我将附上下面的代码,以展示我迄今所做的工作,非常感谢您的时间!

代码

代码语言: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代码

代码语言:javascript
复制
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();
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-10-05 09:46:09

在“新游戏”函数开始时重置与运动相关的变量,在其中设置gameOver = false等等。

代码语言:javascript
复制
direction = undefined;
nextDirection = undefined;
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73958570

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档