smooth snake movement in javascript

Viewed 376

I was making a snake game. I have a basic game but I wanted to move the snake more smoothly and specially I wanted to turn the direction of the snake more smoothly.

The problem until now is that I have been removing the tail of the snake and adding it to the head for the movement part. Moving the snake smoothly is rather easy by reducing the interval for calling the draw function and incrementing the x and y values by small amounts but what I am having problem is with turning the snake smoothly,it is exactly where I am lost/confused as to how to do it like done here (only the turning of snake part and not the changing of head when snake gets blocked)

can anyone help out please? here is my code:

let cvs = "";
let ctx = "";
let size = [];
var direction = 'b';
var speed = 200;

//moving lines on arrow click
window.addEventListener("keydown", moveSomething, false);

function moveSomething(e) {
  switch (e.keyCode) {
    case 37:
      //left
      if (direction != 'r') {
        direction = 'l';
      }
      break;

    case 38:
      //up
      if (direction != 'b') {
        direction = 't';
      }
      break;

    case 39:
      //right
      if (direction != 'l') {
        direction = 'r';
      }
      break;

    case 40:
      //bottom
      if (direction != 't') {
        direction = 'b';
      }
      break;
  }
}

let food = {
  x: Math.floor(Math.random() * 220),
  y: Math.floor(Math.random() * 400),
  s: 20,

  draw: function() {
    //this if block rounds off the x and y values
    if ((this.x % 20) != 0 || (this.y % 20) != 0) {
      if ((this.x % 20) != 0) {
        let e = this.x % 20;
        e = 20 - e;
        this.x = this.x + e;
      }

      if ((this.y % 20) != 0) {
        let e = this.y % 20;
        e = 20 - e;
        this.y = this.y + e;
      }
    };

    ctx.fillStyle = "red";
    ctx.fillRect(this.x, this.y, this.s, this.s);
  },

  newfood: function() {
    this.x = Math.floor(Math.random() * 220);
    this.y = Math.floor(Math.random() * 400);
    this.draw();
  }
}

const snake = {
  s: 20,

  draw: function(x, y) {
    ctx.fillStyle = "green";
    ctx.fillRect(this.s * x, this.s * y, this.s, this.s);

    ctx.strokeStyle = "black";
    ctx.strokeRect(this.s * x, this.s * y, this.s, this.s);
  },

  snakeInit: function() {
    for (let i = 8; i >= 4; i--) {
      size.push({
        x: i,
        y: 6
      })
    }
  }, 

  callDraw: function() {
    for (let i = 0; i < size.length; i++) {
      this.draw(size[i].x, size[i].y);
    }
  },

  move: function() {
    var snakeX = size[0].x;
    var snakeY = size[0].y;

    if (direction == 'r') {
      snakeX++;
    } else if (direction == 'l') {
      snakeX--;
    } else if (direction == 't') {
      snakeY--;
    } else if (direction == 'b') {
      snakeY++;
    }
    //console.log("Inside move1", speed);

    if (snakeX == -1 || snakeX == cvs.width / this.s || snakeY == -1 || snakeY == Math.floor(cvs.height / this.s) || this.checkSelfCollision(snakeX, snakeY, size)) {
      ctx.clearRect(0, 0, cvs.width, cvs.height);
      gameloop = clearInterval(gameloop);
      return;
    } else {
      ctx.clearRect(0, 0, cvs.width, cvs.height);
      food.draw();
    }

    if (snakeX * 20 == food.x && snakeY * 20 == food.y) {
      var tail = {
        x: snakeX,
        y: snakeY
      };

      food.eaten();
      speed += 200;
      food.newfood();
    } else {
      var tail = size.pop();
      tail.x = snakeX;
      tail.y = snakeY;
    }

    size.unshift(tail);

    for (let i = 0; i < size.length; i++) {
      this.draw(size[i].x, size[i].y);
    }
  },

  checkSelfCollision: function(x, y, arr) {
    for (let i = 0; i < arr.length; i++) {
      if (arr[i].x == x && arr[i].y == y) {
        return true;
      }
    }
    return false;
  }
}

function loop() {
  const cvsL = document.getElementById("snakes");
  const ctxL = cvsL.getContext('2d');

  cvs = cvsL;
  ctx = ctxL;
  snake.snakeInit();

  snake.callDraw();
  food.draw();
  gameloop = setInterval(function() {
    snake.move();
  }, speed);
}
<body onload="loop();">

<canvas id="snakes" width=240px height=420px style="border: 1px solid black;display: block;"></canvas>

</body>

0 Answers
Related