Home > Net >  Why the code doesn't work when the snake eats the apple?
Why the code doesn't work when the snake eats the apple?

Time:01-25

Good afternoon everyone. I was making my own snake game. And when I implemented the snake eating function, I ran into a problem (The function that should start while the snake is eating the apple doesn't work.)

I tried to equate the positions of the apple to the size of the block. And the function should return me an alert when the snake has eaten the apple.

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

//Snake
var snake = [];
var px = canvas.width / 2;
var py = canvas.height / 2;
var dir = "right";
var maxCell = 10;
var can = canvas.getBoundingClientRect();

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

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() {
  //! Spawn apple
  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);

    if (snake.length < maxCell) {
      snake.push({
        x: px,
        y: py
      });
    }

    if (px >= canvas.width) {
      px = 0;
    } else if (px < 0) {
      px = canvas.width;
    }
    if (py >= canvas.height) {
      py = 0;
    } else if (py < 0) {
      py = canvas.height;
    }
    snake.forEach(function(elem, index) {
      ctx.fillStyle = `red`;
      ctx.fillRect(elem.x, elem.y, box, box);
    });

    //BROKEN CODE
    if (head.x == ax && head.y == ay) {
      alert("HI");
    }
    snake.pop();
  }

  Snake();
  Apple();
}

function loop() {
  setInterval(() => {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    Elems();
  }, 2000 / 30);
}

loop();
canvas {
  border: 1px solid #000;
  background-color: #000;
}
<canvas id="game" width="450" height="450"></canvas>

CodePudding user response:

You are checking for equality:

if (head.x == ax && head.y == ay) {
  alert("HI");
}

You must check for overlap. Apple is not a point, it is an area. You need to check whether the two areas overlap or not. (The area of apple and the area of the head of the snake)

The question is that you have two rectangles, and Do they overlap?

The second solution: you can set the position of apple in a way that your current code can work. Currently you are spawning apples on canvas randomly, if you can fix this, your current code might work.

Basically, you will ensure that the corner of the apple, and the corner of the head will be equal when the snake eats the apple. if you can fix the apple spawning code, it might work.

CodePudding user response:

You need to calculate your grid if you box is 10x10 . In your case you have 450 x 450px canvas you divide that by 10 and the grid will be 45x45

Use grid.x and grid.y (those are your max values in you grid) to place the snake and generate an apple coords.

That way you need to check only top left coords and not if rectangles overlap

var canvas = document.getElementById("game");
var ctx = canvas.getContext("2d");
var box = 10;
//calculate your grid
var grid = {
  x: Math.floor(canvas.width / box),
  y: Math.floor(canvas.height / box)
};

var snake = [];
//use grid to center the snake
var px = Math.floor(grid.x / 2) * box;
var py = Math.floor(grid.y / 2) * box;
var dir = "right";
var maxCell = 10;
var can = canvas.getBoundingClientRect();

//Apple
//use your grid to spawn an apple
var ax = Math.floor(Math.random() * grid.x) * box;
var ay = Math.floor(Math.random() * grid.y) * box;

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() {
  //! Spawn apple
  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);

    if (snake.length < maxCell) {
      snake.push({
        x: px,
        y: py
      });
    }

    if (px >= canvas.width) {
      px = 0;
    } else if (px < 0) {
      px = canvas.width;
    }
    if (py >= canvas.height) {
      py = 0;
    } else if (py < 0) {
      py = canvas.height;
    }
    snake.forEach(function(elem, index) {
      ctx.fillStyle = `red`;
      ctx.fillRect(elem.x, elem.y, box, box);
    });
    //BROKEN CODE
    if (head.x == ax && head.y == ay) {
      alert("HI");
    }
    snake.pop();
  }

  Snake();
  Apple();
}

function loop() {
  setInterval(() => {
    ctx.clearRect(0, 0, canvas.width, canvas.height);
    Elems();
  }, 2000 / 30);
}

loop();
canvas {
  border: 1px solid #000;
  background-color: #000;
}
<canvas id="game" width="450" height="450"></canvas>

  • Related