这段时间看了视频,用JavaScript实现2048小游戏,都是一些基本语法和简单逻辑javascript
下面分享一下整个2048游戏代码css
2048.htmlhtml
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="2048.css">
</head>
<body>
<p>SCORE:<span id="score">0</span></p>
<div id="gridPanel">
<div id="c00" class="cell"></div>
<div id="c01" class="cell"></div>
<div id="c02" class="cell"></div>
<div id="c03" class="cell"></div>
<div id="c10" class="cell"></div>
<div id="c11" class="cell"></div>
<div id="c12" class="cell"></div>
<div id="c13" class="cell"></div>
<div id="c20" class="cell"></div>
<div id="c21" class="cell"></div>
<div id="c22" class="cell"></div>
<div id="c23" class="cell"></div>
<div id="c30" class="cell"></div>
<div id="c31" class="cell"></div>
<div id="c32" class="cell"></div>
<div id="c33" class="cell"></div>
</div>
<div id="gameOver">
<p>
GAME OVER!<br>
SCORE:<span id="final">0</span><br>
<a class="btn" href="javascript:game.start();">TRY AGAIN!</a>
</p>
</div>
<script src="2048.js"></script>
</body>
</html>
2048.css
#gridPanel{
width: 480px;
height: 480px;
margin: 0 auto;
position: relative;
background: #bbada0;
border-radius: 10px;
}
.cell{
width: 100px;
height: 100px;
border-radius: 6px;
background:#ccc0b3;
position: absolute;
font-size: 60px;
text-align: center;
color: #fff;
line-height: 100px;
}
[id^="c0"]{top:16px}
[id^="c1"]{top:132px}
[id^="c2"]{top:248px}
[id^="c3"]{top:364px}
[id$="0"]{left:16px}
[id$="1"]{left:132px}
[id$="2"]{left:248px}
[id$="3"]{left:364px}
.n2{background-color:#eee3da}
.n4{background-color:#ede0c8}
.n8{background-color:#f2b179}
.n16{background-color:#f59563}
.n32{background-color:#f67c5f}
.n64{background-color:#f65e3b}
.n128{background-color:#edcf72}
.n256{background-color:#edcc61}
.n512{background-color:#9c0}
.n1024{background-color:#33b5e5}
.n2048{background-color:#09c}
.n4096{background-color:#a6c}
.n8192{background-color:#93c}
.n2,.n4{color:#776e65}
.n1024,.n2048,.n4096,.n8192{font-size:40px}
p{
width: 480px;margin: 0 auto;
font-size: 40px; font-family: Arial;
font-weight: bold;
padding-top: 15px;
}
#gameOver{
display: none;
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(55,55,55,.5);
}
#gameOver>p{
width: 300px;
height: 200px;
background: #FFFFFF;
position: absolute;
top: 50%;
left: 50%;
margin-top:-100px;
margin-left: -150px;
text-align: center;
line-height: 1.5em;
border-radius: 10px;
border:1px solid #edcf72;
}
#gameOver .btn{
padding: 10px;
color: #FFFFFF;
background: #9f8d77;
border-radius: 6px;
text-decoration: none;
}
2048.js
var game = { data: null, RN: 4, CN: 4,//保存游戏二维数组,总行数,总列数 score: 0,//保存得分 state: 1,//保存游戏状态:1表示运行,0表示结束 RUNNING: 1,//专门表示运行状态 GAMEOVER: 0,//专门表示游戏结束状态 //每一个属性和方法之间必须用逗号隔开! //对象本身的方法要使用本身的属性,必须this. start() {//启动游戏 this.state = this.RUNNING;//重置游戏状态为运行中 this.score = 0;//分数清0 this.data = [];//新建空数组保存在data中 //r从0开始,到<RN结束 for (var r = 0; r < this.RN; r++) { //新建空数组保存到data中r行 this.data[r] = []; //c从0开始,到<CN结束 for (var c = 0; c < this.CN; c++) { //设置data中r行c列的值为0 this.data[r][c] = 0; } }//(遍历结束) this.randomNum(); this.randomNum(); this.updateView(); //事件:内容/设备状态的改变 //事件处理函数:在事件发生时自动执行的操做 document.onkeydown = function (e) { //this->.前的document->game if (this.state == this.RUNNING) switch (e.keyCode) { case 37://左移 this.moveLeft(); break; case 38: //上移 this.moveUp(); break; case 39: //右移 this.moveRight(); break; case 40: //下移 this.moveDown(); break; } }.bind(this); }, move(callback) {//全部移动中相同的代码 //为data拍照,保存在before中 var before = String(this.data); callback.call(this); //为data拍照,保存在after中 var after = String(this.data); if (before != after) {//若是发生了移动 this.randomNum();//随机生成数 if (this.isGameOver())//若是游戏结束 { this.state = this.GAMEOVER; }//修改游戏状态 this.updateView();//更新页面 } }, moveLeft() { this.move(function () { //r从0开始,到<RN结束 for (var r = 0; r < this.RN; r++) { this.moveLeftInRow(r);//左移第r行 } }); }, isGameOver() {//判断游戏是否结束 //遍历data for (var r = 0; r < this.RN; r++) { for (var c = 0; c < this.CN; c++) { //若是当前元素是0,返回false if (this.data[r][c] == 0) return false; //不然,若是c<CN-1且当前元素等于右侧元素 else if (c < this.CN - 1 && (this.data[r][c] == this.data[r][c + 1])) { return false;//返回false } //不然,若是r<RN-1且当前元素等于下方元素 else if (r < this.RN - 1 && (this.data[r][c] == this.data[r + 1][c])) { return false;//返回false } } }//(遍历结束) return true;//返回true }, moveLeftInRow(r) {//左移第r行 //c从0开始,到<CN-1结束,遍历r行中每一个格 for (var c = 0; c < this.CN - 1; c++) { //找r行c列右侧下一个不为0的位置nextc var nextc = this.getNextInRow(r, c); //若是没找到,就退出循环 if (nextc == -1) break; else {//不然 //若是c列的值是0 if (this.data[r][c] == 0) { //将nextc列的值赋值给c列 this.data[r][c] = this.data[r][nextc]; //将nextc列的值置为0 this.data[r][nextc] = 0; c--;//c留在原地 } else if (this.data[r][c] == this.data[r][nextc]) { //不然 若是c列的值等于nextc列的值 //将c列的值*2 this.data[r][c] *= 2; this.score += this.data[r][c]; //将nextc列置为0 this.data[r][nextc] = 0; } } } }, getNextInRow(r, c) {//找r行c列右侧下一个不为0的位置 //i从c+1开始,到<CN结束 for (var i = c + 1; i < this.CN; i++) { //若是i位置不是0,返回i if (this.data[r][i] != 0) return i; }//(遍历结束) return -1; //返回-1 }, moveRight() { this.move(function () { //遍历data中每一行 for (var r = 0; r < this.RN; r++) { this.moveRightInRow(r)//右移第r行 } }); }, moveRightInRow(r) {//右移第r行 //c从CN-1开始,到>0结束,反向遍历r行中每一个格 for (var c = this.CN - 1; c > 0; c--) { //找r行c列左侧前一个不为0的位置prevc var prevc = this.getPrevInRow(r, c); //若是prevc为-1,就退出循环 if (prevc == -1) { break; } else {//不然 //若是c列的值是0 if (this.data[r][c] == 0) { //将prevc列的值赋值给c列 this.data[r][c] = this.data[r][prevc]; //将prevc列的值置为0 this.data[r][prevc] = 0; c++;//c留在原地 } else if (this.data[r][c] == this.data[r][prevc]) { //不然 若是c列的值等于prevc列的值 //将c列的值*2 this.data[r][c] *= 2; this.score += this.data[r][c]; //将prevc列置为0 this.data[r][prevc] = 0; } } } }, getPrevInRow(r, c) {//查找r行c列左侧前一个不为0的位置 //i从c-1开始,到>=0结束,每次-1 for (var i = c - 1; i >= 0; i--) { //若是data中r行i列的值不为0,就返回i if (this.data[r][i] != 0) return i; }//循环结束 //返回-1 return -1; }, moveUp() { this.move(function () { //遍历data中每一列 for (var c = 0; c < this.CN; c++) { //调用moveUpInCol上移第c列 this.moveUpInCol(c); } }); }, moveUpInCol(c) { //r从0开始,到r<RN-1结束,r每次递增1 for (var r = 0; r < this.RN - 1; r++) { //查找r行c列下方下一个不为0的位置nextr var nextr = this.getNextInCol(r, c); //若是没找到,就退出循环 if (nextr == -1) break; else//不然 //若是r位置c列的值为0 if (this.data[r][c] == 0) { //将nextr位置c列的值赋值给r位置 this.data[r][c] = this.data[nextr][c]; //将nextr位置c列置为0 this.data[nextr][c] = 0; r--;//r留在原地 } else if (this.data[r][c] == this.data[nextr][c]) {//不然,若是r位置c列的值等于nextr位置的值 //将r位置c列的值*2 this.data[r][c] *= 2; this.score += this.data[r][c]; //将nextr位置c列的值置为0 this.data[nextr][c] = 0; } } }, getNextInCol(r, c) { //循环,到<RN结束,r每次递增1 for (var i = r + 1; i < this.RN; i++) { //若是r位置c列不等于0, 就返回r if (this.data[i][c] != 0) return i; } //(遍历结束) return -1;//返回-1 }, moveDown() { this.move(function () { //遍历data中每一列 for (var c = 0; c < this.CN; c++) { //调用moveDownInCol下移第c列 this.moveDownInCol(c); } }); }, moveDownInCol(c) { //r从RN-1开始,到r>0结束,r每次递减1 for (var r = this.RN - 1; r > 0; r--) { //查找r位置c列上方前一个不为0的位置prevr var prevr = this.getPrevInCol(r, c); //若是没找到,就退出循环 if (prevr == -1) break; else {//不然 //若是r位置c列的值为0 if (this.data[r][c] == 0) { //将prevr位置c列的值赋值给r位置 this.data[r][c] = this.data[prevr][c]; //将prevr位置c列置为0 this.data[prevr][c] = 0; r++;//r留在原地 } else if (this.data[r][c] == this.data[prevr][c]) {//不然,若是r位置c列的值等于prevr位置的值 //将r位置c列的值*2 this.data[r][c] *= 2; this.score += this.data[r][c]; //将prevr位置c列置为0 this.data[prevr][c] = 0; } } } }, getPrevInCol(r, c) { //循环,r到>=0结束,每次递减1 for (var i = r - 1; i >= 0; i--) { //若是r位置c列不等于0, 就返回r if (this.data[i][c] != 0) return i; }//(遍历结束) return -1; //返回-1 }, updateView() {//将data中的数据更新到每一个div中 //遍历二维数组 for (var r = 0; r < this.RN; r++) { for (var c = 0; c < this.CN; c++) { var n = this.data[r][c]; //找到id为crc的div var div = document.getElementById("c" + r + c); if (n != 0) {//若是n不是0 div.innerHTML = n;//设置div的内容为n //设置div的class为cell n+n div.className = "cell n" + n; } else { div.innerHTML = "";//清楚div的内容 //恢复div的class为cell div.className = "cell"; } } } //找到id为score的span,设置其内容为score属性 document.getElementById("score") .innerHTML = this.score; //找到id为gameOver的div var div = document.getElementById("gameOver"); //若是游戏状态为GAMEOVER就设置div显示 if (this.state == this.GAMEOVER) { div.style.display = "block"; //找到id为final的span,设置其内容为score document.getElementById("final") .innerHTML = this.score; } else {//不然就设置div隐藏 div.style.display = "none"; } }, randomNum() {//在一个随机位置生成2或4 while (true) {//反复: //在0~RN-1之间生成随机数r var r = Math.floor(Math.random() * this.RN); //在0~CN-1之间生成随机数c var c = Math.floor(Math.random() * this.CN); //若是data中r行c列的值为0 if (this.data[r][c] == 0) { //将data中r行c列赋值为: //随机生成一个小数,若是<0.5,就取2,不然取4 this.data[r][c] = Math.random() < 0.5 ? 2 : 4; break; //退出循环 } } },}game.start();在功能上向左,向右,向上,向下基本一致