Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Snake moves horizontally

Tags:

I am trying to create a simple snake game.

(function() {    var canvas = document.getElementById('canvas'),        ctx = canvas.getContext('2d'),        x = 0,        y = 0,        speed = 2;         x_move = speed,        y_move = 0,                                  food_position_x = Math.floor(Math.random() * canvas.width / 10) * 10,        food_position_y = Math.floor(Math.random() * canvas.height / 10) * 10,        size_x = 10;          function eat() {        console.log('food_x:' + food_position_x + ' x:' + x + ' / food_y:' + food_position_y + ' y:' + y);      if (Math.floor(y / 10) * 10 == food_position_y && Math.floor(x / 10) *10  == food_position_x) {        	size_x += 2;        //throw new Error("MATCH!"); // This is not an error. Just trying to stop the script      }    }        // Drawing    function draw() {      eat();      requestAnimationFrame(function() {              draw();            });          // Draw the snake      ctx.beginPath();      ctx.rect(Math.floor(x/10)*10, Math.floor(y/10)*10, size_x, 10);      ctx.clearRect(0, 0, canvas.width, canvas.height);      ctx.fillStyle = '#ffffff';       ctx.fill();      ctx.closePath();        // Draw the food      ctx.beginPath();       ctx.rect(Math.floor(food_position_x/10)*10, Math.floor(food_position_y/10)*10, 10, 10);      ctx.fillStyle = "blue";      ctx.fill();      ctx.closePath();        // Increase the value of x and y in order to animate      x = x + x_move;      y = y + y_move;           }     draw();      // Key Pressing    document.addEventListener('keydown', function(event) {      switch(event.keyCode) {        case 40: // Moving down          if (x_move != 0 && y_move != -1) {            x_move = 0;            y_move = speed;          }        break;        case 39: // Moving right          if (x_move != -1 && y_move != 0) {            x_move = speed;            y_move = 0;           }        break;        case 38: // Moving top          if (x_move != 0 && y_move != 1) {            x_move = 0;            y_move = -speed;           }        break;        case 37: // Moving left          if (x_move != 1 && y_move != 0) {            x_move = -speed;            y_move = 0;           }        break;      }    });  })();
canvas { background-color: #000022 }
<canvas id="canvas" width="400" height="400"></canvas>

jsfiddle

The problem

Every time when I catch the food, the snake becomes longer but when you press the down or up key, it moves horizontally.

Maybe a solution

This is what I believe the solution could be: The snake should be an array! Every time when the key is pressed, define the position of HEAD of snake and move the snake step by step, because it is an array. So the body follows the head. But in this case, I have no idea how to make an array from it.

Maybe there are other solutions. Any helps would be appreciated!

like image 527
Reza Saadati Avatar asked Apr 01 '18 23:04

Reza Saadati


People also ask

Why do some snakes move sideways?

Most snakes slither on the ground in a straight line, often curving as they slide, but their direction is straight. However, as its name suggests, the sidewinder snake moves sideways, something physics professor Jennifer Rieser says is because of its sandy home.

Do snakes move sideways?

Sidewinding movement If you're a snake and on sand or mud then this is the movement you use! By contracting their muscles and pushing off only 2 contact points, they launch their body throwing the head forward and the rest of the body follows moving sideways. Hence the name sidewinding movement.

What are the movements of a snake?

For several decades workers have identified four major modes of snake locomotion: rectilinear, lateral undulation, sidewinding, and concertina locomotion (Mosauer 1932; Gray 1946; Lissmann 1950; Gans 1962; Jayne 1986).

What are the 4 types of snake locomotion?

For several decades different types of snake locomotion have been categorized as one of four major modes: rectilinear, lateral undulation, sidewinding, and concertina. Recent empirical work shows that the scheme of four modes of snake locomotion is overly conservative.


2 Answers

You need to maintain an array of the points currently occupied by the snake body, and add new point (unshift) to the array as the snake approaches and remove point from the back of the array (pop). The following code is a starter, you need to make it your own :).

(function () {      const COLORS={ SNAKE:'#ff7bf5', FOOD:'blue' };      var canvas = document.getElementById('canvas'),          ctx = canvas.getContext('2d');      var snake=[], score=0;      var x, y, food_position_x, food_position_y, x_move, y_move;      var frameCount=0, framesRequiredToMove=10;      //the less the framesToMove the faster the sname moves      function draw(){          if(++frameCount==framesRequiredToMove){              frameCount=0;              move();          }          requestAnimationFrame(draw);      }      function init(){          snake = [{x:3,y:0},{x:2,y:0},{x:1,y:0},{x:0,y:0}];          snake.forEach((p)=>{plot(p.x,p.y,COLORS.SNAKE)})          x=snake[0].x;y=snake[0].y;          score=0;x_move=1;y_move=0;          scoreboard.innerText=score;          newfood();          setTimeout(draw,1000);      }      function plot(x,y,color){          ctx.beginPath();          ctx.rect(x * 10, y * 10, 10, 10);          ctx.fillStyle = color;          ctx.fill();          ctx.closePath();      }      function move(){          snakepx.innerText = x;          snakepy.innerText = y;          x = x + x_move;          y = y + y_move;          // Advance The Snake          plot(x,y,COLORS.SNAKE);          snake.unshift({x:x,y:y});          // Check food encounter          if(x==food_position_x && y==food_position_y){              scoreboard.innerText=++score;              newfood();          }          else{              var last=snake.pop();              ctx.clearRect(last.x * 10, last.y * 10, 10, 10);          }      }      function newfood(){          food_position_x=Math.floor(Math.random() * canvas.width / 10);          food_position_y=Math.floor(Math.random() * canvas.height / 10);          plot(food_position_x,food_position_y,COLORS.FOOD);          foodpx.innerText = food_position_x;          foodpy.innerText = food_position_y;      }      init();        // Key Pressing      document.addEventListener('keydown', function (event) {          event.preventDefault();          switch (event.keyCode) {              case 40: // Moving down                  if (x_move != 0 && y_move != -1) {                      x_move = 0;                      y_move = 1;                  }                  break;              case 39: // Moving right                  if (x_move != -1 && y_move != 0) {                      x_move = 1;                      y_move = 0;                  }                  break;              case 38: // Moving top                  if (x_move != 0 && y_move != 1) {                      x_move = 0;                      y_move = -1;                  }                  break;              case 37: // Moving left                  if (x_move != 1 && y_move != 0) {                      x_move = -1;                      y_move = 0;                  }                  break;          }      });  })();
canvas {      background-color: #000022;      float: left;  }
<canvas id="canvas" width="400" height="180"></canvas>  <div style="margin-left: 410px">      Snake: (<span id="snakepx"></span>, <span id="snakepy"></span>)<br>      Food: (<span id="foodpx"></span>, <span id="foodpy"></span>)<br>      Score: <span id="scoreboard"></span>  </div>
like image 85
Munim Munna Avatar answered Sep 24 '22 14:09

Munim Munna


Well as I had some free time to spare I created my own JS snake to demonstrate you how it can be done. Most important parts are in this.snakeBody where array of body is stored and this.moveForward() where you can see how body is updated.

https://jsfiddle.net/nooorz24/p8xtdv3h/13/

moveForward: function() {     var next = this.getNextfieldValue();      if (next == "frame" || next == "body") {         console.log("You lose!")         this.isAlive = false;     } else {         var newHead = this.getNextfieldCoords();         this.draw.snake(newHead.x, newHead.y);         this.body.unshift(newHead);         if (next == "food") {             this.generateFood();             this.snakeSize++;         } else {             var last = this.body.pop();             this.draw.empty(last.x, last.y);         }     } }, 

I tried to make it as readable as I could, but note that this is unfinished example and would need need loads of improvements to be a playable game

like image 33
NoOorZ24 Avatar answered Sep 21 '22 14:09

NoOorZ24