2048小游戏的实现(PC版)

游戏逻辑

游戏分为两类:一种是基于时间流逝的游戏,一种是基于玩家响应的游戏,2048属于后者,2048是基于用户在电脑上,监听用户按下的上下左右来进行一系列的逻辑,然后实现页面上的变化
keaibaobao

代码的实现

首先是页面的设计,需要有一个标题2048还有score,还有下面的移动方格,方格的底子可以直接写出来,但是由于有数字的格子是会变化的,则需要用js控制动态生成
实现动态生成的部分代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
function updateBoardView(){
$(".number-cell").remove();
for(var i=0;i<4;i++){
for(var j=0;j<4;j++){
$("#grid-container").append('<div class="number-cell" id="number-cell-'+i+'-'+j+'"></div>');
var theNumberCell=$('#number-cell-'+i+'-'+j);
if(board[i][j]==0){
theNumberCell.css('width','0px');
theNumberCell.css('height','0px');
theNumberCell.css('top',getPosTop(i,j)+50);
theNumberCell.css('left',getPosLeft(i,j)+50);
}
else{
theNumberCell.css('width','100px');
theNumberCell.css('height','100px');
theNumberCell.css('top',getPosTop(i,j));
theNumberCell.css('left',getPosLeft(i,j));
theNumberCell.css('background-color',getNumberBackgroundColor(board[i][j]));
theNumberCell.text(board[i][j]);
}
}
}
}

在页面设计好之后就是游戏的重点逻辑的实现
我觉得大概js的实现流程应该是

首先需要实现的是页面刚开始就必须在随机的格子上生成两个随机数字

部分代码,用了js的Math.random()巧妙的随机

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function generateOneNumber(){
if(nospace(board))
{
return false;
}
//随机一个位置
var randx=parseInt(Math.floor(Math.random()*4));
var randy=parseInt(Math.floor(Math.random()*4));
while(true){
if(board[randx][randy]==0){
break;
}
randx=parseInt(Math.floor(Math.random()*4));
randy=parseInt(Math.floor(Math.random()*4));
}
//随机一个数字
var randNumber=Math.random()<0.5?2:4;
//在随机显示随机数字
board[randx][randy]=randNumber;
showNumberWithAnimation(randx,randy,randNumber);
return true;
}

然后是用keydown来检测用户的上下左右键

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$(document).keydown(function(event){
switch(event.keyCode){
case 37: //left
if(moveLeft()){
setTimeout("generateOneNumber()",210);
setTimeout("isgameover()",300);
}
break;
case 38: //up
if(moveUp()){
setTimeout("generateOneNumber()",210);
setTimeout("isgameover()",300);
}
break;
case 39: //right
if(moveRight()){
setTimeout("generateOneNumber()",210);
setTimeout("isgameover()",300);
}
break;
case 40: //down
if(moveDown()){
setTimeout("generateOneNumber()",210);
setTimeout("isgameover()",300);
}
break;
default: //default
break;
}
});

接着编写上下左右键作用下的格子的逻辑变化(以左为例)

这个的实现使整个游戏的关键部分,首先得判断里面的格子是否可以向左边移动,就是判断格子的左边是否有数值为0或者与它相等的数,接着在可以向左移后,从左边开始计数,来判断各行某一列的格子可以移动到哪里,这就又要判断它左边哪里是空或者哪里和它相等,并且中间不能被阻隔,要是满足的话,就直接移过去,将数值改变,最后更新页面变化,包括分数等等

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
function moveLeft(){
if(!canMoveLeft(board))
{
return false;
}
//moveleft
for(var i=0;i<4;i++){
for(var j=1;j<4;j++){
if(board[i][j]!=0){
for(var k=0;k<j;k++){
if(board[i][k]==0&&noBlockHorizontal(i,k,j,board)){
//move
showMoveAnimation(i,j,i,k);
board[i][k]=board[i][j];
board[i][j]=0;
continue;
}
else if(board[i][k]==board[i][j]&&noBlockHorizontal(i,k,j,board)){
//move
showMoveAnimation(i,j,i,k);
//add
board[i][k]+=board[i][j];
board[i][j]=0;
//add score
score+=board[i][k];
updateScore(score);
continue;
}
}
}
}
}
setTimeout("updateBoardView()",200);
return true;}

最后就是判断游戏是否结束了

其实就是增加判断是不是全部格子都有数字了,是不是都不能移动了,就解决了

1
2
3
4
5
6
7
8
function isgameover(){
if(nospace(board)&&nomove(board)){
gameover();
}
}
function gameover(){
alert("gameover!");
}

移动中动画的实现

用的是jquery中的animate()来实现动画,将格子的容器posision: relative,然后让格子容器中中动态生成的格子数字用posision: absolute,然后在js里控制left,top等等来实现动态定位,然后animate的第二个参数来控制动画的时间,便可以顺利完成动画

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
function showNumberWithAnimation(i,j,randNumber){
var numberCell=$('#number-cell-'+i+"-"+j);
numberCell.css('background-color',getNumberBackgroundColor(randNumber));
numberCell.css('color',getNumberColor(randNumber));
numberCell.text(randNumber);
numberCell.animate({
width:"100px",
height:"100px",
top:getPosTop(i,j),
left:getPosLeft(i,j)
},50);
}
function showMoveAnimation(fromx,fromy,tox,toy){
var numberCell=$('#number-cell-'+fromx+'-'+fromy);
numberCell.animate({
top:getPosTop(tox,toy),
left:getPosLeft(tox,toy)
},200);
}

教程

链接:http://www.imooc.com/learn/76


可自由转载、引用,但需署名作者且注明文章出处。