Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

pop function isn't taking tail off snake array?

Tags:

javascript

I am making a snake game in JS. Right now I'm able to draw the snake to the canvas and accept a direction to move from the user. Given the direction I'm able to unshift() a new head to the snake, but for some reason I can't use the pop method to remove the tail. This just results in my snake growing bigger and bigger. Any ideas to why this is?

const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');

//set canvas dimension equal to css dimension
canvas.width = 768;
canvas.height = 512;

//now put those dimensions into variables
const cvsW = canvas.width;
const cvsH = canvas.height;

//create snake unit
const unit = 16;

//create snake array
let snake = [{x: cvsW/2, y: cvsH/2}];

//read user's direction
document.addEventListener('keydown', changeDirection);

let direction;

function changeDirection(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';

    console.log(direction);
}

function draw() {
    for(let i = 0; i < snake.length; i++) {
        ctx.fillStyle = 'limegreen';
        ctx.fillRect(snake[i].x, snake[i].y, unit, unit);
    }

    //grab head position
    let headX = snake[0].x;
    let headY = snake[0].y;

    snake.pop();

    if(direction == 'left') headX -= unit;
    else if(direction == 'up') headY -= unit;
    else if(direction == 'right') headX += unit;
    else if(direction == 'down') headY += unit;

    //create new head
    let newHead = {x: headX, y: headY}

    //add head to snake
    snake.unshift(newHead);
}

setInterval(draw, 100);
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Snake Game</title>
    <style>
        body {
            background-color: #333;
        }

        canvas {
            background-color: #4d4d4d;
            margin: auto;
            display: block;
            position: absolute;
            left: 0;
            right: 0;
            top: 0;
            bottom: 0;
            width: 750px;
            height: 500px;      
        }
    </style>
</head>
<body>
    <canvas id="canvas"></canvas>
    <script src="script.js"></script>
</body>
</html>
like image 308
Alfred Avatar asked Mar 13 '26 23:03

Alfred


1 Answers

You need to clear the current canvas every iteration, else pixels painted onto the canvas earlier will remain. Add

  ctx.clearRect(0, 0, canvas.width, canvas.height);

right before you start iterating over the snake array to paint each square:

const canvas = document.querySelector('#canvas');
const ctx = canvas.getContext('2d');

//set canvas dimension equal to css dimension
canvas.width = 768;
canvas.height = 512;

//now put those dimensions into variables
const cvsW = canvas.width;
const cvsH = canvas.height;

//create snake unit
const unit = 16;

//create snake array
let snake = [{
  x: cvsW / 2,
  y: cvsH / 2
}];

//read user's direction
document.addEventListener('keydown', changeDirection);

let direction;

function changeDirection(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';

  console.log(direction);
}

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.fillStyle = 'limegreen';
  for (let i = 0; i < snake.length; i++) {
    ctx.fillRect(snake[i].x, snake[i].y, unit, unit);
  }

  //grab head position
  let headX = snake[0].x;
  let headY = snake[0].y;

  snake.pop();

  if (direction == 'left') headX -= unit;
  else if (direction == 'up') headY -= unit;
  else if (direction == 'right') headX += unit;
  else if (direction == 'down') headY += unit;

  //create new head
  let newHead = {
    x: headX,
    y: headY
  }

  //add head to snake
  snake.unshift(newHead);
}

setInterval(draw, 100);
body {
  background-color: #333;
}

canvas {
  background-color: #4d4d4d;
  margin: auto;
  display: block;
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  width: 750px;
  height: 500px;
}
<canvas id="canvas"></canvas>
like image 75
CertainPerformance Avatar answered Mar 15 '26 12:03

CertainPerformance



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!