Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Let the snake catch his food

Tags:

javascript

I am trying to create a simple snake game. For now I am trying to catch the food but the position of the snake is never the same as the position of food.

(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);
          food_position_y = Math.floor(Math.random() * canvas.height);
    
      function eat() {   
       console.log('food_x:' + food_position_x + ' x:' + x + ' / food_y:' + food_position_y + ' y:' + y);
        if (y == food_position_y && x == food_position_x) {       
          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, 10, 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>

console.log() will return all positions.

jsfiddle

Am I calculating something wrong? Maybe I have to change the variables food_position_x and food_position_y. If not, I have no idea why the positions are never the same.

like image 701
Reza Saadati Avatar asked Mar 31 '18 23:03

Reza Saadati


People also ask

How do snakes catch their prey?

Snakes will then either constrict (suffocate) or kill their prey with a potent venom. 1/ Snakes ambush their prey after patiently waiting for it to come close to them. 2/ Snakes pick up a scent and follow it, eventually sneaking up on their prey. 3/ Snakes chase after and capture their prey.

Why do snakes throw up their food?

The most common causes for food expulsion are stress, very low temperature, too large prey, underlying health problems, etc. A prey with foreign microbes in its body may rot inside the body of the snake, and cause distension, which could be a reason for vomiting. This is only a brief overview of the process of digestion in snakes.

Do snakes eat their prey head-first?

Ideally, your snake should eat its prey head-first. Snakes are very comfortable eating something that’s long and narrow. However, snakes are far less comfortable eating something that’s too wide. While snakes can extend their jaws wider than you might expect, eating a mouse sideways can present a problem. Snakes have feeding reflexes.

What is the best way to catch a snake?

For this reason a minnow trap is probably best used to catch nonvenomous snakes. Set the trap in a strategic place. Whichever trap you use, set it up in an area where you've seen snakes before.


2 Answers

Your game area is supposed to be a grid of cells with widths and heights of 10. That's why you do this: Math.floor(x/10)*10 when drawing the snake.

To make the eat function work you just need to draw the food in the same way:

food_position_x = Math.floor(Math.random() * canvas.width / 10) * 10;
food_position_y = Math.floor(Math.random() * canvas.height / 10) * 10;

and add the same thing to the if condition of the eat function:

if (Math.floor(y/10)*10 == food_position_y && Math.floor(x/10)* 10 == food_position_x)

(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;
    
      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) {       
          throw new Error("MATCH!"); // This is not an error. Just trying to stop the script
        }
      }
      
      // Drawing
      function draw() {
        eat();
        requestAnimationFrame(function() {      
          draw();      
        });
        // Increase the value of x and y in order to animate
        x = x + x_move;
        y = y + y_move;   
        if (x > canvas.width) x = 0;
        if (y > canvas.height) y = 0;
        if (y < 0) y = canvas.height;
        if (x < 0) x = canvas.width;
        // Draw the snake
        ctx.beginPath();
        ctx.rect(Math.floor(x/10)*10, Math.floor(y/10)*10, 10, 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();  
      } 
      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>
like image 76
Kirill Simonov Avatar answered Oct 22 '22 03:10

Kirill Simonov


Your game looks like it's on big chunky grid, but it really isn't, that's only in the graphics. The state variables, which are what matter, are little fiddly small numbers.

Instead of drawing the snake like this:

ctx.rect(Math.floor(x/10)*10, Math.floor(y/10)*10, 10, 10);

Try drawing it like this:

ctx.rect( x, y, 1, 1 );

And you'll see the real state of the game. This is what you're really playing: https://jsfiddle.net/xeyrmsLc/11/ - and that's why it's hard to get the food.

like image 37
Ben West Avatar answered Oct 22 '22 04:10

Ben West