Comment: The difficulty of the game is how to simulate the movement of a greedy snake. It's obviously simple if it's just a square. However, how to control the length of the snake after it becomes longer? Here is a brief introduction to the specific implementation. Interested friends can refer to it. I hope it will be helpful to you.
Game operation instructions
Use the arrow keys to control the movement of the snake up and down, left and right. The gluttonous snake will grow one length after eating the food.
Game implementation
The difficulty of the game is how to simulate the movement of a greedy snake. It's obviously simple if it's just a square. But how to control the length of the snake after it becomes longer
What about the movement of each square?
If you observe the movement of the snake, you can find that from the head to the tail of the snake, the position of each square at the next moment is its previous square at the current moment.
location. So all we need to do is control the movement of the head of the gluttonous snake. The positions of other parts can be analogized in turn.
Another noteworthy issue is
After the snake eats food, where should the newly added blocks be placed?
The answer is that at the next moment, the newly added block should appear at the tail position of the current moment.
Therefore, after eating the food, a square should be added before updating each position of the snake and its position is set at the tail position of the current moment.
Then, at the current moment, the positions of all blocks except the new blocks are updated.
index.html
snake.js
var canvas;
var ctx;
var timer;
//Measures
var x_cnt = 15;
var y_cnt = 15;
var unit = 48;
var box_x = 0;
var box_y = 0;
var box_width = 15 * unit;
var box_height = 15 * unit;
var bound_left = box_x;
var bound_right = box_x + box_width;
var bound_up = box_y;
var bound_down = box_y + box_height;
//images
var image_sprite;
//objects
var snake;
var food;
var food_x;
var food_y;
// functions
function Role(sx, sy, sw, sh, direction, status, speed, image, flag)
{
this.x = sx;
this.y = sy;
this.w = sw;
this.h = sh;
this.direction = direction;
this.status = status;
this.speed = speed;
this.image = image;
this.flag = flag;
}
function transfer(keyCode)
{
switch (keyCode)
{
case 37:
return 1;
case 38:
return 3;
case 39:
return 2;
case 40:
return 0;
}
}
function addFood()
{
//food_x=box_x+Math.floor(Math.random()*(box_width-unit));
//food_y=box_y+Math.floor(Math.random()*(box_height-unit));
food_x = unit * Math.floor(Math.random() * x_cnt);
food_y = unit * Math.floor(Math.random() * y_cnt);
food = new Role(food_x, food_y, unit, unit, 0, 0, image_sprite, true);
}
function play(event)
{
var keyCode;
if (event == null)
{
keyCode = window.event.keyCode;
window.event.preventDefault();
}
else
{
keyCode = event.keyCode;
event.preventDefault();
}
var cur_direction = transfer(keyCode);
snake[0].direction = cur_direction;
}
function update()
{
//add a new part to the snake before move the snake
if (snake[0].x == food.x && snake[0].y == food.y)
{
var length = snake.length;
var tail_x = snake[length - 1].x;
var tail_y = snake[length - 1].y;
var tail = new Role(tail_x, tail_y, unit, unit, snake[length - 1].direction, 0, 0, image_sprite, true);
snake.push(tail);
addFood();
}
//modify attributes
//mov the head
switch (snake[0].direction)
{
case 0://down
snake[0].y += unit;
if (snake[0].y > bound_down - unit)
snake[0].y = bound_down - unit;
break;
case 1://left
snake[0].x -= unit;
if (snake[0].x < bound_left)
snake[0].x = bound_left;
break;
case 2://right
snake[0].x += unit;
if (snake[0].x > bound_right - unit)
snake[0].x = bound_right - unit;
break;
case 3: //up
snake[0].y -= unit;
if (snake[0].y < bound_up)
snake[0].y = bound_up;
break;
}
//move other part of the snake
for (var i = snake.length - 1; i >= 0; i--)
{
if (i > 0)
//snake[i].direction=snake[i-1].direction;
{
snake[i].x = snake[i - 1].x;
snake[i].y = snake[i - 1].y;
}
}
}
function drawScene()
{
ctx.clearRect(box_x, box_y, box_width, box_height);
ctx.strokeStyle = "rgb(0,0,0";
ctx.strokeRect(box_x, box_y, box_width, box_height);
//detection collisions
//draw images
for (var i = 0; i < snake.length; i++)
{
ctx.drawImage(image_sprite, snake[i].x, snake[i].y);
}
ctx.drawImage(image_sprite, food.x, food.y);
}
function init()
{
canvas = document.getElementById("scene");
ctx = canvas.getContext('2d');
//images
image_sprite = new Image();
image_sprite.src = "images/sprite.png";
image_sprite.onLoad = function ()
{}
//ojects
snake = new Array();
var head = new Role(0 * unit, 0 * unit, unit, unit, 5, 0, 1, image_sprite, true);
snake.push(head);
window.addEventListener('keydown', play, false);
addFood();
setInterval(update, 300); //note
setInterval(drawScene, 30);
}
Related reading: html5 Snake game perfectly implemented using 63 lines of code