javascript
用原生JS写一个网页版的2048小游戏(兼容移动端)
?這個(gè)游戲JS部分全都是用原生JS代碼寫的,加有少量的CSS3動(dòng)畫,并簡(jiǎn)單的兼容了一下移動(dòng)端。
先看一下在線的demo:https://yuan-yiming.github.io/2048-online-game/
github地址:https://github.com/Yuan-Yiming/2048-online-game
?
?====================================================================
?
下面簡(jiǎn)單分析一下JS代碼:
1.游戲中包含的主要事件:
new?game按鈕的click事件:點(diǎn)擊后重新開始一次新的游戲;
game?over后重新開始按鈕的click事件:點(diǎn)擊后重新開始一次新的游戲;
桌面端鍵盤上的方向鍵keydown的事件:按下方向鍵后數(shù)字會(huì)向相應(yīng)的方向移動(dòng);
移動(dòng)端的touch事件:通過計(jì)算touchstart和touchend的坐標(biāo)變化,判斷手指在移動(dòng)端屏幕的滑動(dòng)方向;
?
2.業(yè)務(wù)邏輯
2.1 重新開始一次游戲:
需要清空游戲盤,并且隨機(jī)給一個(gè)格子生成一個(gè)數(shù)字2,每次生成不同數(shù)字都會(huì)給格子配相應(yīng)的背景顏色;
2.2?按下方向盤或滑動(dòng)屏幕時(shí)格子移動(dòng)情況(核心部分)
游戲面板有4 x 4的格子,遍歷每一行的每一個(gè)格子,若為空格則不作處理,非空格則要判斷其下一步(注意每次只判斷一步的動(dòng)作,方法howToGo())的運(yùn)動(dòng)情況,即:
a:空格,不作處理
b:非空格,進(jìn)一步判斷下一步動(dòng)作,有3種情況:
b1:若需要移動(dòng)的格子前面是沒有數(shù)字的空格,則格子往前移動(dòng)一個(gè),即將數(shù)字插入到前面格子內(nèi),原本格子中的數(shù)字銷毀,然后從b開始循環(huán)再次判斷;
b2:若需要移動(dòng)的格子前面不是空格,且與前面格子包含的數(shù)字不相等,則格子無需移動(dòng),該格子運(yùn)動(dòng)判斷完畢,進(jìn)行下一個(gè)格子的運(yùn)動(dòng)判斷;
b3:若需要移動(dòng)的格子前面不是空格,且與前面格子包含的數(shù)字相等,則將前面格子內(nèi)的數(shù)字 x 2,原本格子中的數(shù)字銷毀,該格子運(yùn)動(dòng)判斷完畢,進(jìn)行下一個(gè)格子的運(yùn)動(dòng)判斷;
注意:由于是每次運(yùn)動(dòng)都是由運(yùn)動(dòng)方向的最前面格子開始運(yùn)動(dòng)的,即b2,b3兩種情況碰到前面有格子時(shí),說明前面的格子已經(jīng)完成運(yùn)動(dòng),前面沒有空位了,所以當(dāng)前格子運(yùn)動(dòng)完成,繼續(xù)移動(dòng)后面的格子。
?
以下使用圖片來說明格子運(yùn)動(dòng)的情況:
上面有兩行格子,如果是向左運(yùn)動(dòng),首先遍歷第1行,對(duì)1~4號(hào)格子依次判斷其運(yùn)動(dòng)情況,首先1號(hào)格子先運(yùn)動(dòng),由于是1號(hào)格子靠邊,可認(rèn)為其前面是包含不同數(shù)字的格子,運(yùn)動(dòng)情況為b2,無需運(yùn)動(dòng);2號(hào)格子為空格,運(yùn)動(dòng)情況為a;3號(hào)格子前面為空格,首先運(yùn)動(dòng)情況為b1,運(yùn)動(dòng)后3號(hào)格子的數(shù)字插到2號(hào)格子,3號(hào)格子數(shù)字銷毀成為空格,然后需要對(duì)2號(hào)格子再次判斷,再進(jìn)行一次運(yùn)動(dòng),即b3,使得1號(hào)格子數(shù)字變成4,2號(hào)格子成為空格;后面4號(hào)格子為空格不作處理。遍歷第2行,對(duì)5~8號(hào)格子依次判斷其運(yùn)動(dòng)情況,5號(hào)格子與1號(hào)格子情況相同,6、7、8號(hào)格子為空格,無需處理。
向左運(yùn)動(dòng)后的格子:
?
如果是向右運(yùn)動(dòng),遍歷第1行要從右邊開始,4~1號(hào)格子依次運(yùn)動(dòng),首先4號(hào)格子空格無需處理;然后3號(hào)格子運(yùn)動(dòng)情況b1,向前移動(dòng)一格,數(shù)字2插入到4號(hào)格子內(nèi);2號(hào)空格無需處理;1號(hào)空格先連續(xù)進(jìn)行兩次b1運(yùn)動(dòng),再進(jìn)行一次b3運(yùn)動(dòng),碰到4號(hào)格子內(nèi)數(shù)字相同,最終使得4號(hào)格子內(nèi)數(shù)字變成4。遍歷第2行,8~5號(hào)格子依次運(yùn)動(dòng),8、7、6號(hào)為空格均無需處理,5號(hào)格子連續(xù)3次b1運(yùn)動(dòng),使得8號(hào)格子內(nèi)數(shù)字變成2。
向右運(yùn)動(dòng)后的格子:
?
向上或者向下運(yùn)動(dòng)同理。
?
=====================================================================
?
下面廢話不說,直接上代碼。
HTML代碼:index.html
<!DOCTYPE html> <html> <head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"><title>Play 2048 Game Online!</title><link rel="stylesheet" type="text/css" href="desktop.css"><link media="(max-width: 860px)" rel="stylesheet" type="text/css" href="mobile.css"><link rel="icon" href="icon.png"> </head> <body><!-- <div class="github"><a href="https://www.baidu.com"></a></div> --><div class="wrapper"><div class="header"><div class="title"><strong>2048</strong></div><div class="slogan"><p>Play 2048 Game Online!</p></div><div class="score"><span>Score</span><br><span class="number">0</span><span class="score-animation">+12</span></div><div class="best"><span>Best</span><br><span class="number">1024</span><span class="best-animation">+12</span></div><div class="new-game"><span>New Game</span></div></div><div class="game-board"><div class="grid grid-11 row1 col1"><span></span></div><div class="grid grid-12 row1 col2"><span></span></div><div class="grid grid-13 row1 col3"><span></span></div><div class="grid grid-14 row1 col4"><span></span></div><div class="grid grid-21 row2 col1"><span></span></div><div class="grid grid-22 row2 col2"><span></span></div><div class="grid grid-23 row2 col3"><span></span></div><div class="grid grid-24 row2 col4"><span></span></div><div class="grid grid-31 row3 col1"><span></span></div><div class="grid grid-32 row3 col2"><span></span></div><div class="grid grid-33 row3 col3"><span></span></div><div class="grid grid-34 row3 col4"><span></span></div><div class="grid grid-41 row4 col1"><span></span></div><div class="grid grid-42 row4 col2"><span></span></div><div class="grid grid-43 row4 col3"><span></span></div><div class="grid grid-44 row4 col4"><span></span></div></div><div class="popup"><div class="game-over"><p>Game is over...</p><p class="try-again">Try again?</p></div><div class="win"><p>You win the game!! </p><p>Congratulation!!</p><p class="try-again">Try again?</p></div></div></div><script type="text/javascript" src="2048.js"></script></body> </html>
CSS桌面版代碼:desktop.css
* {list-style: none;color: #8f7a66;padding: 0;margin: 0;box-sizing: border-box; } body {background-color: #ffffe0; }.wrapper {position: relative;width: 400px;height: 540px;/*border: 1px solid red;*/margin: 0 auto; } /*頭部*/ .header {width: 400px;height: 140px;/*border: 1px solid green;*/position: relative;/*opacity: 0.4;*/ } .title, .slogan, .score, .best, .new-game, .github>a {position: absolute; } .title strong {display: inline-block;width: 260px;height: 100px;font-size: 78px;line-height: 100px;/*text-align: center;*/padding: 0 5px;/*border: 1px solid black;*/ } .slogan {padding: 0 5px;top: 85px;/*border: 1px solid black;*/ } .github>a {display: inline-block;width: 50px;height: 50px;/*border: 1px solid red;*/top: 8%;right: 5%;/*margin: 5px;*/background: url("Git.png") no-repeat 0 0;border-radius: 50%;background-size: 100%; } .github>span>span {display: inline-block;width: 100px;height: 16px;line-height: 16px;position: absolute;bottom: -24px;left: -25px;text-align: center;color: #2c2c2c; }/*分?jǐn)?shù)*//* 分?jǐn)?shù)動(dòng)畫 */ .score-animation, .best-animation{display: none;position: absolute;top: 25px;left: 10px;width: 65px;height: 30px;font-size: 24px;font-weight: bold; } .score {left: 220px; } .best {left: 315px; } .score, .best {position: absolute;width: 85px;height: 60px;line-height: 28px;top: 20px;background-color: #bbada0; } .score span, .best span, .new-game span {color: #ffffff; } .score, .best, .new-game, .game-board, .grid {text-align: center;border-radius: 5px; } .best .number, .score .number, .new-game {font-size: 22px;font-weight: bold; } .new-game {width: 180px;height: 40px;line-height: 40px;left: 220px;top: 90px;text-align: center;background-color: #8e7963;cursor: pointer; } .new-game:hover {width: 182px;height: 42px;line-height: 42px;left: 219px;top: 89px;font-size: 24px; }/*游戲主面板*/ .game-board {width: 400px;height: 400px;padding: 5px 5px;background-color: #bbada0;/*opacity: 0.4;*/ } .grid {position: relative;float: left;width: 87.5px;height: 87.5px;line-height: 87.5px;/*font-size: 48px;*/font-weight: bold;margin: 5px;background-color: #b0c4de; } .game-board .grid span {/*color: */} /*game over or win the game彈出頁面*/ .popup .game-over, .popup .win {position: absolute;left: 60px;text-align: center;width: 280px;height: 160px;border-radius: 5px;/*border: 1px solid red;*/opacity: 1.0; } .popup p {color: #8f7a66; } .popup .game-over {display: none;top: 230px;font-size: 36px;font-weight: bold; }.popup .win {display: none;top: 220px;font-size: 28px;font-weight: bold; }p.try-again {color: #fff;font-size: 22px;width: 150px;height: 50px;line-height: 50px;border-radius: 5px;margin: 0 auto;background-color: #8f7a66;cursor: pointer; } .header, .game-board {/*opacity: 0.4;*/ }.new-grid {background-color: #b0c4de !important; }/* 生成新格子動(dòng)畫 */ @keyframes tempgrid {from {width: 45px; height: 45px; top: 24px;left: 24px; font-size: 18px; line-height: 45px;display: block;}to {width: 87.5px; height: 87.5px; top: 0px;left: 0px; font-size: 48px; line-height: 87.5px;display: none;} } @-webkit-keyframes tempgrid {from {width: 45px; height: 45px; top: 24px;left: 24px; font-size: 18px; line-height: 45px;display: block;}to {width: 87.5px; height: 87.5px; top: 0px;left: 0px; font-size: 48px; line-height: 87.5px;display: none;} } @-moz-keyframes tempgrid {from {width: 45px; height: 45px; top: 24px;left: 24px; font-size: 18px; line-height: 45px;display: block;}to {width: 87.5px; height: 87.5px; top: 0px;left: 0px; font-size: 48px; line-height: 87.5px;display: none;} } .temp-grid {animation: tempgrid 0.15s ease-in forwards;-webkit-animation: tempgrid 0.15s ease-in forwards;-ms-animation: tempgrid 0.15s ease-out forwards;-moz-animation: tempgrid 0.15s ease-out forwards; }
CSS移動(dòng)端兼容代碼:mobile.css
body {background-color: #fffadd; }.wrapper {width: 100%;/*height: 540px;*//*border: 1px solid red;*//*margin: 0 auto;*/ }/*頭部*/ .header {width: 100%;/*height: 140px;*/position: relative; } .title, .slogan, .score, .best, .new-game {position: absolute;float: left;text-align: center; }.title, .slogan {width: 100%;}.title strong {display: inline-block;width: 100%;/*height: 260px;*/font-size: 487%; /* 100% 16px *//*line-height: 192%;*/text-align: center;/*padding: 0 5px;*//*border: 1px solid black;*/ } .slogan {/*margin-top: 10px;*/top: 65%; }/* github */ /*.github>a {top: 4%;right: 6.25%; }*//*分?jǐn)?shù)*/ .score, .best, .new-game {width: 25%;/*border: 1px solid green;*/ }/* 分?jǐn)?shù)動(dòng)畫 */ .score-animation, .best-animation{display: none;/*position: absolute;*/top: 25px;left: 10px;width: 65px;height: 30px;font-size: 24px;font-weight: bold; }.score, .best {/*position: absolute;*/line-height: 28px;top: 90%;background-color: #bbada0; } .score {left: 47.5%; } .best {left: 75%; } .new-game {width: 45%;height: 60px;line-height: 60px;left: 0;top: 90%;text-align: center;background-color: #8e7963;cursor: pointer;/*padding-bottom: 2em;*/font-size: 28px; } .new-game:hover {width: 45%;/*height: 42px;*//*line-height: 42px;*/height: 60px;line-height: 60px;left: 0;top: 90%;/*line-height: 2e;*/font-size: 28px; }.score span, .best span, .new-game span {color: #ffffff; } .score, .best, .new-game, .game-board, .grid {text-align: center;border-radius: 5px; } .best .number, .score .number {font-size: 22px;font-weight: bold; }/*游戲主面板*/ .game-board {position: absolute;/*display: none;*/width: 100%;height: auto;/*height: 400px;*//*padding: 10px 10px;*/background-color: #bbada0;/*opacity: 0.4;*/top: 36%; } .grid {/*position: relative;*/float: left;width: 22%;/*height: *//*padding-bottom: 21.95%;*//*height: 100%;*/line-height: 80px;/*font-size: 48px;*/font-weight: bold;/*padding-bottom: 410px;*/padding: 1.5%;background-color: #b0c4de; }/* 生成新格子動(dòng)畫 */ @keyframes tempgrid {from {width: 50%; height: 50%; top: 25%;left: 25%; font-size: 24px; line-height: 192%;display: block;}to {width: 100%; height: 100%; top: 0px;left: 0px; font-size: 48px; line-height: 192%;display: none;} } @-webkit-keyframes tempgrid {from {width: 50%; height: 50%; top: 25%;left: 25%; font-size: 24px; line-height: 192%;display: block;}to {width: 100%; height: 100%; top: 0px;left: 0px; font-size: 48px; line-height: 192%;display: none;} } @-moz-keyframes tempgrid {from {width: 50%; height: 50%; top: 25%;left: 25%; font-size: 24px; line-height: 192%;display: block;}to {width: 100%; height: 100%; top: 0px;left: 0px; font-size: 48px; line-height: 192%;display: none;} }
js代碼:2048.js
// 頁面加載時(shí) window.onload = function () {// var temp = tempGrid(2);giveNumber(2);newGameBotton();getReady();backgroundColorToNumber();scaleWidth();touch(); }// 在移動(dòng)端使得格子寬高比例1:1 function scaleWidth() {// 獲取格子的寬度var grid = document.getElementsByClassName("grid"),width = window.getComputedStyle(grid[0], null)["width"];// width = grid[0].style.width;//給格子高度賦值for (var i = 0; i < 16; i++) {grid[i].style.height = width;} }// 創(chuàng)建一個(gè)臨時(shí)的格子 function createTempGrid(num) {var temp = document.createElement("div");temp.innerHTML = "<span>" + num + "</span>"; temp.style.position = "absolute";temp.style.backgroundColor = "#fff8dc";temp.style.width = "87.5px";temp.style.height = "87.5px";temp.style.lineHeight = "87.5px";temp.style.fontWeight = "bold";temp.style.fontSize = "48px";temp.style.borderRadius = "5px";temp.style.top = "0";temp.style.left = "0";// temp.style.display = "none";// console.log(temp);temp.classList.add("temp-grid");return temp;};// 刪除臨時(shí)格子 function deleteTempGrid() {var temp = document.getElementsByClassName("temp-grid");for (var i = 0; i < temp.length; i ++) {temp[i].remove();}var newGrid = document.getElementsByClassName("new-grid");// console.log(newGrid);if (newGrid) {// console.log(newGrid.length);for (var i = 0; i < newGrid.length; i ++) {newGrid[i].classList.remove("new-grid");// console.log(newGrid.length);}} }// giveNumber:隨機(jī)生成一個(gè)空格子,每個(gè)空格子里面放一個(gè)數(shù)字num function giveNumber(num) {// console.log("give!!!!");var x, y, newGrid, tempGrid;tempGrid = createTempGrid(num);while (true) {// if (tempGrid && tempGrid.parentElement) {// tempGrid.parentElement.removeChild(tempGrid);// }x = Math.floor(Math.random() * 4) + 1;y = Math.floor(Math.random() * 4) + 1;newGrid = document.getElementsByClassName("grid-" + x + y)[0];// newGrid.style.backgroundColor = "#b0c4de";if (newGrid.innerHTML == "<span></span>") {newGrid.classList.add("new-grid");newGrid.innerHTML = "<span>" + num + "</span>";newGrid.appendChild(tempGrid);break;}}// return blankGrid; }// clearGrid:清空格子及分?jǐn)?shù)歸零 function clearGrid() {var grid = document.getElementsByClassName("grid"),score = document.getElementsByClassName("score")[0].children[2];score.innerText = "0";for (var i = 0; i < grid.length; i ++) {grid[i].innerHTML = "<span></span>";// grid[i].style.backgroundColor = "#b0c4de";}backgroundColorToNumber(); }// 重新開始一次游戲 function newGame() {clearGrid();giveNumber(2);backgroundColorToNumber();return true; }// 觸發(fā)新一次游戲的按鈕 function newGameBotton() {var newGameBtn = document.getElementsByClassName("new-game")[0];newGameBtn.addEventListener("click", function () {newGame(); }, false); newGameBtn.addEventListener("touchend", function () {newGame();}, false); }// backgroundColorToNumber:數(shù)字跟背景顏色/數(shù)字大小對(duì)應(yīng) function backgroundColorToNumber() {var gridNum,// child,grid = document.getElementsByClassName("grid");for (var i = 0; i < grid.length; i ++) {gridNum = getGridNum(grid[i]);// child = grid[i].children[0];grid[i].style.fontSize = "48px";// if ((" " + grid[i].className + " ").indexOf(" " + "new-grid" + " ") == -1) {switch (gridNum) {case 2:grid[i].style.backgroundColor = "#fff8dc";// grid[i].children[0].style.color = "#fff"; // 這句代碼會(huì)使得頁面癱瘓!!break;case 4:grid[i].style.backgroundColor = "#e9967a";// grid[i].children[0].style.color = "#8f7a66"; break;case 8:grid[i].style.backgroundColor = "#FFA07A";break;case 16:grid[i].style.backgroundColor = "#F4A460";break;case 32:grid[i].style.backgroundColor = "#FA8072";break;case 64:grid[i].style.backgroundColor = "#ff7f50";break;case 128:grid[i].style.backgroundColor = "#FF6347";grid[i].style.fontSize = "40px";break;case 256:grid[i].style.backgroundColor = "#FF8800";grid[i].style.fontSize = "40px";break;case 512:grid[i].style.backgroundColor = "#FF6600";grid[i].style.fontSize = "40px";break;case 1024:grid[i].style.backgroundColor = "#F53";grid[i].style.fontSize = "32px";break;case 2048:grid[i].style.backgroundColor = "#F40";grid[i].style.fontSize = "32px";break;default:grid[i].style.backgroundColor = "#b0c4de";// grid[i].children[0].style.color = "#fff"; }// }} }// 游戲主入口 function getReady() {window.onkeydown = function(e) {deleteTempGrid(); // 在其他位置keyDown(e.keyCode);// backgroundColorToNumber();} }// getGridNum(ele):傳入div元素,返回格子里面的數(shù)字 function getGridNum(ele) {return parseInt(ele.children[0].innerText); // 空格返回NaN }// 各個(gè)方向的prevGrid,即所對(duì)應(yīng)方向的前一個(gè)格子 function getPrevGrid(ele, direction) {var prevEle,count = 0;// 各個(gè)方向if (direction == "left") {return ele.previousElementSibling || null;} else if (direction == "right") {return ele.nextElementSibling || null;} else if (direction == "up") {for (var i = 0; i < 4; i ++) {ele = ele.previousElementSibling;if (!ele) {return null;}}return ele;} else if (direction == 'down') {for (var i = 0; i < 4; i ++) {ele = ele.nextElementSibling;if (!ele) {return null;}}return ele;} }// #滑塊移動(dòng)# // 桌面版通過監(jiān)聽方向鍵來控制滑塊移動(dòng)方向 function keyDown(keyCode) {var dir,arr,go,count = 0, // 用于疊加每次運(yùn)動(dòng)得到的分?jǐn)?shù)signal = 0; // 用于判斷格子是否運(yùn)動(dòng)switch (keyCode) {case 37:dir = "left";break;case 38:dir = "up";break;case 39:dir = "right";break;case 40:dir = "down";break;}for (var i = 1; i < 5; i ++) {if (dir == "up" || dir == "down") {arr = document.getElementsByClassName("col" + i);}else if (dir == "left" || dir == "right") {arr = document.getElementsByClassName("row" + i);}if (dir == "up" || dir == "left") {for (var j = 1; j <= 3; j ++) {// console.log(col[j]);max = j;go = howToGo(arr[j], dir, max); // 疊加返回得分// console.log("go2:" + go);signal += go;if (go > 1) {count += go; // 累計(jì)每一次運(yùn)動(dòng)的得分}}} else if (dir == "down" || dir == "right") {for (var j = 2; j >= 0; j --) {max = 3 - j;go = howToGo(arr[j], dir, max);// gridMove(arr[j], dir, 1);// console.log("go:" + go);signal += go;if (go > 1) {count += go; // 累計(jì)每一次運(yùn)動(dòng)的得分}}}}// 格子有運(yùn)動(dòng)signal > 0if (signal > 0) {// console.log("signal:" + signal);giveNumber(2);backgroundColorToNumber();testGameOver();}// 格子移動(dòng),且得分>0if (count > 0) {addScore(count);}return count; }// 移動(dòng)端使用touch事件來監(jiān)聽滑塊移動(dòng) function touch() {var gameBoard = document.getElementsByClassName("game-board")[0];gameBoard.addEventListener("touchstart",function (e) {// e.preventDefault();startX = e.changedTouches[0].pageX;startY = e.changedTouches[0].pageY;},false);gameBoard.addEventListener('touchend',function(e){e.preventDefault(); // 阻止瀏覽器的默認(rèn)行為,例如滾動(dòng)、跳轉(zhuǎn)等!!//獲取滑動(dòng)屏幕時(shí)的X,YendX = e.changedTouches[0].pageX,endY = e.changedTouches[0].pageY;//獲取滑動(dòng)距離distanceX = endX-startX;distanceY = endY-startY;//判斷滑動(dòng)方向,滑動(dòng)角度大于15°if(Math.abs(distanceX) / Math.abs(distanceY) > 1.73 && distanceX > 0){deleteTempGrid();keyDown(39);}else if(Math.abs(distanceX) / Math.abs(distanceY) > 1.73 && distanceX < 0){deleteTempGrid();keyDown(37);}else if(Math.abs(distanceY) / Math.abs(distanceX) > 1.73 && distanceY < 0){deleteTempGrid();keyDown(38);}else if(Math.abs(distanceY) / Math.abs(distanceX) > 1.73 && distanceY > 0){deleteTempGrid();keyDown(40);}else{// console.log('點(diǎn)擊未滑動(dòng)');}}); }// 3.記錄分?jǐn)?shù),分?jǐn)?shù)會(huì)增加, function addScore(score) {var span = document.getElementsByClassName("number"),currentScore = parseInt(span[0].innerText),bestScore = parseInt(span[1].innerText);span[0].innerText = score + currentScore;scoreUpAnimaton("score", score);if (span[0].innerText > bestScore) {scoreUpAnimaton("best", score);span[1].innerText = span[0].innerText;} }// howToGoLeft(ele, direction, max):該函數(shù)判斷單個(gè)格子怎么移動(dòng) function howToGo(ele, direction, max, testMode) {var prevGrid,prevGridNum,gridNum = 0,go,addNum,numLen,doubleNumGrid;// console.log(prevGrid);// 各個(gè)方向prevGrid = getPrevGrid(ele, direction);gridNum = getGridNum(ele);if (prevGrid) {prevGridNum = getGridNum(prevGrid);} else {prevGridNum = "null";}// 前面是空格,要繼續(xù)判斷。。。。。。。。。。。。。。。。。。。。。if (gridNum && !prevGridNum) {prevGrid.innerHTML = ele.innerHTML;ele.children[0].innerText = "";max -= 1;// gridMove(ele, direction, 1);if (max) {go = howToGo(prevGrid, direction, max);// 0、double、continue}// 返回1// console.log("go:" + (go || 1));// if (max == 0) {// console.log("before:" + typeof(go));// go = 1;// console.log("after" + typeof(go));// }return go || 1; // 若go = 0,返回1;go = double,返回double,go = underfied,返回1// 和前面數(shù)字相同} else if (gridNum == prevGridNum) {if (!testMode) {gridNum *= 2;// addScore(gridNum);// gridMove(ele, direction, 1);prevGrid.children[0].innerText = gridNum + "";// 在這里添加數(shù)字變大的動(dòng)畫:// numLen = (gridNum + "").length;ele.children[0].innerText = "";// console.log('gridNum:' + gridNum)if (gridNum == 2048) {popup("win");}// 如果數(shù)字疊加,就返回得分,且得分≥4}// console.log("gridNum: " + gridNum);return gridNum;} else {// 格子沒動(dòng),返回0return 0;} }// 4.怎么判斷game over,或者達(dá)到2048為winner // test geme over function testGameOver() {var content,leftTest,rightTest,upTest,downTest,count = 0;grid = document.getElementsByClassName("grid");for (var i = 0; i < grid.length; i ++) {content = grid[i].innerHTML;if (content != "<span></span>") {count += 1;}}// console.log("count:" + count);if (count == 16) {if (getGridNum(grid[3]) == getGridNum(grid[4])) {count -= 2;}if (getGridNum(grid[7]) == getGridNum(grid[8])) {count -= 2;}if (getGridNum(grid[11]) == getGridNum(grid[12])) {count -= 2;}for (var i = 0; i < grid.length; i ++) {if(!howToGo(grid[i], "left", 1, true) && !howToGo(grid[i], "right", 1, true) && !howToGo(grid[i], "up", 1, true) && !howToGo(grid[i], "down", 1, true)) {count --;if (count == 0) {popup("game-over");return true;}}}}return false; }// game over 后彈出 function popup(popType) {var num,tryAgainEle,ele = document.getElementsByClassName(popType)[0],headerEle = document.getElementsByClassName("header")[0],gameBoardEle = document.getElementsByClassName("game-board")[0];ele.style.display = "block";headerEle.style.opacity = "0.4";gameBoardEle.style.opacity = "0.4";// tryAgain(num);if (popType == "game-over") {num = 0;}if (popType == "win") {num = 1;}tryAgainEle = document.getElementsByClassName("try-again")[num];tryAgainEle.addEventListener("click", function () {tryAgain(ele, headerEle, gameBoardEle);}, false);tryAgainEle.addEventListener("touchend", function () {tryAgain(ele, headerEle, gameBoardEle);}, false); }// 再來一次 function tryAgain(ele, headerEle, gameBoardEle) {ele.style.display = "none";headerEle.style.opacity = "1.0";gameBoardEle.style.opacity = "1.0";newGame(); }// 5.測(cè)試 function test() {var randomInt,timer;timer = setInterval(function() {randomInt = Math.floor(Math.random() * 4) + 37;keyDown(randomInt);// console.log(randomInt);if (testGameOver()) {clearInterval(timer);}}, 300); }// 分?jǐn)?shù)增加的動(dòng)畫 function scoreUpAnimaton(type, score) {var ele,score,timer,count = 0;if (type == "score") {ele = document.getElementsByClassName("score-animation")[0];} else if (type == "best") {ele = document.getElementsByClassName("best-animation")[0];}score = "+" + score;ele.innerText = score;ele.style.top = "25px";ele.style.color = "#8f7a66";ele.style.opacity = "1.0"timer = setInterval(function() {count ++;ele.style.display = "inline-block";ele.style.top = parseInt(ele.style.top) - 8 + "px";ele.style.opacity = parseFloat(ele.style.opacity) - 0.1;if (count == 6) {clearInterval(timer);ele.style.display = "none";}}, 80); }
轉(zhuǎn)載于:https://www.cnblogs.com/yuanyiming/p/10480959.html
總結(jié)
以上是生活随笔為你收集整理的用原生JS写一个网页版的2048小游戏(兼容移动端)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 将瀚高数据库表内数据导出Excel格式
- 下一篇: JavaScript获取文本框内容,se