js写2048游戏代码

<!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{
	width: 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{
	width: 400px;
	height: 400px;
	background: #eee;
	margin: 0 auto;
	position: relative;
	
}
.block{
	width: 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))

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏河湾欢儿的专栏

第八节dom以及dom库的封装

1242
来自专栏王肖的UT

《OpenGL ES 2.0 for Android》读书笔记

OpenGL其实只能绘制三角形,确定三个顶点,然后就可以绘制一个三角形,多个三角形拼在一起就可以组成各式各样的图形,把图片资源贴到这些各式各样的图形上就可以实现...

1.8K9
来自专栏码洞

Go 语言切片的三种特殊状态 —— 90% 的开发者都忽视了

我们今天要来讲一个非常细节的小知识,这个知识被大多数 Go 语言的开发者无视了,它就是切片的三种特殊状态 —— 「零切片」、「空切片」和「nil 切片」。

932
来自专栏LIN_ZONE

已知两点的经度和纬度,计算两点间的距离(php,javascript)

php代码:转载  http://www.cnblogs.com/caichenghui/p/5977431.html

1071
来自专栏十月梦想

CSS基础语法

属性(property)是您希望设置的样式属性(style attribute)。每个属性有一个值。属性和值被冒号分开。

794
来自专栏阿炬.NET

asp.net mvc 验证码

3457
来自专栏WindCoder

从li看html标签属性(attribute)和dom元素的属性(property)

从对象来说,attribute是html文档上标签属性,而property则是对应dom元素的自身属性。

4081
来自专栏Android常用基础

自定义View(四)-动画- Interpolator与Evaluator

Interpolator插值器之前我们已经接触过了,而Evaluator好像我们还没有将,这是属性动画中俩个比较中的两个知识点,弄清楚它们有助于我们更好的使用与...

2062
来自专栏九彩拼盘的叨叨叨

学习纲要:ES6系列:箭头函数和对象方法简写

882
来自专栏xingoo, 一个梦想做发明家的程序员

【web必知必会】—— DOM:四个常用的方法

 终于开始复习DOM的知识了,这一阵忙乎论文,基本都没好好看技术的书。   记得去年实习的时候,才开始真正的接触前端,发现原来JS可以使用的如此灵活。 ...

1965

扫码关注云+社区

领取腾讯云代金券