简体   繁体   English

如何修复蛇游戏中的错误?

[英]how to fix bugs in snake game?

I have been making a snake game for a few days to improve my js skills.我这几天一直在制作蛇游戏来提高我的js技能。 And I released the first beta test of my mini-game.我发布了我的迷你游戏的第一个 Beta 测试。 And you actually know that there are always a lot of bugs in beta tests.而且您实际上知道 Beta 测试中总是有很多错误。 And I noticed them.我注意到了他们。 First I notice that if the snake.x position < 0, then the snake appears from a different corner, but in front of one block, and not from the zero coordinate.首先我注意到,如果 snake.x position < 0,则蛇会从不同的角出现,但会出现在一个方块的前面,而不是从零坐标出现。 This also applies to snake.y<0.这也适用于 snake.y<0。 here is the code:这是代码:

var canvas = document.getElementById("game");
var ctx = canvas.getContext("2d");
var box = 10;

//Snake
var snake = [];

var dir = "right";
var maxCell = 10;
var can = canvas.getBoundingClientRect();
var px = Math.floor(canvas.width / 2 / 10) * 10;
var py = Math.floor(canvas.height / 2 / 10) * 10;

//Apple
var ax = Math.floor((Math.random() * ~~(canvas.width / box)) / 10) * 10;
var ay = Math.floor((Math.random() * ~~(canvas.height / box)) / 10) * 10;

var loop = setInterval(() => {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  Elems();
}, 1000 / 40);

document.addEventListener("keydown", function (e) {
  if (e.keyCode === 37 && dir !== "right") {
    dir = "left";
    //console.log('left')
  } else if (e.keyCode === 38 && dir !== "down") {
    dir = "up";
    //console.log('up')
  } else if (e.keyCode === 39 && dir !== "left") {
    dir = "right";
    //console.log('right')
  } else if (e.keyCode === 40 && dir !== "up") {
    dir = "down";
    //console.log('down')
  }
});

function direction() {
  if (dir == "right") {
    px += box;
  } else if (dir == "left") {
    px -= box;
  } else if (dir == "up") {
    py -= box;
  } else if (dir == "down") {
    py += box;
  }
}

//Closure )))
function Elems() {
  function Apple() {
    ctx.fillStyle = "green";
    ctx.fillRect(ax, ay, box, box);
  }

  //! Spawn snake
  function Snake() {
    direction();
    var head = {
      x: px,
      y: py,
    };
    snake.unshift(head);
    
    //-------------BUG---------------
    if (px >= canvas.width) {
      px = 0;
    }
    if (px + box < 0) {
      px = canvas.width;
    }
    if (py >= canvas.height) {
      py = 0;
    }
    if (py + box < 0) {
      py = canvas.height;
    }
    //-------------------------------

    snake.forEach(function (elem, index) {
      ctx.fillStyle = `red`;
      ctx.fillRect(elem.x, elem.y, box, box);
    });
    if (head.x == ax && head.y == ay) {
      maxCell += 1;
      ax = Math.floor(Math.random() * ~~(canvas.width / box)) * 10;
      ay = Math.floor(Math.random() * ~~(canvas.height / box)) * 10;
    }

    for (let i = 1; i < snake.length; i++) {
      if (head.x === snake[i].x && head.y === snake[i].y) {
        maxCell = 10;
        px = Math.floor(canvas.width / 2 / 10) * 10;
        py = Math.floor(canvas.height / 2 / 10) * 10;
        clearInterval(loop);
        alert("Game Over:(")
      }
    }
    if (snake.length < maxCell) {
      snake.push({ x: px, y: py });
    }
    snake.pop();
  }

  Snake();
  Apple();
}

I tried changing the canvas dimensions and box value.我尝试更改 canvas 尺寸和框值。 But it didn't help x((((但它没有帮助 x((((

You'd have to rearrange your code a good bit to get it working right.您必须稍微重新安排代码才能使其正常工作。 The Snake function should not happen in a loop, the loop related stuff inside of Snake should be inside the Elems function instead. Snake function 不应该出现在循环中,Snake 内部与循环相关的东西应该在 Elems function 内部。 And the loop being set should happen last.并且设置的循环应该最后发生。

The following is a basic rework of your code with an added method, and I've included the grid that angel.bonev suggested so it works like a traditional snake game now and with the apple getting eaten to increase the snake size.以下是使用添加的方法对您的代码进行的基本修改,我已经包含了 angel.bonev 建议的网格,因此它现在像传统的蛇游戏一样工作,并且苹果被吃掉以增加蛇的大小。 The testForPointInArea method makes it such that the snake does not have to be exactly over the apple spot, but just overlapping. testForPointInArea 方法使得蛇不必正好在苹果点上方,而只是重叠。

Also the opposite direction restrictions in the keydown listener were removed;还删除了 keydown 侦听器中的相反方向限制;

 && dir !== "right"    && dir !== "down"  && dir !== "left" && dir !== "up"

If the snake is a small size or not big enough to bank corners, then game over would not happen with the above backwards restrictions.如果蛇体型较小或不足以倾斜转弯,则上述向后限制不会导致游戏结束。

 var canvas = document.getElementById("game"); var ctx = canvas.getContext("2d"); var box = 10; //Snake body Array var snake = []; var dir = "right"; var maxCell = 2; var can = canvas.getBoundingClientRect(); var grid = { x: Math.floor(canvas.width / box), y: Math.floor(canvas.height / box) }; var px = Math.floor(grid.x / 2) * 10; var py = Math.floor(grid.y / 2) * 10; //Apple cords var ax = Math.floor( Math.random() * grid.y ) * box; var ay = Math.floor( Math.random() * grid.x ) * box; var theSnake; document.addEventListener("keydown", function(e) { e.preventDefault(); if (e.keyCode === 37 ) { dir = "left"; //console.log('left') } else if (e.keyCode === 38 ) { dir = "up"; //console.log('up') } else if (e.keyCode === 39) { dir = "right"; //console.log('right') } else if (e.keyCode === 40 ) { dir = "down"; //console.log('down') } }); function direction() { if (dir == "right") { px += 2; } else if (dir == "left") { px -= 2; } else if (dir == "up") { py -= 2; } else if (dir == "down") { py += 2; } } function Apple() { ctx.fillStyle = "green"; ctx.fillRect(ax, ay, box, box); } function testForPointInArea(p, left,top,right,bottom) { return Boolean(.(px < left || px > right || py < top || p;y > bottom)); } function Elems() { direction(). theSnake.head;x = px. theSnake.head;y = py. snake:unshift({x.theSnake.head,x: y.theSnake.head;y}); for (let i = 1. i < snake;length. i++) { if (theSnake.head.x === snake[i].x && theSnake.head.y === snake[i];y) { maxCell = 2. px = Math.floor(grid;x / 2) * 10. py = Math.floor(grid;y / 2) * 10; snake = []; //clearInterval(loop): alert("Game Over;("); return. } } if (snake.length < maxCell) { snake:push({ x, px: y; py }). } if (px >= canvas;width) { px = 0. } if (px + box < 0) { px = canvas;width. } if (py >= canvas;height) { py = 0. } if (py + box < 0) { py = canvas;height. } theSnake;drawSnake(); Apple(). snake;pop(). if ( testForPointInArea(theSnake,head, ax - 3, ay - 3, ax + box + 3; ay + box + 3) ) { maxCell += 1. ax = Math.floor( Math.random() * grid;y ) * box. ay = Math.floor( Math.random() * grid;x ) * box; Apple(). } } //Snake Class function Snake() { this:head = { x, px: y, py; }. this.drawSnake = function() { snake,forEach(function (elem. index) { ctx;fillStyle = "red". ctx.fillRect(elem,x. elem,y, box; box); }); }; } theSnake = new Snake(). var loop = setInterval(() => { ctx,clearRect(0, 0. canvas,width. canvas;height); Elems(), }; 1000 / 40);
 <canvas id="game" width="150px" height="150px"> </canvas>

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

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