Some strange lewd skills to play good words, can promote their forced case, this is not, a line of JS code to achieve a snake game became loaded forced to the highest realm! The code is as follows:

(function(){var s = [41,40],d = 1,f = 43,x,c = document.createelement ('canvas'); c.width=400; c.height=400; c.style.background="#535353"; C. extContent=" Current browser does not support canvas tag "; b=c.getContext('2d'); function w(s,c){b.fillStyle = c; b.fillRect(s % 20 * 20, ~~(s / 20) * 20 , 18 , 18); }; Document. The onkeydown = function (e) {d = s [1] - [0] = s = (x = 20,1,20] [1 - [(e | | event). The keyCode to 37] | | d)? d : x; }; ! (function(){s.unshift(x = s[0] + d); If (s.i ndexOf (x, 1) > 0 | | x < 0 | | x > 399 | | d = = 1 && x % 20 = = 0 | | d = = 1 && x % 20 = = 19) return alert (' game over! '); w(x,'#2396ef'); x === f ? (()=>{while (s.indexOf(f = ~~(Math.random() * 399)) > 0); w(f,'#35e3dc'); })() : w(s.pop(),'#535353'); setTimeout(arguments.callee,300); }) (); document.body.appendChild(c); }) ();Copy the code

Ps: I’m not here to play pussy. !

Ok, let’s run this line of code to see what it looks like:

Don’t you like the GIFs? Well, you can go to the online demo and see the specific examples.

And with that done,

Okay, back to the point, how could I possibly be here to fake it? I’m going to analyze how this works. That’s what I’m trying to do.

Let’s break down the code to see:

First, the outermost layer wraps a self-calling function, as follows:

(function(){})(); // This is not the only way to write self-calling functionsCopy the code

Then the second step, to draw a scene, which is obviously to use HTML5 canvas tags, we can use the document.createElement() method to create an element, continue:

(function(){// create canvas tag var c = document.createElement('canvas'); }) ();Copy the code

The snake movement scene must be fixed size, that is, we need to set the width and height of the canvas, in this case, I set 400X400, and then add a background to the scene. In this way:

(function(){// create canvas tag var c = document.createElement('canvas'); c.width = 400; c.height = 400; c.style.background = '#535353'; }) ();Copy the code

The Canvas element is created and we want to add it to the DOM page, so use appendChild() to add it. As follows:

(function(){// create canvas tag var c = document.createElement('canvas'); c.width = 400; c.height = 400; c.style.background = '#535353'; document.body.appendChild(c); }) ();Copy the code

Oh, and some browsers may not support the Canvas tag, so let’s not forget to give an elegant hint:

(function(){// create canvas tag var c = document.createElement('canvas'); c.width = 400; c.height = 400; c.style.background = '#535353'; C. extContent=" Current browser does not support canvas tag "; document.body.appendChild(c); }) ();Copy the code

Now that the scene is drawn, we need to draw snakes on the scene, so the canvas.getContext(‘2d’) method is essential.

(function(){// create canvas tag var c = document.createElement('canvas'); c.width = 400; c.height = 400; c.style.background = '#535353'; var b = c.getContext('2d'); document.body.appendChild(c); }) ();Copy the code

Next, the composition of the snake is analyzed. In fact, the scene here can be regarded as 400 20*20 blocks, so the snake can also be regarded as a block by a block, which is a queue, that is, an array, in technical terms [20]. Initializes the snake here for two blocks, namely [20], then the snake initialization or slightly adjust the position, so also [40] 40, to actually appeared for the first time here, is a food, hides the default on the snake initialization position next, then the snake eat immediately, and then under the random position of a food, So the default food position is 40. To make it easier to make a small difference, let’s make it a little bigger, 43. Ok, now we want to know the direction of the snake, the snake can move up, down, left, right, so let’s define s[1] -s [0], based on position. Let’s define a snake first:

(function(){// create canvas tag var c = document.createElement('canvas'); c.width = 400; c.height = 400; c.style.background = '#535353'; var b = c.getContext('2d'); Var s = [41,40]; var s = [41,40]; The location of the food / / the default document. The body. The appendChild (c); }) ();Copy the code

Next, start mapping the snake, its movements and its food. Define a function to fill the background with canvas.fillstyle (), where the snake and the food and the trajectory of the snake are all small square rectangles, so we use Canvas.fillrect () to draw a rectangle. This method takes four parameters, as shown in the image below:

The path coordinates of the snake movement are defined as the coordinates of the snake array, so the first argument is s % 20 * 20 and the second argument is ~~(s / 20 * 20). If you don’t understand the ~~ operator, check out my article on JavaScript bit-operators. It feels a little abstract, but in fact, you need to rely on your imagination to imagine and understand.

(function(){// create canvas tag var c = document.createElement('canvas'); c.width = 400; c.height = 400; c.style.background = '#535353'; var b = c.getContext('2d'); Var s = [41,40]; var s = [41,40]; var s = [41,40]; Function w(s,c){b. Stringstyle = c; B. villrect (s % 20 * 20,~~(s / 20 * 20),18,18); } document.body.appendChild(c); }) ();Copy the code

Each time the snake eats a piece of food, it adds a 20 by 20 piece to the array. Of course, for orientation purposes, the width and height of the piece should be related to the width and height of the drawn rectangle. Therefore, we need to define a variable to represent the location of the next random food after the snake eats it.

(function(){// create canvas tag var c = document.createElement('canvas'); c.width = 400; c.height = 400; c.style.background = '#535353'; var b = c.getContext('2d'); Var s = [41,40],// select * from * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Function w(s,c){b. Stringstyle = c; B. villrect (s % 20 * 20,~~(s / 20 * 20),18,18); } document.body.appendChild(c); }) ();Copy the code

The user then presses the arrow key on the keyboard, or wSAD, to control the direction of the snake’s movement. But we need to know the keyCode of the keyboard key, the keyCode of the arrow key is: left :37, up :38, right :39, down :40. The keyboard event is onKeyDown.

(function(){// create canvas tag var c = document.createElement('canvas'); c.width = 400; c.height = 400; c.style.background = '#535353'; var b = c.getContext('2d'); Var s = [41,40],// select * from * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Function w(s,c){b. Stringstyle = c; B. villrect (s % 20 * 20,~~(s / 20 * 20),18,18); } // Press the direction key to control the movement direction of the snake. Then the game crash document. Onkeydown = function (e) {d = s [1] - [0] = s = = (x = [1-20,1,20] [e | | event]. KeyCode to 37] | | d)? d : x; } document.body.appendChild(c); }) ();Copy the code

The snake then eats one food and should add the next, using the unshift() method here to add the array.

(function(){// create canvas tag var c = document.createElement('canvas'); c.width = 400; c.height = 400; c.style.background = '#535353'; var b = c.getContext('2d'); Var s = [41,40],// select * from * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Function w(s,c){b. Stringstyle = c; B. villrect (s % 20 * 20,~~(s / 20 * 20),18,18); Document.onkeydown = function(e){// If (e){// if (e){// if (e){ So the snake's direction is s [1] - [0] d s = s [1] - [0] s = = = (x = [1-20,1,20] [e | | event]. KeyCode to 37] | | d)? d : x; }! (function(){ s.unshift(x = s[0] + d); }) (); / / it is also a kind of the calling function of writing the document. The body. The appendChild (c); }) ();Copy the code

Then judge if the snake hits a wall or hits itself, the game is over.

(function(){// create canvas tag var c = document.createElement('canvas'); c.width = 400; c.height = 400; c.style.background = '#535353'; var b = c.getContext('2d'); Var s = [41,40],// select * from * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Function w(s,c){b. Stringstyle = c; B. villrect (s % 20 * 20,~~(s / 20 * 20),18,18); Document.onkeydown = function(e){// If (e){// if (e){// if (e){ So the snake's direction is s [1] - [0] d s = s [1] - [0] s = = = (x = [1-20,1,20] [e | | event]. KeyCode to 37] | | d)? d : x; }! (function(){ s.unshift(x = s[0] + d); // If the snake bumps into a wall or itself, The game ends if (s.i ndexOf (x, 1) > 0 | | x < 0 | | x > 399 | | d = = 1 && x % 20 = = 0 | | d = = 1 && x % 20 = = 19) return Alert (' game over '); }) (); / / it is also a kind of the calling function of writing the document. The body. The appendChild (c); }) ();Copy the code

Then they drew the food and decided whether it was eaten by the snake, and if so, randomly generated the next food.

(function(){// create canvas tag var c = document.createElement('canvas'); c.width = 400; c.height = 400; c.style.background = '#535353'; var b = c.getContext('2d'); Var s = [41,40],// select * from * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Function w(s,c){b. Stringstyle = c; B. villrect (s % 20 * 20,~~(s / 20 * 20),18,18); Document.onkeydown = function(e){// If (e){// if (e){// if (e){ So the snake's direction is s [1] - [0] d s = s [1] - [0] s = = = (x = [1-20,1,20] [e | | event]. KeyCode to 37] | | d)? d : x; }! (function(){ s.unshift(x = s[0] + d); // If the snake bumps into a wall or itself, The game ends if (s.i ndexOf (x, 1) > 0 | | x < 0 | | x > 399 | | d = = 1 && x % 20 = = 0 | | d = = 1 && x % 20 = = 19) return Alert (' game over '); // Then start drawing the color of the snake node w(x,'#e641d3'); If (x == f){if(x == f){if(x == f){if(x == f){if(x == f){if(x == f){if(x == f){ while (s.indexOf(f = ~~(Math.random() * 399)) > 0); // Redraw the food color w(f,'#35e3dc'); }else{w(s.pop(),'#535353');}else{w(s.pop(),'#535353'); }}) (); / / it is also a kind of the calling function of writing the document. The body. The appendChild (c); }) ();Copy the code

Finally, let the snake run at a certain time, as follows:

(function(){// create canvas tag var c = document.createElement('canvas'); c.width = 400; c.height = 400; c.style.background = '#535353'; var b = c.getContext('2d'); Var s = [41,40],// select * from * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Function w(s,c){b. Stringstyle = c; B. villrect (s % 20 * 20,~~(s / 20 * 20),18,18); Document.onkeydown = function(e){// If (e){// if (e){// if (e){ So the snake's direction is s [1] - [0] d s = s [1] - [0] s = = = (x = [1-20,1,20] [e | | event]. KeyCode to 37] | | d)? d : x; }! (function(){ s.unshift(x = s[0] + d); // If the snake bumps into a wall or itself, The game ends if (s.i ndexOf (x, 1) > 0 | | x < 0 | | x > 399 | | d = = 1 && x % 20 = = 0 | | d = = 1 && x % 20 = = 19) return Alert (' game over '); // Then start drawing the color of the snake node w(x,'#e641d3'); If (x == f){if(x == f){if(x == f){if(x == f){if(x == f){if(x == f){if(x == f){ while (s.indexOf(f = ~~(Math.random() * 399)) > 0); // Redraw the food color w(f,'#35e3dc'); }else{w(s.pop(),'#535353');}else{w(s.pop(),'#535353'); } setTimeout(arguments.callee,300); }) (); / / it is also a kind of the calling function of writing the document. The body. The appendChild (c); }) ();Copy the code

So that’s it, that’s it. Actually, the logic here is not so hard, but the hard thing is to calculate the coordinates of the snake and the trajectory of the snake and the food. Can understand thoroughly, depends on personal mathematics knowledge, ha ha. Finally, the integration of so much code into a line of code, you can be well installed force!

Ps: This article code draws lessons from a foreign god more than 20 lines of JS code to achieve greedy snake, based on the source code analysis and modify packaging, do not like spray.