你的位置:首页 > Java教程

[Java教程]Javascript实现的2048


HTML代码如下

<!DOCTYPE html><html> <head> <title></title> <meta charset="utf-8" /> <link rel="stylesheet" href="2048.css"/> <script src="2048.js"></script> <script> </script> </head> <body>  <p>Score:<span id="score"></span></p> <div id="gridPanel">  <!--背景格-->  <!--第1行-->  <div id="g00" class="grid"></div>  <div id="g01" class="grid"></div>  <div id="g02" class="grid"></div>  <div id="g03" class="grid"></div>  <!--第2行-->  <div id="g10" class="grid"></div>  <div id="g11" class="grid"></div>  <div id="g12" class="grid"></div>  <div id="g13" class="grid"></div>  <!--第3行-->  <div id="g20" class="grid"></div>  <div id="g21" class="grid"></div>  <div id="g22" class="grid"></div>  <div id="g23" class="grid"></div>  <!--第4行-->  <div id="g30" class="grid"></div>  <div id="g31" class="grid"></div>  <div id="g32" class="grid"></div>  <div id="g33" class="grid"></div>  <!--前景格-->  <!--第1行-->  <div id="c00" class="cell"></div>  <div id="c01" class="cell"></div>  <div id="c02" class="cell"></div>  <div id="c03" class="cell"></div>  <!--第2行-->  <div id="c10" class="cell"></div>  <div id="c11" class="cell"></div>  <div id="c12" class="cell"></div>  <div id="c13" class="cell"></div>  <!--第3行-->  <div id="c20" class="cell"></div>  <div id="c21" class="cell"></div>  <div id="c22" class="cell"></div>  <div id="c23" class="cell"></div>  <!--第4行-->  <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"><!--同时包含前景和背景的容器-->  <div><!--半透明灰色背景--></div>  <p><!--居中小窗口-->    Game Over!<br>    Score:<span id="finalScore"></span><br>    <a class="button" onclick="game.start()">Try again!</a>  </p> </div> </body></html>

CSS代码如下

@charset "utf-8";#gridPanel{width:480px;height:480px;  margin:0 auto;  background-color:#bbada0;  border-radius:10px;  position:relative;}.grid,.cell{width:100px; height:100px;  border-radius:6px;}.grid{background-color:#ccc0b3;  margin:16px 0 0 16px;  float:left;}.cell{  /*margin:16px 0 0 16px;  float:left;  position:relative;  z-index:10;  top:-464px;  left:0;*/  position:absolute;  text-align:center;  line-height:100px;  font-size:60px;}#c00,#c01,#c02,#c03{top:16px;}#c10,#c11,#c12,#c13{top:132px;}#c20,#c21,#c22,#c23{top:248px;}#c30,#c31,#c32,#c33{top:364px;}#c00,#c10,#c20,#c30{left:16px;}#c01,#c11,#c21,#c31{left:132px;}#c02,#c12,#c22,#c32{left:248px;}#c03,#c13,#c23,#c33{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}.n8,.n16,.n32,.n64,.n128,.n256,.n512,.n1024,.n2048,.n4096,.n8192{color:#fff}.n1024,.n2048,.n4096,.n8192{font-size:40px}/*分数显示*/p{width:480px; margin:0 auto;  font-family:Arial;font-weight:bold;  font-size:40px; padding-top:15px;}/*Game Over*/#gameOver{width:100%; height:100%;  position:absolute; top:0; left:0;  display:none;}#gameOver>div{width:100%; height:100%;  background-color:#555; opacity:.5;}#gameOver>p{width:300px; height:200px;  border:1px solid #edcf72;  line-height:1.6em; text-align:center;  background-color:#fff; border-radius:10px;  position:absolute; top:50%; left:50%;  margin-top:-135px; margin-left:-150px;}.button{padding:10px; border-radius:6px;  background-color:#9f8b77; color:#fff;  cursor:pointer;}

javascript代码如下

var game={	data:[],//保存所有数字的二维数组	rn:4, //总行数	cn:4, //总列数	state: 0, //游戏当前状态:Running|GameOver	RUNNING:1,	GAMEOVER:0,	score:0, //分数	isGameOver:function(){//判断游戏状态为结束		//如果没有满,则返回false		if(!this.isFull()){			return false;		}else{//否则			//从左上角第一个元素开始,遍历二维数组			for(var row=0;row<this.rn;row++){				for(var col=0;col<this.cn;col++){					//如果当前元素不是最右侧元素					if(col<this.cn-1){					//  如果当前元素==右侧元素						if(this.data[row][col]==							this.data[row][col+1]){							return false;						}					}					//如果当前元素不是最下方元素					if(row<this.rn-1){					//  如果当前元素==下方元素						if(this.data[row][col]==							this.data[row+1][col]){					    return false;						}					}				}			}return true;		}	},	start:function(){//游戏开始		this.state=this.RUNNING;		//找到游戏结束界面,隐藏		var div=document.getElementById("gameOver");		div.style.display="none";		this.data=[//初始化二维数组			[0,0,0,0],			[0,0,0,0],			[0,0,0,0],			[0,0,0,0]		];		this.score=0; //重置分数为0		/*for(var r=0;r<this.rn;r++){			this.data[r]=[];//向空数组中添加每一行数组			for(var c=0;c<this.cn;c++){				//向当前空行数组中加默认元素0				this.data[r][c]=0;			}		}*/		//在两个随机位置生成2或4		this.randomNum();		this.randomNum();		//将数据更新到页面		this.updateView();	},	isFull:function(){//判断当前数组是否已满for(var row=0;row<this.rn;row++){//遍历二维数组	for(var col=0;col<this.cn;col++){		//  只要发现当前元素==0		if(this.data[row][col]==0){			return false;		}	}}		//(如果循环正常退出)		return true;	},	randomNum:function(){//在随机空位置生成一个数		if(!this.isFull()){//如果*不*满,才{			while(true){//循环true				//0-3随机生成一个行号row				var row=parseInt(Math.random()*this.rn);				//0-3随机生成一个列号col				var col=parseInt(Math.random()*this.cn);				//如果data[row][col]==0				if(this.data[row][col]==0){				//  Math.random():<0.5 >=0.5				//					2   4				//  随机生成一个数<0.5?2:4,				//  放入data[row][col]					this.data[row][col]=								Math.random()<0.5?2:4;					break;//退出循环					}			}		}	},	updateView:function(){//将二维数组中每个格的数字放入前景格中//遍历二维数组中每个元素,比如:row=2,col=3, 16for(var row=0;row<this.rn;row++){	for(var col=0;col<this.cn;col++){		/*网页中一切元素,属性,文字都是对象*/		var div=document.getElementById("c"+row+col);			               //"c23"		var curr=this.data[row][col]; //当前元素值		//修改div开始标签和结束标签之间的内容		div.innerHTML=curr!=0?curr:"";		//修改div的class属性	  div.className=curr!=0?"cell n"+curr:"cell"		//  class	}}	var span=document.getElementById("score");	span.innerHTML=this.score;	//判断并修改游戏状态为GAMEOVER	if(this.isGameOver()){		this.state=this.GAMEOVER;		var div=document.getElementById("gameOver");		var span=document.getElementById("finalScore");		span.innerHTML=this.score;	//修改div的style属性下的display子属性为"block"		div.style.display="block";	}	},//updateView方法的结束	/*实现左移*/	/*找当前位置右侧,*下一个*不为0的数*/	getRightNext:function(row,col){		//循环变量:nextc——>指下一个元素的列下标		//从col+1开始,遍历row行中剩余元素,<cn结束		for(var nextc=col+1;nextc<this.cn;nextc++){		//  如果遍历到的元素!=0			if(this.data[row][nextc]!=0){		//    就返回nextc				return nextc;			}		}return -1;//(循环正常退出,就)返回-1	},	/*判断并左移*指定行*中的每个元素*/	moveLeftInRow:function(row){		//col从0开始,遍历row行中的每个元素,<cn-1结束		for(var col=0;col<this.cn-1;col++){		// 获得当前元素下一个不为0的元素的下标nextc			var nextc=this.getRightNext(row,col);		// 如果nextc==-1,(说明后边没有!=0的元素了)			if(nextc==-1){				break;			}else{// 否则		//   如果当前位置==0,				if(this.data[row][col]==0){		//     将下一个位置的值,当入当前位置					this.data[row][col]=						this.data[row][nextc];		//     下一个位置设置为0					this.data[row][nextc]=0;		      col--;//让col退一格,重复检查一次				}else if(this.data[row][col]==							this.data[row][nextc]){		//   否则,如果当前位置==nextc的位置		//     将当前位置*=2;					this.data[row][col]*=2;		//     下一个位置设置为0;					this.data[row][nextc]=0;		//     将当前位置的值,累加到score上					this.score+=this.data[row][col];				}			}		}	},	/*移动所有行*/	moveLeft:function(){    var oldStr=this.data.toString();		//循环遍历每一行		for(var row=0;row<this.rn;row++){		//  调用moveLeftInRow方法,传入当前行号row			this.moveLeftInRow(row);		}//(循环结束后)		var newStr=this.data.toString();		if(oldStr!=newStr){			//调用randomNum(),随机生成一个数			this.randomNum();			//调用updateView(),更行页面			this.updateView();		}	},	moveRight:function(){		var oldStr=this.data.toString();		for(var row=0;row<this.rn;row++){			this.moveRightInRow(row);		}		var newStr=this.data.toString();		if(oldStr!=newStr){			this.randomNum();			this.updateView();		}	},	/*判断并右移*指定行*中的每个元素*/	moveRightInRow:function(row){		//col从cn-1开始,到>0结束		for(var col=this.cn-1;col>0;col--){			var nextc=this.getLeftNext(row,col);			if(nextc==-1){				break;			}else{				if(this.data[row][col]==0){					this.data[row][col]=						this.data[row][nextc];					this.data[row][nextc]=0;		      col++;				}else if(this.data[row][col]==							this.data[row][nextc]){					this.data[row][col]*=2;					this.data[row][nextc]=0;					this.score+=this.data[row][col];				}			}		}	},	/*找当前位置左侧,下一个不为0的数*/	getLeftNext:function(row,col){		//nextc从col-1开始,遍历row行中剩余元素,>=0结束		for(var nextc=col-1;nextc>=0;nextc--){			//  遍历过程中,同getRightNext			if(this.data[row][nextc]!=0){				return nextc;			}		}return -1;	},	/*获得任意位置下方不为0的位置*/	getDownNext:function(row,col){		//nextr从row+1开始,到<this.rn结束		for(var nextr=row+1;nextr<this.rn;nextr++){			if(this.data[nextr][col]!=0){				return nextr;			}		}return -1;	},	/*判断并上移*指定列*中的每个元素*/	moveUpInCol:function(col){		//row从0开始,到<rn-1,遍历每行元素		for(var row=0;row<this.rn-1;row++){		//	先获得当前位置下方不为0的行nextr			var nextr=this.getDownNext(row,col);			if(nextr==-1){ break; // 如果nextr==-1			}else{// 否则		//   如果当前位置等于0				if(this.data[row][col]==0){		//			将当前位置替换为nextr位置的元素					this.data[row][col]=							this.data[nextr][col];		//     将nextr位置设置为0					this.data[nextr][col]=0;					row--;//退一行,再循环时保持原位				}else if(this.data[row][col]==							this.data[nextr][col]){				//   否则,如果当前位置等于nextr位置		//     将当前位置*=2					this.data[row][col]*=2;		//     将nextr位置设置为0					this.data[nextr][col]=0;		//     将当前位置的值累加到score属性上					this.score+=this.data[row][col];				}			}		}	},	/*上移所有列*/	moveUp:function(){		var oldStr=this.data.toString();		//遍历所有列for(var col=0;col<this.cn;this.moveUpInCol(col++));		var newStr=this.data.toString();		if(oldStr!=newStr){			this.randomNum(); 			this.updateView();		}	},	/*下移所有列*/	moveDown:function(){		var oldStr=this.data.toString();for(var col=0;col<this.cn;this.moveDownInCol(col++));		var newStr=this.data.toString();		if(oldStr!=newStr){			this.randomNum();			this.updateView();		}	},	moveDownInCol:function(col){		//row从this.rn-1,到>0结束,row--		for(var row=this.rn-1;row>0;row--){			var nextr=this.getUpNext(row,col);			if(nextr==-1){				break;			}else{				if(this.data[row][col]==0){					this.data[row][col]=							this.data[nextr][col];					this.data[nextr][col]=0;					row++;				}else if(this.data[row][col]==							this.data[nextr][col]){					this.data[row][col]*=2;					this.data[nextr][col]=0;					this.score+=this.data[row][col];				}			}		}	},	/*获得任意位置上方不为0的位置*/	getUpNext:function(row,col){		for(var nextr=row-1;nextr>=0;nextr--){			if(this.data[nextr][col]!=0){				return nextr;			}		}return -1;	}}//onload事件:当页面加载*后*自动执行window.onload=function(){	game.start();//页面加载后,自动启动游戏	//当按键盘按键时,触发移动:	document.onkeydown=function(){		//获得事件对象中键盘号:2步		//事件对象:在事件发生时自动创建		//     封装了事件的信息		if(game.state==game.RUNNING){			//Step1: 获得事件对象			var e=window.event||arguments[0];					//IE     DOM标准			//Step2: 获得键盘号:e.keyCode			if(e.keyCode==37){				game.moveLeft();			}else if(e.keyCode==39){				game.moveRight();			}else if(e.keyCode==38){				game.moveUp();			}else if(e.keyCode==40){				game.moveDown();			}			//如果按左键,调用moveLeft			//否则如果按右键,调用moveRight		}	}}