Reputation: 5429
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.
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.
Upvotes: 7
Views: 153
Reputation: 8491
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>
Upvotes: 3
Reputation: 4596
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.
Upvotes: 1
Reputation: 371089
The main problem is that there are so many possibilities for x
and food_position_x
, and precise control is difficult, that it's very difficult to land exactly on an X that matches in combination with a Y that matches. You have to move back and forth a lot around the same area to get an exact match for X or an exact match for Y (from which you can then proceed to go in some orthogonal direction to land on the food).
But your code does work at a base level. You might consider reducing the speed and making the visual square location exactly match the internal numbers (less visual granularity which doesn't match the underlying state).
Upvotes: 0