html+css+js适合前端小白的实战全解(超详细)——2048小游戏(三)

续上一小节,我们回到newgame()这个函数,我们之前只做了init()内函数,相当于一个初始化操作,现在,我们需要在随机两个两个生成数字。
随机生成数字在这个游戏里会经常出现,用户移动一步,也会产生一个随机数字。
我们在newgame()函数里,声明一个generateOneNumber()函数,来随机在16个格子里找出没有数字的格子,随机生成一个数字2或4。
因为newgame()函数里,起始时,生成了2个随机数字,于是我们要调用2次。

2.31 generateOneNumber()函数

在main2048.js里,我们再去定义这个函数。我们先判断什么时候还能生成数字,就是4×4这16个格子里还有空间,就可以。
我们定义一个nospace()函数,传入当前board的值,表示16个格子里已经没有空间了,返回false,否则返回true.

function generateOneNumber(){
     if(nospace(board)){
         return false;
     }
     return true;
 }

2.32 nospace()函数

我们将nospace(board)函数放在【support2048.js】里
先遍历board数组,如果board[i][j]存在为0的元素,则还有空间,返回false。否则返回true。

 function nospace(board) { 
     for(var i = 0; i < 4; i++)
        for(var j = 0; j < 4; j++)
            if(board[i][j]==0)
                return false;

    return true;
  }

下面我们回到generateOneNumber(),如果有空间的话,我们怎么生成数呢?

1. 需要寻找一个空位
我们使用Math里面的random()函数,Math.random() 是算法中常用的函数,其作用是返回0~1之间浮点数,而我们的位置 i 和 j 都是0123,我们如何转换成0到4之间的随机数呢?

很简单,我们把生成的0~1之间的浮点数×4,这样就能产生0到4之间的浮点数。
为了能获得0到4之间的整数,我们使用Math.floor()函数其作用是返回小于或等于一个给定数字的最大整数,比如1.4就返回整数1, 0.693就返回0。这样我们就能生成0123这四个随机数。

但是这样我们得到的数仍是一个浮点类型的,我们需要把随机数用作坐标,所以必须是整形的,我们再嵌套一个parseInt()函数来将生成的随机数强制转换成整形。

var randx = parseInt(Math.floor(Math.random()*4));
var randy = parseInt(Math.floor(Math.random()*4));

但此时这个数字我们仍不能用,因为如果这个位置原本有数字,我们不能使用,我们还需要判断该位置是否为0。

我们可以使用一个死循环,找每一个位置上的randx和randy是不是为0。为0我们就可以break结束循环,找到该坐标。

    while(true){
        if(board[randx][randy]==0) break;

        randx = parseInt(Math.floor(Math.random()*4));
        randy = parseInt(Math.floor(Math.random()*4));
    }

2. 需要随机一个数字
下面我们随机生成一个数字,我们可以巧妙利用Math.random(),50%生成2, 50%生成4,我们可以判断生成的数与0.5比大小,生成2或4

var randNumber = Math.random() > 0.5?2:4;

3. 在随机位置显示随机数字

board[randx][randy] = randNumber;

然后我们需要通知前端显示这个randNumber,在2048游戏中,显示这一步是有一个动画效果的,我们新声明一个函数showNumberWithAnimation(randx,randy,randNumber)

2.33 showNumberWithAnimation()函数

在【showanimation2048.js】里,我们需要调用numberCell。
numberCell 从0到有数字, 那文字颜色和背景颜色都要根据数字来决定。之前已经写过 getNumberBackgroundColor()getNumberColor(),需要在这里调用。

var numberCell = $('#number-cell-'+i+'-'+j);
    numberCell.css('background-color',getNumberBackgroundColor(randNumber));
    numberCell.css('color',getNumberColor(randNumber));
    numberCell.text(randNumber);

动画部分,我们使用jquery的animate()函数来完成。

  1. 宽高改变,从width=0和height=0转换成width=100px, height=100px。
  2. 位置改变,从grid-cell的中心转成与grid-cell相同大小
    numberCell.animate({
        width:'100px',
        height:'100px',
        top:getPosTop(i,j),
        left:getPosLeft(i,j)
    },50);

第二个参数50,是指50ms完成该动画。
至此 showNumberWithAnimation()函数已经完成。

此时我们可以测试一下我们的代码,可以发现初始时生成了随机两个数,点击New Game,又生成了不同的两个数
在这里插入图片描述

这一小节结束,放上我们目前为止所有的代码检查一下!

2048.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>2048</title>
    <script type="text/javascript" src="jquery-3.4.1.min.js"></script>
    <script type="text/javascript" src="main2048.js"></script>
    <script type="text/javascript" src="showanimation2048.js"></script>
    <script type="text/javascript" src="support2048.js"></script>
    <link rel="stylesheet" type="text/css" href="2048.css">
</head>
<body>
    <header>
        <h1>2048</h1>
        <a href="javascript:newgame();" id="newgamebutton">New Game</a>
        <p>score:<span id="score">0</span></p>
    </header>

    <div id="grid-container">
        <div class="grid-cell" id="grid-cell-0-0"></div>
        <div class="grid-cell" id="grid-cell-0-1"></div>
        <div class="grid-cell" id="grid-cell-0-2"></div>
        <div class="grid-cell" id="grid-cell-0-3"></div>

        <div class="grid-cell" id="grid-cell-1-0"></div>
        <div class="grid-cell" id="grid-cell-1-1"></div>
        <div class="grid-cell" id="grid-cell-1-2"></div>
        <div class="grid-cell" id="grid-cell-1-3"></div>

        <div class="grid-cell" id="grid-cell-2-0"></div>
        <div class="grid-cell" id="grid-cell-2-1"></div>
        <div class="grid-cell" id="grid-cell-2-2"></div>
        <div class="grid-cell" id="grid-cell-2-3"></div>

        <div class="grid-cell" id="grid-cell-3-0"></div>
        <div class="grid-cell" id="grid-cell-3-1"></div>
        <div class="grid-cell" id="grid-cell-3-2"></div>
        <div class="grid-cell" id="grid-cell-3-3"></div>
    </div>
</body>
</html>

2048.css

body{
    font-family: Arial;
}

header{
    display: block;
    margin: 0 auto;
    width: 500px;
    text-align: center;
}

header h1{
    font-size: 60px;
    font-weight: bold;
}

header #newgamebutton{
    display: block;
    margin: 20px auto;

    width: 100px;
    padding: 10px 10px;
    background-color: #8f7a66;
    color: #fff;

    border-radius: 10px;
    text-decoration: none;
}

header #newgamebutton:hover{
    background-color: #9f8b77;
}

header p{
    font-size: 25px;
    margin: 20px auto;
}


#grid-container{
    width: 460px;
    height: 460px;
    padding: 20px;

    margin: 50px auto;
    background-color: #bbada0;

    border-radius: 10px;
    position: relative;
    left: 0;
    top:0;
}

.grid-cell{
    width: 100px;
    height: 100px;
    border-radius: 6px;
    background: #ccc0b3;

    position: absolute;
}


.number-cell{
    border-radius: 6px;
    
    font-weight: bold;
    font-size: 60px;
    line-height: 100px;
    text-align: center;
    
    position: absolute;
}

main2048.js

var board = new Array();
var score = 0;

$(document).ready(function() { 
    newgame();
 });

function newgame() { 

    // 1.初始化棋盘
    init();

    // 2.随机两个格子生成数字
    generateOneNumber();
    generateOneNumber();

  }

function init() { 
    for(var i = 0; i < 4; i++)
        for(var j = 0; j < 4; j++)
        {
            var gridCell = $("#grid-cell-"+i+"-"+j);
            gridCell.css('top', getPosTop(i,j));
            gridCell.css('left', getPosLeft(i,j));
        }

    for(var i = 0; i < 4; i++){
        board[i] = new Array();
            for(var j = 0; j < 4; j++){
                board[i][j] = 0;
            }     
   }

   updateBoardView();
}

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('top',getPosTop(i,j));
                theNumberCell.css('background-color',getNumberBackgroundColor(board[i][j]));
                theNumberCell.css('color',getNumberColor(board[i][j]));
                theNumberCell.text(board[i][j]);
            }
        }   
 }

 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;
 }

support2048.js

function getPosTop(i,j){
    return 20 + i*120;
}
function getPosLeft(i,j){
    return 20 + j*120;
}

function getNumberBackgroundColor(number){
    switch(number){
        case 2:return "#eee4da"; break; 
        case 4:return "#ede0c8"; break; 
        case 8:return "#f2b179"; break; 
        case 16:return "#f59563"; break; 
        case 32:return "#f67c5f"; break; 
        case 64:return "#f65e3b"; break; 
        case 128:return "#edcf72"; break; 
        case 256:return "#edcc61"; break; 
        case 512:return "#9c0"; break; 
        case 1024:return "#33b5e5"; break; 
        case 2048:return "#09c"; break; 
        case 4096:return "#a6c"; break; 
        case 28192:return "#93c"; break; 
    }
    return "black";
}

function getNumberColor(number) { 
    if(number <= 4)
        return "#776e65";

    return "white";
 }

 function nospace(board) { 
     for(var i = 0; i < 4; i++)
        for(var j = 0; j < 4; j++)
            if(board[i][j]==0)
                return false;
    
    return true;
  }

showanimation2048.js

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);
}

猜你喜欢

转载自blog.csdn.net/weixin_41306215/article/details/107610326