📜 ⬆️ ⬇️

Snake on Canvas

Greetings dear Habra community. After reading the post "Create a game using canvas and sprites" on the day of its release, I decided to deepen my knowledge in Canvas. So, as long as the work did not have to deal with this element, I had to quickly run over the API.
Of course, drawing lines, rectangles, triangles and semicircles is a very entertaining exercise. But to gain real experience, the task was set - to create something functional and simple.

That's how the idea was born to write your own game, the familiar snake.

Unfortunately, work and rest take so much time that the game was over just now.
Let it be as a demonstration of the beta version of the game. Maybe someone will benefit from my work. Perhaps I will get an invite, but at the same time I will listen with interest, critical or commendable opinions of my colleagues.

Go!
The code is written using the jQuery library, because it is more convenient. All variables and functions are declared after the page loading event. We enumerate the variables and set the default settings for some, also set the canvas dimensions and define the “body” of the snake. Which will be a multi-dimensional array. The idea is that the snake body is a set of 9px by 9px sectors, and the origin of each sector is a multiple of 10. 1px “to the right” of the sector will not be drawn, for visual separation.
')
//  ,     var canvas, context, first_x, first_y, rabbit_pos = new Array(), rabbit_on_field = false, start = true, state = false, g_over = false, direction = 'right'; //      canvas = document.getElementById('mycanvas'); canvas.width = 310; canvas.height = 310; context = canvas.getContext('2d'); //    context.fillStyle = "#CE3429"; //     var snake_sectors = [[10, 50], [20, 50], [30, 50], [40, 50]]; 

The function of displaying the playing field frames, which we will call immediately after the default settings are announced.

 //    function field(context){ context.strokeStyle = "#546DEA"; context.lineWidth = 1; context.strokeRect(7, 7, 295, 295); } 

The output function of a snake, in which other necessary functions are called.

 //   function snake(){ if(state){ //  ""   //      undefined context.clearRect(first_x, first_y, 9, 9); //  "" :  , / if(start){ //     ,       //   ,   9px  10 for(var i in snake_sectors){ context.fillRect(snake_sectors[i][0], snake_sectors[i][1], 9, 9); } start = false; } else{ //     - "" context.fillRect(snake_sectors.slice(-1)[0][0], snake_sectors.slice(-1)[0][1], 9, 9); } //         if(!rabbit_on_field){ rabbit(); } //     ""  "" var last_x = snake_sectors.slice(-1)[0][0]; var last_y = snake_sectors.slice(-1)[0][1]; first_x = snake_sectors[0][0]; first_y = snake_sectors[0][1]; //        if(direction == 'right'){ var next_x = last_x + 10; if(next_x > 290){ //    ,   window.setTimeout(game_over, 700); return false; } snake_sectors.push([next_x, last_y]); } if(direction == 'down'){ var next_y = last_y + 10; if(next_y > 290){ //    ,   window.setTimeout(game_over, 700); return false; } snake_sectors.push([last_x, next_y]); //     ("" ) } if(direction == 'up'){ var next_y = last_y - 10; if(next_y < 10) { //    ,   window.setTimeout(game_over, 700); return false; } snake_sectors.push([last_x, next_y]); } if(direction == 'left'){ var next_x = last_x - 10; if(next_x < 10) { //    ,   window.setTimeout(game_over, 700); return false; } snake_sectors.push([next_x, last_y]); } //          // .. ""    for(var i = 0; i < snake_sectors.length - 1; i++){ if(snake_sectors.slice(-1)[0][0] == snake_sectors[i][0] && snake_sectors.slice(-1)[0][1] == snake_sectors[i][1]){ //   window.setTimeout(game_over, 700); return false; } } //     //     "" if(!is_catching()) snake_sectors.splice(0, 1); else rabbit(); //   ,   -   setTimeout(snake, 200); // 200 ms } } 

In order. When state == true (true / false, the start / pause state of the game), the function performs a series of actions, which are described in the comments.
Below are all the other functions that are called in snake ().
Briefly in essence: the output of a rabbit (with the generation of random values ​​of its coordinates and checking for the existence of such in the "body" of the snake);
 //      function rabbit(){ //    rabbit_pos[0] = math_rand(); rabbit_pos[1] = math_rand(); //       ""  for(var i in snake_sectors){ if(rabbit_pos[0] == snake_sectors[i][0]){ rabbit_pos[0] = math_rand(); } if(rabbit_pos[1] == snake_sectors[i][1]){ rabbit_pos[1] = math_rand(); } } //  ,        context.fillRect(rabbit_pos[0], rabbit_pos[1], 9, 9); rabbit_on_field = true; } 

function-generator of random values ​​in a given range;

 //       //     function math_rand(){ return Math.ceil((Math.random() * 2.9) * 10) * 10; } 

checking for the rabbit's “eating” (coincidence of the coordinates of the “head” with the coordinates of the rabbit);

 //   ""  // ..   ""     function is_catching(){ if(rabbit_pos[0] == snake_sectors.slice(-1)[0][0] && rabbit_pos[1] == snake_sectors.slice(-1)[0][1]) return true; else return false; } 

announcement of the end of the game and return to the default settings (for a new start);

 // " ",      - //         function game_over(){ //   ,     , //          "Game Over" g_over = true; //     context.clearRect(8, 8, 293, 293); //      context.font='35px Verdana'; context.strokeStyle="#DB733B"; context.strokeText('Game Over!',47,160); //     -   "Game Over!" setTimeout(function(){context.clearRect(8, 8, 293, 293); g_over = false}, 1500); //    -    snake_sectors = [[10, 50], [20, 50], [30, 50], [40, 50]]; state = false; direction = 'right'; start = true; rabbit_on_field = false; } 

trapping of events of clicking on "game" keys and the corresponding consequences;

 //     ""  document.onkeydown = function(event){ var keyCode; if(event == null){ keyCode = window.event.keyCode; } else{ keyCode = event.keyCode; } switch(keyCode){ // space/ case 32: //     if(!g_over){ //    (continue) state = (!state) ? true : false; //   snake(); } break; // left/  case 37: //    "" if(direction == 'right') return; direction = 'left'; break; // up/  case 38: //    "" if(direction == 'down') return; direction = 'up'; break; // right/  case 39: //    "" if(direction == 'left') return; direction = 'right'; break; // down/  case 40: //    "" if(direction == 'up') return; direction = 'down'; break; default: break; } } 

You can play here .

I will be glad to hear healthy criticism in the comments. Thank you for attention!

Source: https://habr.com/ru/post/202014/


All Articles