JQuery初体验-JavaScript实现2048小游戏PC端

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/funkstill/article/details/85089320

目录

效果图

游戏页面

游戏页面样式

游戏基础逻辑

游戏动画逻辑

游戏主逻辑

游戏交互逻辑


效果图:

游戏页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>2048</title>
    <link href="2048.css" rel="stylesheet" type="text/css">
    <script type="text/javascript" src="jquery-1.11.0.js"></script>
    <script type="text/javascript" src="support.js"></script>
    <script type="text/javascript" src="animation.js"></script>
    <script type="text/javascript" src="main.js"></script>
    <script type="text/javascript" src="game.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>

游戏页面样式:

/*设置游戏整体位置*/
header{
    display: block;
    margin: 0 auto;
    width: 100%;
    text-align: center;
}
header h1{
    font-family: Arial;
    font-size: 40px;
    font-weight: bold;
}
/* 设置按钮样式*/
header #newgamebutton{
    display: block;
    margin: 20px auto;

    width: 100px;
    padding: 10px 10px;
    background-color: #8f7a66;
    font-family: "Arial";
    color: white;
    border-radius: 10px;
    text-decoration: none;
}
/*按钮hover响应*/
header #newgamebutton:hover{
    background-color: #9f8b77;
}
/*分数样式*/
header  p{
    font-family: Arial;
    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;
}
/*设置小方块样式*/
.grid-cell{
    width: 100px;
    height: 100px;
    border-radius: 6px;
    background-color: #ccc0b3;
    position: absolute;
}
/*设置数字方格的字体样式*/
.number-cell{
    border-radius: 6px;

    font-family: Arial;
    font-weight: bold;
    font-size: 60px;
    line-height: 100px;
    text-align: center;

    position: absolute;
}
.gameover{
    display: block;
    margin: 0 auto;
    width: 500px;
    text-align: center;
    vertical-align: middle;

    position: absolute;
}
.gameover p{
    font-family: Arial;
    font-size: 50px;
    color: white;
    margin: 20px auto;

    margin-top: 150px;
}
.gameover span {
    font-family: Arial;
    font-size: 50px;
    color: white;
    margin: 20px auto;
}

#restartgamebutton {
    display: block;
    margin: 20px auto;

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

    font-family: Arial;
    font-size: 30px;
    color: white;

    border-radius: 10px;

    text-decoration: none;
}

#restartgamebutton:hover {
    background-color: #9f8b77;
}

游戏基础逻辑:

/**
 * Created by cell on 2018/12/18.
 */
//设置小格子顶端距离
function getPosTop(dx,dy) {
    return 20+dx*120;
}
//设置小格子左端距离
function getPosLeft(dx,dy) {
    return 20+dy*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 8192:return "#93c";break;
        default:return "#222";break;
    }
}
function getNumberColor(number) {
    if (number<=4){
        return "#776e65";
    }
    return "white";
}
//判断是否可以移动
function canMoveLeft(board) {
    for(var r=0;r<4;r++){
        for(var c=1;c<4;c++){//第一列无法左移
            //当前小格有值
            if(board[r][c]!=0){
                //前面为空或者前面的值和当前值相等
                if(board[r][c-1]==0||board[r][c-1]==board[r][c]){
                    return true;
                }
            }
        }
    }
    return false;
}
function canMoveRight(board) {
    for(var r=0;r<4;r++){
        for(var c=2;c>=0;c--){//倒数第一列无法右移
            //当前小格有值
            if(board[r][c]!=0){
                //右面为空或者右面的值和当前值相等
                if(board[r][c+1]==0||board[r][c+1]==board[r][c]){
                    return true;
                }
            }
        }
    }
    return false;
}
function canMoveUp(board) {
    for(var r=1;r<4;r++){//第一行无法上移
        for(var c=0;c<4;c++){
            //当前小格有值
            if(board[r][c]!=0){
                //上面为空或者上面的值和当前值相等
                if(board[r-1][c]==0||board[r-1][c]==board[r][c]){
                    return true;
                }
            }
        }
    }
    return false;
}
function canMoveDown(board) {
    for(var r=2;r>=0;r--){//最下面一行无法下移
        for(var c=0;c<4;c++){
            //当前小格有值
            if(board[r][c]!=0){
                //下面为空或者下面的值和当前值相等
                if(board[r+1][c]==0||board[r+1][c]==board[r][c]){
                    return true;
                }
            }
        }
    }
    return false;
}
//判断中间是否有空格
function noBlokHorizontalCol(r,temp,c,board) {
    //判断第r行的第c列和第temp列之间是否有空格,temp<c即temp在左
    for (var i = temp+1;i<c;i++){
        if(board[r][i]!=0){
            return false;
        }
    }
    return true;
}
function noBlokHorizontalRow(r1,r2,c,board) {
    //判断(r1,c)和(r2,c)之间是否有空格
    for (var i=r1+1;i<r2;i++){
        if(board[i][c]!=0){
            return false;
        }
    }
    return true;
}
//判断是否有未赋值的块
function noSpace(board) {
    for(var r=0;r<4;r++){
        for(var c=0;c<4;c++){
            if(board[r][c]==0){
                return false;
            }
        }
    }
    return true;
}
function noMove(board) {
    if(canMoveUp(board)||canMoveDown(board)||canMoveLeft(board)||canMoveRight(board)){
        return false;
    }
    return true;
}

游戏动画逻辑:

/**
 * Created by cell on 2018/12/18.
 */
function ShowNumberWithAnimation(x,y,number) {
    //获取当前的数字格
    var numberCell = $("#number-cell-"+x+"-"+y);
    //设置当前数字格的背景和前景色及数字值
    numberCell.css("background-color",getNumberBackgroundColor(number));
    numberCell.css("color",getNumberColor(number));
    numberCell.text(number);
    //设置当前数字格显示动画
    numberCell.animate({
        width:"100px",
        height:"100px",
        top:getPosTop(x,y),
        left:getPosLeft(x,y)
    },50);
}
function showMoveAnimation(origx,origy,tagtx,tagty) {
    //获取当前数字格内容
    var numberCell = $("#number-cell-"+origx+"-"+origy);
    numberCell.animate({
        top:getPosTop(tagtx,tagty),
        left:getPosLeft(tagtx,tagty)
    },200);
}
function updateScore(score) {
    $("#score").text(score);
}

游戏主逻辑:

/**
 * Created by cell on 2018/12/18.
 */
//创建数组
var board = new Array();
var hasConfilcted = new Array();
var score = 0;
$(function () {
    newgame()
});
function newgame() {
    //棋盘初始化
    init();
    //在随机两个格子生成数字
    generateOneNumber();
    generateOneNumber();
}
function restartgame() {
    $("#gameover").remove();
    updateScore(0);
    newgame();
}
function init() {
    //UI初始化
    for (var row=0;row<4;row++){
        for (var column=0;column<4;column++){
            var griCell = $("#grid-cell-"+row+"-"+column);
            //设置每个格子顶端距离
            griCell.css("top",getPosTop(row,column));
            //设置每个格子左端距离
            griCell.css("left",getPosLeft(row,column));
        }
    }
    //数据初始化
    for (var row=0;row<4;row++){
        //创建二维数组
        board[row]=new Array();
        hasConfilcted[row]=new Array();
        for (var column=0;column<4;column++){
            //每个小格子初始值为0
            board[row][column]=0;
            hasConfilcted[row][column]=false;
        }
    }
    updateBoardView();
    score = 0;
}
//刷新页面
function updateBoardView() {
    //清除已有的
    $(".number-cell").remove();
    //添加新的
    for (var row=0;row<4;row++){
        for(var column=0;column<4;column++){
            $("#grid-container").append("<div class='number-cell' id='number-cell-"+row+"-"+column+"'></div>");
            var numberCell = $("#number-cell-"+row+"-"+column);
            //如果棋盘数字的值都为0,设置数字格高度宽度为0
            if(board[row][column]==0){
                numberCell.css("width","0px");
                numberCell.css("height","0px");
                numberCell.css("top",getPosTop(row,column)+50);
                numberCell.css("left",getPosLeft(row,column)+50);
            }
            //如果不为0,设置高宽、背景色及数字值
            else{
                numberCell.css("width","100px");
                numberCell.css("height","100px");
                numberCell.css("top",getPosTop(row,column));
                numberCell.css("left",getPosLeft(row,column));
                numberCell.css("background-color",getNumberBackgroundColor(board[row][column]));
                numberCell.css("color",getNumberColor(board[row][column]));
                if(board[row][column]>999){//当数字大于四位数时按位数缩小字体
                    numberCell.css("font-size",(3*60/(board[row][column].toString().length)).toString()+"px");
                }else {
                    numberCell.css("font-size","60px");
                }
                numberCell.text(board[row][column]);
            }
            hasConfilcted[row][column]=false;
        }
    }
}
function generateOneNumber() {
    if(noSpace(board)){
        return false;
    }
    //生成随机位置随机数字
    //1.生成随机位置
    var randx=parseInt(Math.floor(Math.random()*4));
    var randy=parseInt(Math.floor(Math.random()*4));
    while (true){
        //若当前格子值为0,则可以生成
        if(board[randx][randy]==0){
            break;
        }
        //否则重新寻找空格子
        var randx=parseInt(Math.floor(Math.random()*4));
        var randy=parseInt(Math.floor(Math.random()*4));
    }
    //2.生成随机数字(需求规定:只可以生成2或4)
    var randNumber = Math.random()<0.5?2:4;
    //3.将生成的数字显示到生成的位置
    board[randx][randy]=randNumber;
    ShowNumberWithAnimation(randx,randy,randNumber);

    return true;
}

游戏交互逻辑:

/**
 * Created by cell on 2018/12/18.
 */
//keydown事件
$(document).keydown(function (event) {
    switch (event.keyCode){
        case 65://left
        case 37:
            /*
            * moveLeft()
            * 完成向左移动逻辑
            * 返回值为Boolean类型,判断是否可以向左移动
            * */
            if(moveLeft()){
                setTimeout("generateOneNumber();",210)//填充空位
                setTimeout("isGameOver();",300)//判断是否无空格
            }
            break;
        case 87://up
        case 38:
            if(moveUp()){
                setTimeout("generateOneNumber();",210)//填充空位
                setTimeout("isGameOver();",300)//判断是否无空格
            }
            break;
        case 68://right
        case 38:
            if(moveRight()){
                setTimeout("generateOneNumber();",210)//填充空位
                setTimeout("isGameOver();",300)//判断是否无空格
            }
            break;
        case 83://down
        case 40:
            if(moveDown()){
                setTimeout("generateOneNumber();",210)//填充空位
                setTimeout("isGameOver();",300)//判断是否无空格
            }
            break;
        default:
            break;
    }
})
function moveLeft() {
    //返回值为Boolean类型,判断是否可以向左移动
    if(!canMoveLeft(board)){
        return false;
    }
    //向左移动逻辑
    for(var r=0;r<4;r++){
        for(var c=1;c<4;c++){//第一列无法左移
            //当前小格有值
            if(board[r][c]!=0){
                //向左移动
                for(var temp=0;temp<c;temp++){//c列左边的列
                    if(board[r][temp]==0&&noBlokHorizontalCol(r,temp,c,board)){
                        //当前遍历值为0且与目标块之间无有值块
                        showMoveAnimation(r,c,r,temp);
                        //当前值传递到目标块
                        board[r][temp]=board[r][c];
                        board[r][c]=0;

                        continue;
                    }else if(board[r][temp]==board[r][c]
                            &&noBlokHorizontalCol(r,temp,c,board)
                            &&!hasConfilcted[r][temp]){
                        //当前遍历值和目标块的值相等,且之间无有值的块
                        showMoveAnimation(r,c,r,temp);
                        //当前值加到目标块
                        board[r][temp]+=board[r][c];
                        board[r][c]=0;
                        //更新分数
                        score+=board[r][temp];
                        updateScore(score);

                        hasConfilcted[r][temp]=true;
                        continue;
                    }
                }
            }
        }
    }
    setTimeout("updateBoardView();",200);
    return true;
}
function moveRight() {
    if(!canMoveRight(board)){
        return false;
    }
    for(var r=0;r<4;r++){
        for(var c=2;c>=0;c--){
            if(board[r][c]!=0){
                for(var temp=3;temp>c;temp--){
                    if(board[r][temp]==0&&noBlokHorizontalCol(r,temp,c,board)){
                        showMoveAnimation(r,c,r,temp);
                        board[r][temp]=board[r][c];
                        board[r][c]=0;
                        continue;
                    }else if(board[r][temp]==board[r][c]
                        &&noBlokHorizontalCol(r,temp,c,board)
                        &&!hasConfilcted[r][temp]){
                        showMoveAnimation(r,c,r,temp);
                        board[r][temp]+=board[r][c];
                        board[r][c]=0;
                        score+=board[r][temp];
                        updateScore(score);
                        hasConfilcted[r][temp]=true;
                        continue;
                    }
                }
            }
        }
    }
    setTimeout("updateBoardView();",200);
    return true;
}
function moveUp() {
    if(!canMoveUp(board)){
        return false;
    }
    for(var r=1;r<4;r++){
        for(var c=0;c<4;c++){
            if(board[r][c]!=0){
                for(var temp=0;temp<r;temp++){
                    if(board[temp][c]==0&&noBlokHorizontalRow(temp,r,c,board)){
                        showMoveAnimation(r,c,temp,c);
                        board[temp][c]=board[r][c];
                        board[r][c]=0;
                        continue;
                    }else if(board[temp][c]==board[r][c]
                        &&noBlokHorizontalRow(temp,r,c,board)
                        &&!hasConfilcted[temp][c]){
                        showMoveAnimation(r,c,temp,c);
                        board[temp][c]+=board[r][c];
                        board[r][c]=0;
                        score+=board[temp][c];
                        updateScore(score);
                        hasConfilcted[temp][c]=true;
                        continue;
                    }
                }
            }
        }
    }
    setTimeout("updateBoardView();",200);
    return true;
}
function moveDown() {
    if(!canMoveDown(board)){
        return false;
    }
    for(var r=2;r>=0;r--){
        for(var c=0;c<4;c++){
            if(board[r][c]!=0){
                for(var temp=3;temp>r;temp--){
                    if(board[temp][c]==0&&noBlokHorizontalRow(temp,r,c,board)){
                        showMoveAnimation(r,c,temp,c);
                        board[temp][c]=board[r][c];
                        board[r][c]=0;
                        continue;
                    }else if(board[temp][c]==board[r][c]
                        &&noBlokHorizontalRow(temp,r,c,board)
                        &&!hasConfilcted[temp][c]){
                        showMoveAnimation(r,c,temp,c);
                        board[temp][c]+=board[r][c];
                        board[r][c]=0;
                        score+=board[temp][c];
                        updateScore(score);
                        hasConfilcted[temp][c]=true;
                        continue;
                    }
                }
            }
        }
    }
    setTimeout("updateBoardView();",200);
    return true;
}
//判读游戏结束条件
function isGameOver() {
    //没有未赋值的块并且不能继续滑动合并
    if(noSpace(board)&&noMove(board)){
        gameover();
    }
}
//游戏结束响应
function gameover() {
    alert("Game Over!");
    $("#grid-container").append(
        "<div id='gameover' class='gameover'>" +
            "<p>本次得分</p>" +
            "<span>" +score+ "</span>" +
             "<a href='javascript:restartgame();' id='restartgamebutton'>Restart</a>"  +
        "</div>");
    var gameover = $("#gameover");
    gameover.css("width","500px");
    gameover.css("height","500px");
    gameover.css("background-color","rgba(0,0,0,0.5)");
}

猜你喜欢

转载自blog.csdn.net/funkstill/article/details/85089320