I used the C language and used the curses library to implement a Snake Game On a linux terminal.
This javascript version of the greedy snake is the learning notes of the http://www.veryhuo.com/game/tanchishe.html, the implementation principle is basically the same as the C version.
--------------------
1. How to represent a snake
Store each point (x, y) of snake in a two-dimensional array, and mark these points (x, y) as "cover ", this is used to check whether the snake header has hit the snake body.
// Initialize snkefunction initSnake () {var pointer = randomPointer (len-1, len-1, WIDTH/2); for (var I = 0; I <len; I ++) {var x = pointer [0]-I, y = pointer [1]; snake. push ([x, y]); carrier [x] [y] = "cover"; // mark snake body }}
2. Use js to draw a grid
Use the document. createElent () method to create a table> tr-> td, and then use the document. appendChild () method to append it to the element whose id is "snkewrap:
//initialize grid function initGrid() {var body = document.getElementsByTagName("body")[0];var table = document.createElement("table"),tbody = document.createElement("tbody")for(var j = 0; j < HEIGHT; j++) { var col = document.createElement("tr"); for(var i = 0; i < WIDTH; i++) { var row = document.createElement("td");gridElems[i][j] = col.appendChild(row); }tbody.appendChild(col); }table.appendChild(tbody);document.getElementById("snakewrap").appendChild(table);}
3. generate random coordinates of food
Function randomPointer (startX, startY, endX, endY) {startX = startX | 0; startY = startY | 0; endX = endX | WIDTH; endY = endY | HEIGHT; var p = [], x = Math. floor (Math. random () * (endX-startX) + startX, y = Math. floor (Math. random () * (endY-startY) + startY; // if (x, y) has an object, regenerate the coordinate if (carrier [x] [y]) {return randomPointer (startX, startY, endX, endY);} p [0] = x; p [1] = y; return p ;}
Add new food:
//addObject("food")function addObject(name) {var p = randomPointer(); //get random positionvar x = p[0];var y = p[1];carrier[x][y] = name;gridElems[x][y].className = name;}
4. Press the arrow key to listen to the Action event:
Allow the top-left and bottom-right buttons to change the direction of snake movement. Note that if the direction is the opposite, the modification will not take effect.
Each key on the keyboard has a key cord. This blog records the javascript key cord. You can see that:
| Left arrow |
37 |
| Up arrow |
38 |
| Right arrow |
39 |
| Down arrow |
40 |
//keyboard event listenerfunction attachEvents(e) {e = e || event;directkey = Math.abs(e.keyCode - directkey) != 2 && e.keyCode > 36 && e.keyCode < 41 ? e.keyCode : directkey; return false;}
5. The core of the snake-judgment
Each judgment (that is, the judge () function runs every time --> here the setInterval () method is used), you must first save the "Header" node of snake and then make a judgment.
1) determine the direction and adjust the coordinates of the "Header" according to the direction (because of the setInterval () method, the system will run the judge () function once every millisecond, make sure that the direction of the table is displayed after you press the direction key)
2) Determine whether the "head" hits the wall or the snake's body (that is, when carrier [headX] [headY] = "cover"). If yes, the game ends.
3) Determine whether the current position of the "Header" is food (that is, carrier [headX] [headY] = "food"). If the carrier of the Header element is not food, pop the tail of snake. If yes, let the current position carry information carrier [headX] [headY] = false
4) add an element to the beginning of the array --> to implement the"Visually"The effect of snake moving (or eating food body growth)
Function judge () {// store the "Header" position of snake. var headX = snake [0] [0], headY = snake [0] [1]; switch (directkey) {case 37: headX-= 1; break; // leftcase 38: headY-= 1; break; // upcase 39: headX + = 1; break // rightcase 40: headY + = 1; break; // down} // hit the boundary (block), or hit the body (cover) with the header ), if (headX> = WIDTH | headX <0 | headY> = HEIGHT | headY <0 | carrier [headX] [headY] = "block" | | carrier [headX] [headY] = "cover ") {$ (" Say "). innerText = "Game Over. "; $ (" start "). removeAttribute ("disabled"); $ ("start "). style. color = "#000"; window. clearInterval (snketimer); return;} // if the carrier of the Header element is not a food, pop the tail of snake if (carrier [headX] [headY]! = "Food") {var lastX = snake [snake. length-1] [0], lastY = snake [snake. length-1] [1]; carrier [lastX] [lastY] = false; gridElems [lastX] [lastY]. className = ""; snake. pop ();} else {carrier [headX] [headY] = false; addObject ("food"); // eat the food and then call addObject ("food "), regenerate food} // Add an element to the beginning of the array --> to achieve the effect of "Visually" snake Movement (or food body growth. unshift ([headX, headY]); carrier [headX] [headY] = "cover"; gridElems [headX] [headY]. className = "cover"; len = snake. length ;}
SetInterval () function (so that the above judge () function runs every MS ):
function run_run_run() {if(snakeTimer) {window.clearInterval(snakeTimer);}snakeTimer = window.setInterval("judge()", Math.floor(300));}
6. onload running
The onload event occurs immediately after the page or image is loaded:
Window. onload = function () {initGrid (); document. onkeydown = attachEvents; // listens for keydown events $ ("start "). onclick = function (e) {len = 3; // The initial length of snake directkey = 39; // rightsnake = new Array (); initSnake (); addObject ("food"); run_run_run (); // invalidate the start button $ ("start "). setAttribute ("disabled", true); $ ("start "). style. color = "# aaa ";}}
7. Reference: Http://www.veryhuo.com/game/tanchishe.html
8. Play:My simple and stupid snake game
(Css I borrowed the 2048 most popular recently ):