2048项目开始的前一天才知道JavaScript能开发游戏,出于好奇(一直都没玩过这个游戏),就在手机上下载了2048这个游戏。发现其中除了原版的2048游戏外还有很多的模式,其中的下落模式(类似俄罗斯方块,因此我称之为俄罗斯方块模式)让我很感兴趣,便产生了开发这样模式的想法,同时也为后面用JavaScript开发俄罗斯方块做热身。下图为最终效果图: 俄罗斯方块模式的2048与原版2048相比,一开始以为也是简单的数据相加而已,似乎没什么,可是真正去做的时候才发现没有那么容易。首先,原版2048你每一次操作都是整体进行计算,但是俄罗斯方块模式的2048你每一次操作仅仅针对正在下落的那个方块,我将正在下落的方块称为“当前方块”,下一次出现的方块称为 next方块 ;其次,俄罗斯方块模式的2048的数据计算比较复杂些,“当前方块”下落后要与下面的方块进行合并,在与左边右边方块合并,然后还可能继续往下合并,同时与左边方块合并后也会影响其他方块,又要进行合并,合并过程有点复杂,担心表达不够清楚,下面一张图列举了一个合并的例子。因此在原有2048项目的基础上改为俄罗斯方块模式主要做了如下改变: 1、键盘上的方向键不是控制所有方块的移动,而是控制正在下落的方块即 当前方块,为了能单独控制该方块给game对象新增两个属性:curRow 和 curCol ; 2、当前方块 左右移动时候只需更新相邻两个方块的样式,不必要去更新整个game的视图,为此新定义了一个函数 updateViewTwo() ; 3、加入周期性定时器,实现 当前方块 缓慢向下移动,给game对象增加一个方法timerDown(); 4、当前方块 下落到底部要进行与周围数据相加,比起原版 2048 游戏要复杂得多,这是这个模式难点,为此定义了一个递归函数addData(),来实现数据的相加; 部分主要代码如下:(curRow、curCol为game新增属性,用来定义正在下落的 当前方块 的坐标) updateViewTwo:function(row1,col1,row2,col2){//交换两个方块的视图更新函数 var myid1="c"+row1+col1; var myid2="c"+row2+col2; var mydiv1=document.getElementById(myid1); var mydiv2=document.getElementById(myid2); mydiv1.innerHTML=this.data[row1][col1]; mydiv1.className="gr n"+this.data[row1][col1]; mydiv2.innerHTML=""; mydiv2.className="gr"; }, initialize:function(){//页面加载完成后进行初始化游戏 this.score=0; this.gold=0; this.data=[[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0], [0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0]]; this.dataNext=this.dataR[parseInt(Math.random()*6)]; this.data[this.curRow][this.curCol]=this.dataR[parseInt(Math.random()*6)]; var divnext=document.getElementById("cnext"); divnext.innerHTML=this.dataNext; game.updateView(); }, addData:function(row,col){//实现数据相加计算 if (game.data[row][col]!=0) { if(row!=8&&game.data[row+1][col]==0){//向下移动 game.data[row+1][col]=game.data[row][col]; game.data[row][col]=0; game.addData(row-1,col); game.addData(row+1,col); }else if(row!=8&&game.data[row+1][col]==game.data[row][col]){//向下相加 game.data[row+1][col]=2*game.data[row][col]; game.score+=game.data[row+1][col]; if (game.data[row+1][col]==512) game.gold++; game.data[row][col]=0; game.addData(row+1,col); }else if (col!=0&&game.data[row][col-1]==game.data[row][col]) {//向左相加 game.data[row][col]*=2; game.score+=game.data[row][col]; if (game.data[row][col]==512) game.gold++; game.data[row][col-1]=0; game.addData(row-1,col-1); game.addData(row,col); } else if (col!=7&&game.data[row][col+1]==game.data[row][col]) {//向左相加 game.data[row][col]*=2; game.score+=game.data[row][col]; if (game.data[row][col]==512) game.gold++; game.data[row][col+1]=0; game.addData(row-1,col+1); game.addData(row,col); } } } timerDown:function(){//加入定时器实现当前方块块缓慢下落函数 gameTime=setInterval( function(){ if (game.curRow!=8&&game.data[game.curRow+1][game.curCol]==0) {//判断条件不可调换,否则不能达到预期目的 game.data[game.curRow+1][game.curCol]=game.data[game.curRow][game.curCol]; game.data[game.curRow][game.curCol]=0; game.curRow++; game.updateViewTwo(game.curRow,game.curCol,game.curRow-1,game.curCol); }else{ clearInterval(gameTime); game.addData(game.curRow,game.curCol); game.nextGame(); } } ,1000); }, suspend:function(){//暂停游戏,专为上箭头键和A键设定用于暂停游戏 game.state=0; btn.innerHTML="开始游戏"; clearInterval(gameTime); }, keyDown:function(){ clearInterval(gameTime); game.addData(game.curRow,game.curCol); game.nextGame(); }, keyLeft:function(){//定义当前方块向左移动的函数 if(this.curCol>0&&this.data[this.curRow][this.curCol-1]==0){ var temp=this.data[this.curRow][this.curCol]; this.curCol--; this.data[this.curRow][this.curCol+1]=0; this.data[this.curRow][this.curCol]=temp; this.updateViewTwo(this.curRow,this.curCol,this.curRow,this.curCol+1); } }, keyRight:function(){//定义当前方块向右移动的函数 if(this.curCol<7&&this.data[this.curRow][this.curCol+1]==0){ var temp=this.data[this.curRow][this.curCol]; this.curCol++; this.data[this.curRow][this.curCol-1]=0; this.data[this.curRow][this.curCol]=temp; this.updateViewTwo(this.curRow,this.curCol,this.curRow,this.curCol-1); } }, nextGame:function(){//每次方块下落前进行初始设置 if(this.data[0][2]==0&&this.data[0][4]==0&&this.data[0][3]==0){ this.curRow=0; this.curCol=3; this.data[this.curRow][this.curCol]=this.dataNext; this.dataNext=this.dataR[parseInt(Math.random()*6)]; this.updateView(); this.timerDown(); }else{ this.state==0; btn.innerHTML="开始游戏"; gameOver.style.display="block"; } },document.getElementById("st").οnclick=function(event){//绑定开始游戏的按钮,开始或者暂停游戏 var src=event.srcElement||event.target; if (src.innerHTML=="开始游戏") { game.timerDown(); game.state=1; src.className="st_end"; src.innerHTML="暂停游戏"; }else{ src.innerHTML="开始游戏"; game.state=0; src.className="st_start"; clearInterval(gameTime); } }document.getElementById('game_again').οnclick=function(event){ gameOver.style.display="none"; game.initialize();}window.οnlοad=function(){ game.initialize(); document.οnkeydοwn=function(){ if(game.state==1){ var event=window.event||arguments[0]; var code=event.keyCode; if(code==37||code==65) game.keyLeft(); if(code==38||code==87) game.suspend();//暂停 if(code==39||code==68) game.keyRight(); if(code==40||code==83) game.keyDown(); } }} |
加入JavaScript 定时器开发俄罗斯方块模式的2048项目
最新推荐文章于 2021-02-26 06:41:26 发布