Project address -> Uploaded to Github

Project address -> Code cloud

Project Demo Address


The technical details

  • All global variables
var snake_body  // Snake node array, store each snake node location
var direction   // The current direction of the snake's movement
var food_position   // The location of the food is updated every time it is eaten by a snake
Copy the code
  • Initialize the snake node array and the direction the snake starts moving and the location of the food
function init_snake() {
    // Each value in the array is an object containing the x and y coordinates and color information. Red is the snake head
    snake_body = [{
    	x: 40.y: 40.color: 'black'
    }, {
    	x: 60.y: 40.color: 'black'
    }, {
    	x: 80.y: 40.color: 'red'
    }]
    // The snake starts to move right by default
    direction = 'right'
    // Food start position
    food_position = {
    	x: 260.y: 180}}// Call the snake initialization method
init_snake()
Copy the code
  • First draw the game scene,
// init canvas
function init() {
    context.strokeStyle = '#EEEEEE'
    for(var i = 0; i < 500; i += 20) {
        / / draw a vertical bar
    	context.moveTo(i, 0)
    	context.lineTo(i, 500)
    	/ / draw a horizontal line
    	context.moveTo(0, i)
    	context.lineTo(500, i)
    }
    context.stroke()
    // Because there is a food in the game scene by default, this food is generated at a random location
    context.fillStyle = 'black'
    context.fillRect(food_position.x, food_position.y, 20.20)}Copy the code
  • Began to draw the snake
// repaint snake fastival
function draw_snake() {
    var new_fastival = []
    for(var i = 0; i < snake_body.length; i++) {
        context.fillStyle = snake_body[i].color
        context.fillRect(snake_body[i].x, snake_body[i].y, 20.20)
        new_fastival.push({
    	    x: snake_body[i].x,
    	    y: snake_body[i].y
        })
    }
    // Determine if there was a collision with food
    eat_food()
    // Determine if there is death
    dead(new_fastival)
}
Copy the code
  • Listen for keyboard click events and modify the direction variable according to keycode
// left 37
// right 39
// top 38
// bottom 40
window.addEventListener('keydown'.function(e) {
    if(e.keyCode == 37) {
    	if(direction ! ='right') {
            direction = 'left'}}else if(e.keyCode == 39) {
    	if(direction ! ='left') {
            direction = 'right'}}else if(e.keyCode == 38) {
    	if(direction ! ='bottom') {
    	    direction = 'top'}}else if(e.keyCode == 40) {
    	if(direction ! ='top') {
            direction = 'bottom'}}})Copy the code
  • The way snakes move

    By assigning the value of the last digit of the array to the previous digit, the last digit will besnake_bodyThe x or Y value of the last element in the snake node array plus the width of one snake node, ifleftThe direction x minus is equal to 20,rightDirection + x = 20.topDirection – y = 20,bottomDirection of y + = 20.
function move_snake() {
    var x = 0, y = 0
    // determine the direction
    if(direction == 'right') {
    	x = 20
    } else if(direction == 'left') {
    	x = - 20
    } else if(direction == 'top') {
    	y = - 20
    } else if(direction == 'bottom') {
    	y = 20
    }
    for(var i = 0; i < snake_body.length - 1; i++) {
    	snake_body[i].x = snake_body[i + 1].x
    	snake_body[i].y = snake_body[i + 1].y
    }
    snake_body[snake_body.length - 1].x += x
    snake_body[snake_body.length - 1].y += y
}
Copy the code
  • Determine whether the food has been eaten
function eat_food() {
    // If the value of the last object in the snake array is equal to the value of the food, then the food will be eaten by the snake
    if(snake_body[snake_body.length - 1].x == food_position.x && snake_body[snake_body.length - 1].y == food_position.y) {
    	// Produce food again
    	random_food()
    	// A snake feast will be added after the snake eats its food
    	add_snake_fastival()
    }
}
Copy the code
  • After the food is eaten, the location will be randomly produced
// Method of randomly producing food locations
function random_food() {
    food_position = {
        // ~~ is the bitwise integer algorithm, which is more efficient than math.floor ()
    	x: ~~(Math.random() * (500 / 20)) * 20.y: ~ ~ (Math.random() * (500 / 20)) * 20}}Copy the code
  • Add a snake festival for snakes
function add_snake_fastival() {
    / / new festival
    new_fastival = {
    	x: snake_body[0].x - 20.y: snake_body[0].y - 20.color: 'black'
    }
    // Add to the header of the global array
    snake_body.unshift(new_fastival)
}
Copy the code
  • Determine if a snake is dead. It will die if it bumps into a wall or against itself
function dead(new_fastival) {
    var last_fastival = snake_body[snake_body.length - 1]
    // Determine whether to hit the wall
    if(last_fastival.x == - 20 || last_fastival.x == 500 || last_fastival.y == - 20 || last_fastival.y == 500) {
    	alert("Restart the game.")
    	init_snake()
    }
    // Determine whether to self-harm
    for(var i = 0; i < new_fastival.length; i++) {
    	for(var j = i + 1; j < new_fastival.length; j++) {
            if(new_fastival[i].x == new_fastival[j].x && new_fastival[i].y == new_fastival[j].y) {
            	alert("Restart the game.")
            	init_snake()
            }
    	}
    }
}
Copy the code
  • rendering

In Canvas game development, we have a lot of nodes like this that need collision detection.

Writing this collision detection code repeatedly can greatly affect our development efficiency. Based on my previous experience with the game engine, such asunity,cocos creator. .

I wrote a plugin for collision detection, just need to pass x, y, width, height and other parameters, you can easily develop the game ~~

Collision detection blog please see their own simulation game engine, start to write a JS collision detection plug-in, if there is any problem, welcome to communicate with me!