简体   繁体   English

Javascript蛇游戏错误

[英]Javascript snake game bugs

There are two issues, I can't control the snake, and now it just resets constantly without giving the snake a chance to move. 有两个问题,我无法控制蛇,现在它不断地重置而没有给蛇移动的机会。 I figured that if i kept coding the problem would go away but sadly its not a perfect world. 我认为,如果我继续编码,问题将会消失,但可悲的是,这并不是一个完美的世界。

I tried different key codes for controlling the snake but it didn't work. 我尝试了不同的按键代码来控制蛇,但没有用。

window.onload = function() {

var cvs = document.getElementById("canvas");
var ctx = cvs.getContext("2d");

var cvsW = cvs.width;
var cvsH = cvs.height;

var snekW = 10;
var snekH = 10;

//score
var score = 0;

//default direction
var direction = "right";

//read users directions
document.addEventListener("keydown",getDirection);

//To my knowledge this function should control the snake with the 
  keyboard
function getDirection(e)
{   
    if(e.keyCode == 37 && direction != "right"){
        direction = "left";
    }else if(e.keyCode == 38 && direction != "down"){
         direction = "up";
     }else if(e.keyCode == 39 && direction != "left"){
         direction = "right";   
      }else if(e.keycode == 40 && direction != "up"){
         direction = "down";   
       }
}

function drawSnek(x,y)
{
    ctx.fillStyle = "Lime";
    ctx.fillRect(x*snekW,y*snekH,snekW,snekH);

    ctx.fillStyle = "#000";
    ctx.strokeRect(x*snekW,y*snekH,snekW,snekH);    
}

var len = 4; //default length of the snake
var snek = []; //the snake is an array

for(var i = len-1; i>=0; i--)
{
    snek.push({x:i,y:0});    
}


    //exceptions for direction of snake

    if(direction == "left") snekx--;
    else if( direction == "up") sneky--;
    else if( direction == "right") snekx++;
    else if( direction == "down") sneky++; 


       //Functions for creating snake food have been removed.

    var newHead = { x: snekx, y: sneky};
    snek.unshift(newHead);
    drawScore(score);
}

setInterval(draw, 10); //I do not fully understand this function

} }

There were several issues with your code: 您的代码有几个问题:

You needed a draw function that could be called in an interval. 您需要可以在间隔中调用的绘制函数。 In this draw function you could draw the individual parts of the snake. 在此绘制功能中,您可以绘制蛇的各个部分。

You were unable to control the snake correctly as you had a typo in the down part of the callback function. 您无法正确控制蛇,因为在回调函数的下部出现错字。

You have to either introduce x / y variables for the head of the snake or use the first element of the array to retrieve it. 您必须为蛇的头引入x / y变量,或者使用数组的第一个元素来检索它。

Unshifting the new position using snek.unshift will cause the snake to grow indefinitely. 使用snek.unshift取消移动新位置将导致蛇无限地增长。 Removing array elements using 使用删除数组元素

snek.splice(len,snek.length - len);

solves this problem. 解决了这个问题。

If you only draw new elements to the screen the old parts you drew will still exist in new frames. 如果仅在屏幕上绘制新元素,则绘制的旧零件仍将存在于新框架中。 A good idea would be to clear the canvas using 一个好主意是使用

ctx.clearRect(0, 0, cvsW, cvsH);
window.onload = function () {

    var cvs = document.getElementById("canvas");
    var ctx = cvs.getContext("2d");

    var cvsW = cvs.width;
    var cvsH = cvs.height;

    var snekW = 10;
    var snekH = 10;
    //score
    var score = 0;

    //default direction
    var direction = "right";

    //read users directions
    document.addEventListener("keydown", getDirection);

    //To my knowledge this function should control the snake with the keyboard
    function getDirection(e) {
        if (e.keyCode == 37 && direction != "right") {
            direction = "left";
        } else if (e.keyCode == 38 && direction != "down") {
            direction = "up";
        } else if (e.keyCode == 39 && direction != "left") {
            direction = "right";
        } else if (e.keyCode == 40 && direction != "up") {
            direction = "down";
        }
    }

    function drawSnek(x, y) {
        ctx.fillStyle = "Lime";
        ctx.fillRect(x * snekW, y * snekH, snekW, snekH);

        ctx.fillStyle = "#000";
        ctx.strokeRect(x * snekW, y * snekH, snekW, snekH);
    }
    let snekx = 0;
    let sneky = 0;

    var len = 4; //default length of the snake
    var snek = []; //the snake is an array

    for (var i = len - 1; i >= 0; i--) {
        snek.push({ x: i, y: 0 });
    }

    function draw() {
         ctx.clearRect(0, 0, cvsW, cvsH);
            //exceptions for direction of snake

        if (direction == "left") snekx--;
        else if (direction == "up") sneky--;
        else if (direction == "right") snekx++;
        else if (direction == "down") sneky++;


        //Functions for creating snake food have been removed.

        var newHead = { x: snekx, y: sneky };
        snek.unshift(newHead);
        for(let i = 0; i < snek.length; i++) {
            drawSnek(snek[i].x, snek[i].y)
        }
         snek.splice(len,snek.length - len);
        //drawScore(score);
    }
    setInterval(draw, 50); //I do not fully understand this function
}

CodePen with fixed code: https://codepen.io/lukasmoeller/pen/PvVzqq?editors=1111 (boundaries are not checked - the snake will leave the canvas) 固定代码的CodePen: https ://codepen.io/lukasmoeller/pen/PvVzqq?editors = 1111(边界未选中-蛇会离开画布)

Explanation of setInterval(fn, interval) setInterval(fn, interval)

setInterval calls the function specified using fn every interval ms until it is cleared. setInterval interval ms interval使用fn调用一次指定的函数,直到将其清除为止。 The interval can be cleared by using clearInterval , passing it the return value of setInterval . 可以使用clearInterval清除间隔,并向其传递setInterval的返回值。 If you want to delay function execution at the beginning you could add setTimeout , add a callback that sets the interval: 如果要在开始时延迟函数执行,可以添加setTimeout ,添加一个设置时间间隔的回调:

     setTimeout(function(){
           setInterval(draw, 50);
     }, 1000)

This would only start drawing the game every 50 ms after 1000ms have passed. 经过1000毫秒后,每隔50毫秒才开始绘制游戏。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM