js2048小游戏,方格是怎么合并和移动的
index.html
<html> <head> <meta charset="utf-8"> <title>2048小游戏</title> <meta name="renderer" content="webkit"> <!-- 360手机优先使用chrome内核 --> <meta name="screen-orientation" content="portrait"> <!-- UC强制竖屏 --> <meta name="x5-orientation" content="portrait"> <!-- QQ强制竖屏 --> <meta name="browsermode" content="application"> <!-- UC浏览器应用模式 --> <!-- <meta name="x5-page-mode" content="app"> --> <!-- QQ应用模式 --> <meta http-equiv="Cache-Control" content="no-siteapp"> <!-- 禁止百度转载页面加载流氓广告 --> <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <!-- 优先使用最高IE内核和chrome内核 --> <meta name="viewport" content="width=device-width,maximum-scale=1,initial-scale=1.0,user-scalable=no"> <!-- 禁止用户修改网页大小 --> <meta name="google" value="notranslate"> <!-- 禁用google翻译网页 --> <meta name="robots" content="index,follow"> <!-- 网页搜索引擎方式 --> <meta name="apple-mobile-web-app-capable" content="yes" /> <link href="css/2048.css" rel="stylesheet"> </head> <body> <div class="wrap"> <div class="score_box"> <b>score:</b><b id="score"></b> </div> <div class="cell_wrap"> <div class="box"> <div class="cell"></div> <div class="cell"></div> <div class="cell"></div> <div class="cell"></div> <div class="cell"></div> <div class="cell"></div> <div class="cell"></div> <div class="cell"></div> <div class="cell"></div> <div class="cell"></div> <div class="cell"></div> <div class="cell"></div> <div class="cell"></div> <div class="cell"></div> <div class="cell"></div> <div class="cell"></div> </div> </div> </div> <script src="js/jquery-3.2.1.js"></script> <script src="js/2048.js"></script> </body> </html> <!-- //加排行榜 -->
2048.css
* { box-sizing: border-box; font-family: Helvetica; } body{ background-color: #444; } .wrap{ overflow:hidden; margin-top: 30px; } .score_box{ position: absolute; left: -40px; text-align: center; width: 200px; height: 50px; color: #e8ddc7; background-color: #c26251; border-radius: 40px; font-size: 20px; line-height: 50px; border: 3px solid #c18479; } .cell_wrap{ background-color: rgba(0,0,0,0.2); width: 35%; height: 35vw; padding: 2.5%; margin: 50px auto 0; border-radius: 20px; } .box{ width: 100%; height: 30vw; position: relative; } .cell{ float: left; height: 25%; width: 25%; box-sizing:border-box; border-radius: 15px; background-color: rgba(230,190,160,0.2); padding: 1.5px; background-clip: content-box; } .number_cell{ position: absolute; box-sizing:border-box; width: 25%; height: 25%; padding: 1.5px; background-clip: content-box; left: 0; top: 0; transition: all 0.2s; color: #e8ddc7; } .number_cell_con{ display: block; -webkit-border-radius: 15px; -moz-border-radius: 15px; border-radius: 15px; width: 100%; height:calc(100% - 5px); height:-moz-calc(100% - 5px); height:-webkit-calc(100% - 5px); } .span_wrap{ position: absolute; float: left; top: 26%; left: 50%; } .number_cell_con span{ position: relative; left: -50%; font-size: 65px; -webkit-border-radius: 15px; -moz-border-radius: 15px; border-radius: 15px; } /*position数组坐标位置*/ .pos00{left:0; top:0;} .pos01{left:25%; top:0; } .pos02{left:50%; top:0; } .pos03{left:75%; top:0; } .pos10{left:0; top:25%; } .pos11{left:25%; top:25%; } .pos12{left:50%; top:25%; } .pos13{left:75%; top:25%; } .pos20{left:0; top:50%; } .pos21{left:25%; top:50%; } .pos22{left:50%; top:50%; } .pos23{left:75%; top:50%; } .pos30{left:0; top:75%; } .pos31{left:25%; top:75%; } .pos32{left:50%; top:75%; } .pos33{left:75%; top:75%; } /*级别格子样式*/ .n2{ background: #e5cdc4; color: #846767; box-shadow: 0 4px 0 #b6a7a1, 0 5px 2px rgba(0,0,0,.35); } .n4{ background: #d8968a; box-shadow:0 4px 0 #ad867f,0 5px 2px rgba(0,0,0,.35); } .n8{ background:#c26251; box-shadow:0 4px 0 #924c3f, 0 5px 2px rgba(0,0,0,.35); } .n16{ background:#ef7964; box-shadow:0 4px 0 #c36a5a,0 5px 2px rgba(0,0,0,.35); } .n32{ background:#b35c79; box-shadow:0 4px 0 #98556c,0 5px 2px rgba(0,0,0,.35); } .n64{ background:#922b19; box-shadow:0 4px 0 #662418,0 5px 2px rgba(0,0,0,.35); } .n128{ background:#992f44; box-shadow:0 4px 0 #782b3a,0 5px 2px rgba(0,0,0,.35); } .n256{ background:#6a2938; box-shadow:0 4px 0 #4e2a32,0 5px 2px rgba(0,0,0,.35); } .n512{ background:#ae3a71; box-shadow: 0 4px 0 #7e3356,0 5px 2px rgba(0,0,0,.35); } .n1024{ background:#dc1071; box-shadow:0 4px 0 #9b1e59, 0 5px 2px rgba(0,0,0,.35); } .n2048{ background:#e56416; box-shadow: 0 4px 0 #a54e19 0 5px 2px rgba(0,0,0,.35); } .n4096{ background:#e8292c; box-shadow: 0 4px 0 #b03032,0 5px 2px rgba(0,0,0,.35); } .number_cell_con:after{ font-size: 8px; display: block; width: 100%; text-align: center; position: relative; top: 70%; } .pop_box{ width: 100%; position: fixed; top: 0; left: 0; height: 100%; background-color: rgba(35,30,30,0.95); z-index: 1; } .center_wrap{ position: absolute; float: left; left: 50%; top: 20%; } .pop_head{ border-radius: 30px 30px 0 0; height: 40px; background-color: #c26251; position: relative; top: -60px; line-height: 40px; color: #e5cdc4; } .pop_center{ position: relative; left: -50%; z-index: 2; width: 40vw; height: 300px; text-align: center; background-color: #e5cdc4; border-radius: 30px; padding: 60px 0px; } .pop_center span{ font-size: 20px; color: #c26251; } .closebtn{ display: block; width: 100px; height: 60px; margin: 40px auto 0; border-radius: 20px; background-color: #c26251; border: 3px solid #c18479; color: #e5cdc4; font-size: 18px; outline: none; } .sign{ float: right; margin-top: -80px; margin-right: 20px; border-radius: 50%; overflow: hidden; border: 3px solid #c18479; display:none; } .close{ position: absolute; z-index: 3; background-color: #e5cdc4; border-radius: 50%; border: 2px solid #999; color: #777; cursor: pointer; transform:rotate(45deg); -ms-transform:rotate(45deg); /* IE 9 */ -moz-transform:rotate(45deg); /* Firefox */ -webkit-transform:rotate(45deg); /* Safari 和 Chrome */ -o-transform:rotate(45deg); font-size: 45px; line-height: 45px; width: 45px; height: 45px; top: -10px; right: -10px; } .rank_wrap{ margin-top: -30px; } #rank_cell{ height: 55px; border-bottom: 0.5px dotted #c26251; line-height: 55px; } .ranking{ float: left; margin-left: 30px; font-weight: bold; color: #666; font-size: 25px; } .headpic{ float: left; margin-left: 30px; margin-top: 2.5px; background-color: #eee; width: 50px; height: 50px; } .name{ float: left; margin-left: 10px; } .myscore{ float: right; margin-right: 30px; color: #c33c12; font-size: 25px; font-weight: bold; } @media screen and (max-width: 850px){ .cell_wrap{ width: 55%; height: 55vw; padding: 2.5%; } .box{ height: 50vw; } .sign{ margin-top: 20px; } } @media screen and (max-width: 780px){ .cell_wrap{ width: 95%; height: 95vw; padding: 7.5%; margin-top: 70px; } .span_wrap{ top: 22%; } .box{ height: 80vw; } .number_cell_con span{ font-size: 40px; } .number_cell_con:after{ font-size: 15px; top: 65%; } .pop_center{ width: 85vw; height: 300px; } } @media screen and (max-width: 480px){ .number_cell_con span{ font-size: 33px; } .span_wrap{ top: 22%; } .number_cell_con:after{ font-size: 11px; top: 65%; } .pop_center{ width: 90vw; height: 300px; } #headpic{ margin-left: 17px; } #name{ margin-left: 7px; } } @media screen and (max-width: 400px){ .number_cell_con span{ font-size: 28px; } .span_wrap{ top: 20%; } .number_cell_con:after{ font-size: 11px; top: 65%; } .pop_center{ width: 90vw; height: 300px; } }
2048.js
Game2048.prototype = { constructor:Game2048, init:function(){ this.score = 0; this.arr = []; this.moveAble = false; $("#score").html("0"); $(".number_cell").remove(); this.creatArr(); }, creatArr:function(){ var i,j; for (i = 0; i < 4; i++) { this.arr[i] = []; for (j = 0; j < 4; j++) { this.arr[i][j] = {}; this.arr[i][j].value = 0; } } var iRandom,jRandom; iRandom=getRandom(3); jRandom=getRandom(3); this.arrValueUpdate(2,iRandom,jRandom); this.drawCell(iRandom,jRandom); }, arrValueUpdate:function(num,i,j){ this.arr[i][j].value = num; }, //画出格子时,是按照css样式来添加的 drawCell:function(i,j){ var item = '<div class="number_cell pos'+i+j+'" ><a class="number_cell_con n2"><div class="span_wrap"><span>' +this.arr[i][j].value+'</span></div></a></div>'; $(".box").append(item); }, addEvent:function(){ var that = this; document.onkeydown=function(event){ var e = event || window.event || arguments.callee.caller.arguments[0]; var direction = that.direction; var keyCode = e.keyCode; switch(keyCode){ case 39: that.moveAble = false; that.moveRight(); that.checkLose(); break; case 40: that.moveAble = false; that.moveDown(); that.checkLose(); break; case 37: that.moveAble = false; that.moveLeft(); that.checkLose(); break; case 38: that.moveAble = false; that.moveUp(); that.checkLose(); break; } }; }, newCell:function(){ var i,j,len,index; var ableArr = []; if(this.moveAble != true){ console.log('不能增加新格子,请尝试其他方向移动!'); return; } //将所有的是0的点添加到ableArr数组中, for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { if(this.arr[i][j].value == 0){ ableArr.push([i,j]); } } } len = ableArr.length; if(len > 0){ index = getRandom(len); i = ableArr[index][0]; j = ableArr[index][1]; this.arrValueUpdate(2,i,j); this.drawCell(i,j); } }, //向上 moveUp:function(){ for(var j = 0 ;j<=3;j++){ for(var i=0;i<=3;i++){ var curVal = this.arr[i][j].value; if(curVal != 0){ var k = i + 1; while(k<=3){ var nextVal = this.arr[k][j].value; if(nextVal != 0){ if(nextVal == curVal){ this.moveAble = true; this.mergeCells(k,j,i,j); } break; } k++; } } } } for(var j = 0 ;j<=3;j++){ for(var i=0;i<=3;i++){ var curVal = this.arr[i][j].value; if(curVal == 0){ var k = i + 1; while(k<=3){ var nextVal = this.arr[k][j].value; if(nextVal !=0 ){ this.moveAble = true; this.moveCell(k,j,i,j); break; } k++; } } } } this.newCell(); }, //向下 moveDown:function(){ for(var j = 0 ;j<=3;j++){ for(var i=3;i>=0;i--){ var curVal = this.arr[i][j].value; if(curVal != 0){ var k = i - 1; while(k>=0){ var nextVal = this.arr[k][j].value; if(nextVal != 0){ if(nextVal == curVal){ this.moveAble = true; this.mergeCells(k,j,i,j); } break; } k--; } } } } for(var j = 0 ;j<=3;j++){ for(var i=3;i>=0;i--){ var curVal = this.arr[i][j].value; if(curVal == 0){ var k = i - 1; while(k>=0){ var nextVal = this.arr[k][j].value; if(nextVal !=0 ){ this.moveAble = true; this.moveCell(k,j,i,j); break; } k--; } } } } this.newCell(); }, //向左 moveLeft:function(){ //合并 //[4,4,8,8] - > [8,0,16,0] for(var i = 0 ; i<=3;i++){ for(var j = 0 ; j<=3; j++){ var curVal = this.arr[i][j].value; if(curVal != 0){ var k = j + 1; while(k <= 3){ var nextVal = this.arr[i][k].value; if(nextVal!=0){ if(nextVal == curVal){ this.moveAble = true; this.mergeCells(i,k,i,j); } break; } k++; } } } } //移动[8,0,16,0] -> [8,16,0,0] for(var i = 0 ; i<=3; i++){ for(var j=0;j<=3; j++){ var curVal = this.arr[i][j].value; if(curVal == 0 ){ var k = j +1; while(k <=3){ var nextVal = this.arr[i][k].value; if(nextVal != 0){ this.moveCell(i,k,i,j); break; } k++; } } } } this.newCell(); }, //向右 moveRight:function(){ console.log("右移动"); //合并[4,4,8,8] -> [0 , 4 , 0 , 16] //合并[4,8,0,8] -> [4,0,0,16] //合并[8,0,0,8] -> [0,0,0,16] //合并[4,0,4,0] -> [0,0,8,0] //从右边找到第一个不为0的点,循环取他的下一个不为0的点,判断是不是和当前点的值相等 //如果相等就合并,并且设置标志位,表示可以移动或者合并,不管相等不相等,都要跳出while循环 for(var i = 0 ; i<=3;i++){ for(var j = 3 ; j>=0; j--){ var curVal = this.arr[i][j].value; if(curVal != 0){ var k = j - 1; while(k >= 0){ var nextVal = this.arr[i][k].value; if(nextVal!=0){ if(nextVal == curVal){ this.moveAble = true; this.mergeCells(i,k,i,j); // this.arr[i][j] = 2 * this.arr[i][j]; // this.arr[i][k] = 0; } break; } k--; } } } } //移动[0,0,4,0] -> [0,0,0,4] //移动[8,0,0,4] -> [0,0,8,4] //从右边找到第一个为0的点,循环取他的下一个不为0的点,重新设置两点的值 for(var i = 0 ; i<=3; i++){ for(var j=3;j>=0; j--){ var curVal = this.arr[i][j].value; if(curVal == 0 ){ var k = j -1; while(k >= 0){ var nextVal = this.arr[i][k].value; if(nextVal != 0){ // this.moveAble = true; // this.arr[i][j].value = nextVal; // this.arr[i][k].value = 0; this.moveCell(i,k,i,j); break; } k--; } } } } this.newCell(); }, mergeCells:function(i1,j1,i2,j2){ //合并 var temp =this.arr[i2][j2].value; var temp1 = temp * 2; this.moveAble = true; this.arr[i2][j2].value = temp1; this.arr[i1][j1].value = 0; $(".pos"+i2+j2).addClass('toRemove'); var theDom = $(".pos"+i1+j1).removeClass("pos"+i1+j1).addClass("pos"+i2+j2).find('.number_cell_con'); setTimeout(function(){ $(".toRemove").remove(); theDom.addClass('n'+temp1).removeClass('n'+temp).find('span').html(temp1); },200); this.score += temp1; $("#score").html(this.score); if(temp1 == 2048){ alert('人才啊!祖国的明天就靠你了^o^'); this.init(); } }, moveCell:function(i1,j1,i2,j2){ this.arr[i2][j2].value = this.arr[i1][j1].value; this.arr[i1][j1].value = 0; this.moveAble = true; $(".pos"+i1+j1).removeClass("pos"+i1+j1).addClass("pos"+i2+j2); }, //由于每个方向都有判断游戏是否结束,这里只判断两个方向的即可 checkLose:function(){ //判断游戏结束 var i,j,temp; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { temp = this.arr[i][j].value; if(temp == 0){ return false; } if(this.arr[i+1] && (this.arr[i+1][j].value==temp)){ return false; } if((this.arr[i][j+1]!=undefined) && (this.arr[i][j+1].value==temp)){ return false; } } } alert('革命尚未成功,同志仍需努力^_^'); this.init(); return true; } } //弹出自定义提示窗口start var showAlert= function(msg, url){ //弹框存在 if ( $("#alert_box").length > 0) { $('#pop_box_msg').html(msg); } else { var alertHtml = '<div id="alert_box" class="pop_box">' + '<div class="center_wrap">' + '<div class="pop_center">' + '<div class="pop_head"></div>' + '<span id="pop_box_msg">' + msg + '</span>' + '<button class="closebtn" onclick="closeAlert()">再来一次</button>' + '</div>' + '</div>' + '</div>'; $("body").append(alertHtml); } $("#alert_box").show(); if(url){ setTimeout(function(){ window.location.href = url + '?id=' + 10000*Math.random(); } , 2000 ); } } //重定义alert window.alert=showAlert; //点击遮罩关闭 function closeAlert(){ $("#alert_box").hide(); } //弹出自定义提示窗口end //排行榜start 静静等待后台传数据 function showRanking(){ if ( $("#ranking_box").length > 0) { } else { //id名为rank_cell 的div块随用户玩获取成绩而增++ //id ranking 排名1 2 3... //id headpic 用户头像 //id name 用户名 //id score 用户成绩 // var rankingHtml = '<div id="ranking_box" class="pop_box">' + '<div class="center_wrap">' + '<div class="pop_center">' + '<div class="pop_head"><b>排行榜</b></div>' + '<div class="rank_wrap">' + '<div id="rank_cell">' + '<span id="ranking" class="ranking">1</span>' + '<img id="headpic" class="headpic">' + '<span id="name" class="name">xxx</span>' + '<span id="myscore" class="myscore"></span>' + '</div>' + '</div><div class="close" onclick="closeRanking()">+</div>' + '</div>' + '</div>' + '</div>'; $("body").append(rankingHtml); $("#myscore").html(this.score); } $("#ranking_box").show(); } function closeRanking(){ $("#ranking_box").hide(); } //排行榜end function getRandom(n){ return Math.floor(Math.random()*n) } function Game2048(){ this.addEvent(); } var g = new Game2048(); g.init();
还要在index.html中引入jquery.js。