<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title></title> <link rel="stylesheet" type="text/css" href="css/2.css"/> </head> <body> <p>2048</p> <div class="c"> <!--<div class="ready block b2" style="top: 0px;">2</div> <div class="ready block b2" style="top: 100px;">2</div> <div class="ready block b2" style="top: 200px;">2</div>--> </div> <script src="js/jquery-1.8.3.js" type="text/javascript" charset="utf-8"></script> <script src="js/2048.js" type="text/javascript" charset="utf-8"></script> </body> </html>
*{ margin: 0; padding: 0; } body{ text-align: center; font-size: 20px; font-family: "微软雅黑"; } button{ 60px; height: 30px; background: #222; text-align: center; line-height: 30px; color: #fff; border: none; font-size: 18px; margin-top: 10px;outline: none; border-radius: 5px;cursor: pointer; } button:active{ opacity: 0.8; } .c{ 400px; height: 400px; background: #eee; margin: 0 auto; position: relative; } .block{ 100px; height: 100px; border-radius: 3px; position: absolute; text-align: center; line-height: 100px; font-size: 40px; color: #fff; } .block.b2{ background:#21adbe; } .block.b4{ background:#3706ef; } .block.b8{ background:#06e1ef; } .block.b16{ background:#05795c; } .block.b32{ background:#08b028; } .block.b64{ background:#8af027; } .block.b128{ background:#ccf027; } .block.b256{ background:#f0b027; } .block.b512{ background:#f06e27; } .block.b1024{ background:#f027b5; } .block.b2048{ background:#f02743; }
/** * 2017.6.9-2017.6.15 */ (function(win,doc,$,undefined){ var G2048 = function(dom){ this.c = $(dom); this.autor="lianxiaozhuang"; this.method="对盒子中每一块设置标记;比如位置00,01,02.....,移动方向键时逐行(或列)遍历方块使之移动(实现数的叠加)" this.arr = ["2","4","8","16","32","64","128","256","512","1024","2048"]; this.arrClassName = ["b2","b4","b8","b16","b32","b64","b128","b256","b512","b1024","b2048"]; this.b_width = 100;//方块宽 。与css保持一致 this.maxNum = 16;//盒子最多容纳方块个数 this.initNum = 2;//初始化进来个数 this.end = false;//结束标志 this.timer = null;//移动后延迟添加方块 this.arrCoreAdd();//ie8添加indexOf方法 this.init(); } G2048.prototype = { constructor:G2048, init:function(){ var _this = this; while(_this.initNum>0){//初始化(盒子里扔进几个最初的块) _this.initNum--; _this.radomCreateBlock(); } doc.onkeydown = function(evt) {//键盘 if(!_this.end){//结束标志 _this.keyBoardEvent(win.event || evt); //键盘事件 clearTimeout(_this.timer); _this.timer = setTimeout(function(){ _this.radomCreateBlock();//添加一块 },300) } } }, arrCoreAdd:function(){//解决ie8下数组没有indexOf()方法报错 if (!Array.prototype.indexOf){ Array.prototype.indexOf = function(elt /*, from*/){ var len = this.length >>> 0; var from = Number(arguments[1]) || 0; from = (from < 0)? Math.ceil(from): Math.floor(from); if (from < 0) from += len; for (; from < len; from++){ if (from in this &&this[from] === elt) return from; } return -1; }; } }, radomCreateBlock:function(){//随机生成一块放到盒子 var _this = this; var c_width = _this.c.width(); var c_top = this.c.offset().top,c_left = this.c.offset().left; var bl = '<div class="set block b2">'+_this.arr[0]+'</div>'; _this.c.append($(bl).css({"visibility":"hidden"})); //先不显示;后判断是否重合 var $set = $(".set"); if($(".ready").length==_this.maxNum){//满了 _this.end = true; alert("Game Over !"); } if(!_this.end){ do{//设置随机位置直到合适为止 $set.offset({ "top": c_top+parseInt(Math.random()*4)*_this.b_width, "left":c_left+parseInt(Math.random()*4)*_this.b_width }) }while(_this.checkLap().lap)//位置不合适false时;在执行do语句 } _this.setMark($set);//设置标记 $set.css({"visibility":"visible"}).removeClass("set").addClass("ready"); //显示 }, checkLap:function(){//监测本次是否超出或者重合 var _this = this; var lap = false;//不重合标志 var s_top = $(".set").offset().top,s_left = $(".set").offset().left; _this.c.find(".ready").each(function(index,element){ var r_top = $(element).offset().top,r_left = $(element).offset().left; if(r_top-s_top==0&&r_left-s_left==0){ lap = true;//重合 return false; } }) return{ lap:lap } }, moveBlock:function(dir){//移动 var _this = this; var c_top = this.c.offset().top,c_left = this.c.offset().left; if(dir=="left"){///////////////////////// for(var loop=0;loop<=3;loop++){//循环四次目的(因为没按一次方向键块只移动一部;一个方向最多移动四次可保证此方向不能再移动) for(var i=0;i<=3;i++){//行 var ii = i.toString();//转为串 for(j=1;j<=3;j++){//列(从左到右) var jj = j.toString(); var jj_next = (j-1).toString();//当前块的左边的那一块所在列数 var $now= $('.ready[mark="'+ii+jj+'"]'); //当前 var $now_next = $('.ready[mark="'+ii+jj_next+'"]');//当前块左边那一块 if($now.length!=0){//遍历当前位置存在 var $now_left = $now.offset().left; if($now_next.length!=0){//当前块的左边不为空白位 if($now.text()== $now_next.text()){//两块值相等;重叠并求和 $now_next.remove();//移除重叠块(其中的一个) var $text = $now.text(); var $index = _this.arr.indexOf($text); //当前移动块的值在数组的下标 $now.offset({"left":$now_left-100 }).text(_this.arr[$index+1]) .removeClass(_this.arrClassName[$index]).addClass(_this.arrClassName[$index+1]);//数值改变,并更换class名 } }else{//当前块的左边为空白 $now.offset({"left":$now_left-100}) } _this.setMark($now);//当前块从新设置标记 } } } } }else if(dir=="right"){//////////////// for(var loop=0;loop<=3;loop++){//循环四次目的(因为每按一次方向键块只移动一步,一个方向最多移动四次可保证此方向不能再移动) for(var i=0;i<=3;i++){//行 var ii = i.toString();//数转字符串 for(j=2;j>=0;j--){//列(从右到左) var jj = j.toString();//转化为字符串 var jj_next = (j+1).toString();//当前块的右边的那一块所在列 var $now= $('.ready[mark="'+ii+jj+'"]'); //当前 var $now_next = $('.ready[mark="'+ii+jj_next+'"]');//当前块右边那一块 if($now.length!=0){//遍历当前位置存在 var $now_left = $now.offset().left; if($now_next.length!=0){//当前块的右边不为空白位 if($now.text()== $now_next.text()){//两块值相等;重叠并求和 $now_next.removeClass("ready").hide().remove();//移除重叠块(其中的一个) var $text = $now.text(); var $index = _this.arr.indexOf($text); //当前移动块的值在数组的下标 $now.offset({"left":$now_left+100 }).text(_this.arr[$index+1]) .removeClass(_this.arrClassName[$index]).addClass(_this.arrClassName[$index+1]);//数值改变,并更换class名 } }else{//当前块的右边为空白 $now.offset({"left":$now_left+100}) } _this.setMark($now);//当前块从新设置标记 } } } } }else if(dir=="up"){/////////////////// for(var loop=0;loop<=3;loop++){//循环四次目的(因为每按一次方向键块只移动一步,一个方向最多移动四次可保证此方向不能再移动) for(var j=0;j<=3;j++){//列 var jj = j.toString();//数转字符串 for(i=1;i<=3;i++){//行(从上到下) var ii = i.toString();//转化为字符串 var ii_next = (i-1).toString();//当前块的上边的那一块所在行 var $now= $('.ready[mark="'+ii+jj+'"]'); //当前 var $now_next = $('.ready[mark="'+ii_next+jj+'"]');//当前块上边那一块 if($now.length!=0){//遍历当前位置存在 var $now_top = $now.offset().top; if($now_next.length!=0){//当前块的上边不为空白位 if($now.text()== $now_next.text()){//两块值相等;重叠并求和 $now_next.remove();//移除重叠块(其中的一个) var $text = $now.text(); var $index = _this.arr.indexOf($text); //当前移动块的值在数组的下标 $now.offset({"top":$now_top-100 }).text(_this.arr[$index+1]) .removeClass(_this.arrClassName[$index]).addClass(_this.arrClassName[$index+1]);//数值改变,并更换class名 } }else{//当前块的上边为空白 $now.offset({"top":$now_top-100}) } _this.setMark($now);//当前块从新设置标记 } } } } }else if(dir=="down"){/////////////////// for(var loop=0;loop<=3;loop++){//循环四次目的(因为每按一次方向键块只移动一步,一个方向最多移动四次可保证此方向不能再移动) for(var j=0;j<=3;j++){//列 var jj = j.toString();//数转字符串 for(i=2;i>=0;i--){//行(从下到上) var ii = i.toString();//转化为字符串 var ii_next = (i+1).toString();//当前块的下边的那一块所在行 var $now= $('.ready[mark="'+ii+jj+'"]'); //当前 var $now_next = $('.ready[mark="'+ii_next+jj+'"]');//当前块下边那一块 if($now.length!=0){//遍历当前位置存在 var $now_top = $now.offset().top; if($now_next.length!=0){//当前块的下边不为空白位 if($now.text()== $now_next.text()){//两块值相等;重叠并求和 $now_next.remove();//移除重叠块(其中的一个) var $text =$now.text(); var $index = _this.arr.indexOf($text); //当前移动块的值在数组的下标 $now.offset({"top":$now_top+100 }).text(_this.arr[$index+1]) .removeClass(_this.arrClassName[$index]).addClass(_this.arrClassName[$index+1]);//数值改变,并更换class名 } }else{//当前块的上边为空白 $now.offset({"top":$now_top+100}) } _this.setMark($now);//当前块从新设置标记 } } } } } }, setMark:function(dom){//遍历每一块;设置标记(对应所在位置的行列) var c_top = this.c.offset().top,c_left = this.c.offset().left; var $left = dom.offset().left,$top = dom.offset().top; var left_mark = Math.round(($left-c_left)/100).toString(),//此处加Math.round()防止ie解析的不为整数而错误 top_mark = Math.round(($top-c_top)/100).toString(); dom.attr("mark",top_mark+left_mark);//比如第一行第一块设置为"00" }, keyBoardEvent: function(e) {//键盘事件 var _this = this, _key = e.keyCode || e.which; switch(_key) { case 37: //左键 _this.moveBlock("left"); break; case 38: //向上键 _this.moveBlock("up"); break; case 39: //右键 _this.moveBlock("right"); break; case 40: //向下键 _this.moveBlock("down"); break; case 13: //回车键 break; case 32: //空格 break; default: break; } } } new G2048(".c") }(window,document,jQuery))