HTML5开发游戏“2048”

时间:2022-11-17 15:31:48


游戏请访问效果http://1.testyang.sinaapp.com/index.html


HTML的部分:

<!DOCTYPE html>
<html>
<head lang="en">
    <meta charset="UTF-8">
    <title>2048</title>
    <link type="text/css" href="2048.css" rel="stylesheet">
    <script src="jquery-2.1.3.min.js"></script>
    <script src="support2048.js"></script>
    <script src="showAnimation.js"></script>
    <script src="main2048.js"></script>
</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部分

/*{
    margin: 0;
    padding: 0;
}*/
header{
    margin: 0 auto;
    display: block;
    text-align: center;
    width: 500px;
    /*border: 1px solid black;*/
}


header h1{
    font-family: Arial;
    font-weight: bold;
    font-size: 50px;
    margin: 0 auto;
}


header #newGameButton{
    text-decoration: none;
    display: block;
    font-family: Arial;
    margin: 0 auto;
    padding: 10px 10px;
    color: white;
    border-radius: 10px;
    background-color: #8f7a66;
    width: 100px;
}


header #newGameButton:hover{
    background-color: #9f9e35;
}


header p{
    font-family: Arial;
    font-size: 25px;
    margin: 0 auto;
}


#grid-container{
    width: 460px;
    height: 460px;
    padding: 20px;
    /*border: 1px solid black;*/
    margin: 40px auto;
    background-color: #bbada0;
    border-radius: 10px;
    position: relative;
}


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


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

 main.js部分:

/**
 * Created by yangxin on 2015/3/29.
 */
var board = new Array();
var score = 0;
var hasConflicted = new Array();      //为了使一个格子一次碰撞只能一次增加的判断


$(document).ready(function(){
    newGame();
});
function newGame(){                       //考虑两件事:1.初始化棋盘格
    init();                               //随机2个格子生成2和4
    generateOneNumber();                   //随机生成一个数的函数,游戏最初需要两个数所有调用两次
    generateOneNumber();
    score = 0;
    updateScore(score);
}


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();
        hasConflicted[i] = new Array();
        for(var j=0;j<4;j++){
            board[i][j]=0;
            hasConflicted[i][j] = false;
        }
    }
    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('left', getPosLeft(i, j));
                theNumberCell.css('background-color', getNumberBackgroundColor(board[i][j]));
                theNumberCell.css('color', getNumberColor(board[i][j]));
                theNumberCell.text(board[i][j]);
            }
            hasConflicted[i][j] = false;
        }
    }
}


function generateOneNumber(){
    if( noSpace(board))           //格子已满,产生新数失败
        return false;
    var randx = parseInt(Math.floor(Math.random()*4)); //parseInt是把浮点数转换为整形,randx是个坐标
    var randy = parseInt(Math.floor(Math.random()*4));
    while(true){                                        //死循环,知道找到空格子(即等于0)跳出循环
        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;   //随机产生2和4(真TM机智)
    board[randx][randy] = randNumber;
    showNumberWithAnimation(randx,randy,randNumber);  //通知前端产生新数并显示


    return true;           //格子未满,可以产生新数
}


$(document).keydown(function(event){
    switch (event.keyCode){
        case 37: //left
            if(moveLeft()){
                generateOneNumber();
                isGameOver();
            }
            break;
        case 38://up
            if(moveUp()){
                generateOneNumber();
                isGameOver();
            }
            break;
        case 39://right
            if(moveRight()){
                generateOneNumber();
                isGameOver();
            }
            break;
        case 40://down
            if(moveDown()){
                generateOneNumber();
                isGameOver();
            }
            break;
    }
});


function isGameOver(){
    if( noSpace(board) && noMove(board))
        gameOver();
}


function gameOver(){
    alert("NO ZUO NO DIE! 傻逼了吧!");
}


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) && !hasConflicted[i][k]){
                        //move
                        showMoveAnimation(i, j, i, k);
                        //add
                        board[i][k] += board[i][j];
                        board[i][j] = 0;
                        //addScore;
                        score += board[i][k];
                        updateScore(score);
                        hasConflicted[i][k] = true;


                        continue;
                    }
                }
            }
        }
    setTimeout("updateBoardView()",200);
    return true;
}


function moveUp(){
    if( !canMoveUp(board) ){
        return false;
    }
    //moveup
    for(var j=0; j<4; j++)
        for(var i=1; i<4; i++){
            if(board[i][j] != 0){
                for(var k=0; k<i; k++){
                    if(board[k][j] == 0 && noBlockVertical(j, k, i, board)){
                        //move
                        showMoveAnimation(i, j, k, j);
                        board[k][j] =  board[i][j];
                        board[i][j] = 0;
                        continue;
                    }
                    else if(board[k][j] == board[i][j] && noBlockVertical(j, k, i, board) && !hasConflicted[k][j]){
                        //move
                        //add
                        showMoveAnimation(i, j, k, j);
                        board[k][j] *= 2;
                        board[i][j] = 0;
                        //addScore
                        score += board[k][j];
                        updateScore(score);
                        hasConflicted[k][j] = true;
                        continue;
                    }


                }
            }
        }
    setTimeout("updateBoardView()",200);
    return true;
}


function moveRight(){
    if( !canMoveRight(board) ){           //先判断能不能移动
        return false;
    }
    //moveright
    for(var i=0; i<4; i++)
        for(var j=2; j>=0; j--){
            if(board[i][j] != 0){
                for(var k=3; k>j; k--){
                    if( board[i][k] == 0 && noBlockHorizontal(i, j, k, 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, j, k, board) && !hasConflicted[i][k] ){
                        //move
                        //add
                        showMoveAnimation(i, j, i, k);
                        board[i][k] *= 2;
                        board[i][j] = 0;
                        //addScore
                        score += board[i][k];
                        updateScore(score);
                        hasConflicted[i][k] = true;


                        continue;
                    }
                }
            }
        }


    setTimeout("updateBoardView()",200);
    return true;
}


function moveDown(){
    if( !canMoveDown(board) ){
        return false;
    }
    //movedown
    for(var j=0; j<4; j++)
        for(var i=2; i>=0; i--){
            if(board[i][j] != 0){
                for(var k=3; k>i; k--){
                    if(board[k][j] == 0 && noBlockVertical(j, i, k, board)){
                        //move
                        showMoveAnimation(i, j, k, j);
                        board[k][j] = board[i][j];
                        board[i][j] = 0;




                        continue;
                    }
                    else if(board[k][j] == board[i][j] && noBlockVertical(j, i, k, board) && !hasConflicted[k][j]){
                        //move
                        //add
                        showMoveAnimation(i, j, k, j);
                        board[k][j] *= 2;
                        board[i][j] = 0;
                        //addScore
                        score += board[k][j];
                        updateScore(score);
                        hasConflicted[k][j];


                        continue;
                    }
                }
            }
        }
    setTimeout("updateBoardView()",200);
    return true;
}


support.js部分:

/**
 * Created by yangxin on 2015/3/29.
 */
function getPosTop(i,j){
    return 20+120*i;
}


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 "#59563"; 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 8192: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;    //返回false说明还有空的格子
        }
    return true;               //如果返回true说明16个空格都满了


}


function canMoveLeft(board){
    for(var i=0; i<4; i++)
        for(var j=1; j<4; j++){
            if(board[i][j] !== 0){
                if(board[i][j-1]==0 || board[i][j-1]==board[i][j])
                    return true;
            }


        }
    return false;
}


function canMoveRight(board){
    for(var i=0; i<4; i++)
        for(var j=2; j>=0; j--){
            if(board[i][j] != 0){
                if(board[i][j+1] == 0 || board[i][j+1] == board[i][j])
                    return true;
            }
        }
    return false;
}


function noBlockHorizontal(row, col1, col2, board){
    for(var i=col1+1; i<col2; i++){
        if(board[row][i] != 0){
            return false;
        }
    }
    return true;
}


function canMoveUp(board){
    for(var j=0; j<4; j++)
        for(var i=1; i<4; i++){
            if(board[i][j] != 0){
                if(board[i-1][j] == 0 || board[i-1][j] == board[i][j]){
                    return true;
                }
            }
        }
    return false;
}


function canMoveDown(board){
    for(var j=0; j<4; j++)
        for(var i=2; i>=0; i--){
            if(board[i][j] != 0){
                if(board[i+1][j] == 0 || board[i+1][j] == board[i][j])
                    return true;
            }
        }
    return false;
}


function noBlockVertical(col, row1, row2, board){
    for(var i=row1+1; i<row2; i++){
        if(board[i][col] != 0){
            return false;
        }
    }
    return true;
}


function noMove (board) {
    if( !canMoveDown(board) && !canMoveUp(board) && !canMoveLeft(board) && !canMoveRight(board))
        return true;  //不能上下左右的移动
    return false;
}


showAnimation.js部分:


/**
 * Created by yangxin on 2015/3/29.
 */
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);
}


function updateScore( score ){
    $( '#score').text (score);
}


完整开发视频出处:http://www.imooc.com/learn/76