以下是我自己在学习前段技术的js阶段中,自己用js来写的一个2048的小游戏,具体的代码以及介绍如下:
首先我们得在页面中去将我们的游戏界面用html构建出来,创建一个4x4的九宫格,同时添加一个累计成绩的计分板。
页面效果如下图:
HTML代码如下:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>2048小游戏</title> <link rel="stylesheet" href="index_2048.css"> //引入外部CSS文件 </head> <body> <div> <p>SCORE:<span id="score01">0</span></p> //创建累加分数的计分板 <div> //包裹整个界面的外层盒子,内部添加4行4列的格子 <div id="c00"></div> <div id="c01"></div> <div id="c02"></div> <div id="c03"></div> <div id="c10"></div> <div id="c11"></div> <div id="c12"></div> <div id="c13"></div> <div id="c20"></div> <div id="c21"></div> <div id="c22"></div> <div id="c23"></div> <div id="c30"></div> <div id="c31"></div> <div id="c32"></div> <div id="c33"></div> </div> <div id="gameover"> //创建一个游戏结束时的遮罩层 <div> <p>GAME OVER!!!</p> <p>SCORE:<span id="score02"></span></p> <a href="javascript:game.start()">try again!</a> </div> </div> </div> <script src="index_2048.js"></script> //引入外部js文件 </body> </html>
CSS代码如下:
//去掉浏览器缺省的样式 *{ margin: 0; padding: 0; box-sizing:border-box; } //设置最外层大盒子的样式 .marg{ width: 400px; height: 450px; margin:100px auto 0px; font-family: Arial; font-size: 40px; font-weight: bold; } p{ width: 100%; height: 50px; line-height: 50px; } .marg>p span{ color: red; } //设置包裹九宫格的大盒子的样式 .main{ width: 400px; height: 400px; background-color: #bbada0; border-radius: 15px; } //设置所有的小格子样式 .cell{ width: 80px; height: 80px; margin:16px 0px 0px 16px; border-radius: 5px; background-color: #ccc0b3; float: left; text-align: center; line-height: 80px; } //设置遮罩层的样式 .gameover{ position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: rgba(55,55,55,0.3); display: none; } .over{ width: 300px; position: absolute; top: 50%; left: 50%; border: 1px solid black; border-radius: 5px; background-color: #fff; text-align: center; font-size: 30px; margin-left: -150px; margin-top: -120px; } .over a{ display: inline-block; text-decoration:none; width: 150px; height: 50px; line-height: 50px; font-size: 30px; font-weight: bold; color: #fff; outline: none; border: none; border-radius: 4px; background-color: #9F8D77; margin-bottom: 5px; cursor: pointer; } //设置在游戏中,当格子内的数据发生改变时对应的样式 .n2{background-color:#eee3da;color:#776e65} .n4{background-color:#ede0c8;color:#776e65} .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;font-size:30px;color:#FFF;} .n2048{background-color:#09c;font-size:30px;color:#FFF;} .n4096{background-color:#a6c;font-size:30px;color:#FFF;} .n8192{background-color:#93c;font-size:30px;color:#FFF;}
JS代码如下:
var game ={ mydata: [], //添加一个属性mydata用于存储游戏数据 score: 0, //添加一个得分属性 gameover: 0, //添加一个游戏结束时的状态 gamerrunning:1, //添加一个游戏运行时的状态 status:1, //添加一个游戏状态 start:function (){ //设置一个游戏开始时的方法 this.status = this.gamerrunning; this.score = 0; this.mydata = []; for(var r = 0;r < 4; r++){ //将mydata这个数组循环变量添加0这个数,让其成为一个二维数组 this.mydata[r] = []; for(var c = 0;c < 4;c++){ this.mydata[r][c] = 0; } } this.randomNum(); //游戏开始时随机生成一个2/4的数字 this.randomNum(); this.dataView(); //游戏开始时执行dataView这个函数将数据更新传递到页面中,刷新页面中的数据 // console.log(this.mydata); }, randomNum:function(){ //生成随机数的方法,并将初始值的随机数赋值给mydata for(;;){ //这里的for循环不能给定固定的条件,因为在游戏运行时无法得知它的结束条件,只能一致循环 var r = Math.floor(Math.random()*4); //设置一个随机变量,让其作为数字随机出现的坐标 var c = Math.floor(Math.random()*4); if(this.mydata[r][c] == 0){ //如果数据中当前的这个坐标中的值为0或空的话就插入一个2或4的随机数 var num = Math.random() > 0.5 ? 2 : 4; //设置的这个随机数2或4出现的几率一样,对半开 this.mydata[r][c] = num; break; } } }, dataView:function(){ //数据传递到页面中的方法,并控制样式的变化 for(var r = 0;r < 4;r++){ for(var c = 0;c < 4;c++){ var div = document.getElementById("c" + r + c); if (this.mydata[r][c] == 0) { div.innerHTML = ""; div.className = "cell"; } else { div.innerHTML = this.mydata[r][c]; div.className = 'cell n'+this.mydata[r][c]; } } } document.getElementById('score01').innerHTML = this.score; if (this.status == this.gameover) { document.getElementById('score02').innerHTML = this.score; document.getElementById('gameover').style.display = 'block'; } else{ document.getElementById('gameover').style.display = 'none'; } }, isgameover:function(){ for(var r = 0;r < 4;r++){ for(var c = 0;c < 4;c++){ if (this.mydata[r][c] == 0) { return false; } if (c<3) { if (this.mydata[r][c] == this.mydata[r][c+1]) { return false; } } if (r<3) { if (this.mydata[r][c] == this.mydata[r+1][c]) { return false; } } } } return true; }, //左移动 moveLeft:function(){ var before = String(this.mydata); for(var r = 0;r < 4;r++){ this.moveLeftInRow(r); } var after = String(this.mydata); if (before != after) { this.randomNum(); if (this.isgameover()) { this.status = this.gameover; } this.dataView(); } }, moveLeftInRow:function(r){ for(var c = 0;c < 3;c++){ var nextc = this.getNEXTinRow(r,c); if (nextc != -1) { if (this.mydata[r][c] == 0) { this.mydata[r][c] = this.mydata[r][nextc]; this.mydata[r][nextc] = 0; c--; } else if (this.mydata[r][c] == this.mydata[r][nextc]) { this.mydata[r][c] *=2; this.mydata[r][nextc] =0; this.score += this.mydata[r][c]; } } else { break; } } }, getNEXTinRow:function(r,c){ for(var i = c+1;i < 4;i++){ if (this.mydata[r][i] != 0) { return i; } } return -1; }, //右移动 moveRight:function(){ var before = String(this.mydata); for(var r = 0;r < 4;r++){ this.moveRightInRow(r); } var after = String(this.mydata); if (before != after) { this.randomNum(); if (this.isgameover()) { this.status = this.gameover; } this.dataView(); } }, moveRightInRow:function(r){ for(var c = 3;c > 0;c--){ var nextc = this.RightgetNEXTinRow(r,c); if (nextc != -1) { if (this.mydata[r][c] == 0) { this.mydata[r][c] = this.mydata[r][nextc] ; this.mydata[r][nextc] = 0; c++; } else if (this.mydata[r][c] == this.mydata[r][nextc]) { this.mydata[r][c] *=2; this.mydata[r][nextc] =0; this.score += this.mydata[r][c]; } } else { break; } } }, RightgetNEXTinRow:function(r,c){ for(var i = c-1;i >= 0;i--){ if (this.mydata[r][i] != 0) { return i; } } return -1; }, //上移动 moveTop:function(){ var before = String(this.mydata); for(var r = 0;r < 4;r++){ this.moveTopInRow(r); } var after = String(this.mydata); if (before != after) { this.randomNum(); if (this.isgameover()) { this.status = this.gameover; } this.dataView(); } }, moveTopInRow:function(r){ for(var c = 0;c < 3;c++){ var nextc = this.TopgetNEXTinRow(r,c); if (nextc != -1) { if (this.mydata[c][r] == 0) { this.mydata[c][r] = this.mydata[nextc][r] ; this.mydata[nextc][r] = 0; c++; } else if (this.mydata[c][r] == this.mydata[nextc][r]) { this.mydata[c][r] *=2; this.mydata[nextc][r] =0; this.score += this.mydata[c][r]; } } else { break; } } }, TopgetNEXTinRow:function(r,c){ for(var i = c+1;i < 4;i++){ if (this.mydata[i][r] != 0) { return i; } } return -1; }, //下移动 moveBottom:function(){ var before = String(this.mydata); for(var r = 0;r < 4;r++){ this.moveBottomInRow(r); } var after = String(this.mydata); if (before != after) { this.randomNum(); if (this.isgameover()) { this.status = this.gameover; } this.dataView(); } }, moveBottomInRow:function(r){ for(var c = 3;c > 0;c--){ var nextc = this.BottomgetNEXTinRow(r,c); if (nextc != -1) { if (this.mydata[c][r] == 0) { this.mydata[c][r] = this.mydata[nextc][r] ; this.mydata[nextc][r] = 0; c++; } else if (this.mydata[c][r] == this.mydata[nextc][r]) { this.mydata[c][r] *=2; this.mydata[nextc][r] =0; this.score += this.mydata[c][r]; } } else { break; } } }, BottomgetNEXTinRow:function(r,c){ for(var i = c-1;i >= 0;i--){ if (this.mydata[i][r] != 0) { return i; } } return -1; }, } game.start(); document.onkeydown = function(event){ var event = event || e || arguments[0]; if (event.keyCode == 37) { game.moveLeft(); } else if (event.keyCode == 38) { game.moveTop(); } else if (event.keyCode == 39) { game.moveRight(); } else if (event.keyCode == 40) { game.moveBottom(); } } //下面这段代码是为了将这个游戏通过打包成app模式做的兼容处理, var startX,startY,endX,endY; //定义四个变量来存储X轴与Y轴上的触摸时和离开触摸时的值 document.addEventListener("touchstart",function(event){ //绑定一个手指触摸开始时的监听事件 var event = event || e || arguments[0]; startX = event.touches[0].pageX; startY = event.touches[0].pageY; }) document.addEventListener("touchend",function(event){ //绑定一个手指触摸结束离开时的监听事件 var event = event || e || arguments[0]; endX = event.changedTouches[0].pageX; endY = event.changedTouches[0].pageY; var x = endX - startX; var y = endY - startY; var absX = Math.abs(x) > Math.abs(y); var absY = Math.abs(y) > Math.abs(x); if (x > 0 && absX) { game.moveRight(); } else if (x < 0 && absX) { game.moveLeft(); } else if (y > 0 && absY) { game.moveBottom(); } else if (y < 0 && absY) { game.moveTop(); } })
发表评论 取消回复