Game Operation Instructions
Use the direction keys to control the greedy snake to move up, down, left and right. A greedy snake will grow in length after eating food.
The specific implementation of the game
The difficulty of the game is how to simulate the movement of the greedy snake. It's obviously very simple if it's just a block. But when the length of the snake becomes longer, how to control the movement of each block
?
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 block at the next moment is the position of its previous block at the current moment
Location. So all we need to do is control the movement of the snake's head. The positions of other parts can be deduced by analogy.
Another issue worth noting is
After the greedy snake eats the 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 end of the current moment.
Therefore, after eating food, you should add a block before updating each position of the snake, and set its position to the tail position at the current moment.
Then the positions of all blocks except the newly added blocks are updated at the current moment
index.html
snake.js
The code is as follows:
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, 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 //move 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); }