js2048小游戏,方格是怎么合并和移动的

index.html

<html>
<head>
    <meta charset="utf-8">
    <title>2048小游戏</title>
    <meta name="renderer" content="webkit">    <!-- 360手机优先使用chrome内核 -->
    <meta name="screen-orientation" content="portrait">  <!-- UC强制竖屏 -->
    <meta name="x5-orientation" content="portrait">  <!-- QQ强制竖屏 -->
    <meta name="browsermode" content="application">  <!-- UC浏览器应用模式 -->
    <!--  <meta name="x5-page-mode" content="app">  -->  <!-- QQ应用模式 -->
    <meta http-equiv="Cache-Control" content="no-siteapp"> <!-- 禁止百度转载页面加载流氓广告 -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> <!-- 优先使用最高IE内核和chrome内核 -->
    <meta name="viewport" content="width=device-width,maximum-scale=1,initial-scale=1.0,user-scalable=no">
    <!--  禁止用户修改网页大小 -->
    <meta name="google" value="notranslate">  <!-- 禁用google翻译网页 -->
    <meta name="robots" content="index,follow">  <!-- 网页搜索引擎方式 -->
    <meta name="apple-mobile-web-app-capable" content="yes" />
    <link href="css/2048.css" rel="stylesheet">
</head>
<body>
    <div class="wrap">
        <div class="score_box">
            <b>score:</b><b id="score"></b>
        </div>
        <div class="cell_wrap">
            <div class="box">
                <div class="cell"></div>
                <div class="cell"></div>
                <div class="cell"></div>
                <div class="cell"></div>
                <div class="cell"></div>
                <div class="cell"></div>
                <div class="cell"></div>
                <div class="cell"></div>
                <div class="cell"></div>
                <div class="cell"></div>
                <div class="cell"></div>
                <div class="cell"></div>
                <div class="cell"></div>
                <div class="cell"></div>
                <div class="cell"></div>
                <div class="cell"></div>
            </div>
        </div>
    </div>
    <script src="js/jquery-3.2.1.js"></script>
    <script src="js/2048.js"></script>
</body>
</html>
<!--
//加排行榜
-->

2048.css

* {
    box-sizing: border-box;
    font-family: Helvetica;
}
body{
    background-color: #444;
}
.wrap{
    overflow:hidden;
    margin-top: 30px;
}
.score_box{
    position: absolute;
    left: -40px;
    text-align: center;
    width: 200px;
    height: 50px;
    color: #e8ddc7;
    background-color: #c26251;
    border-radius: 40px;
    font-size: 20px;
    line-height: 50px;
    border: 3px solid #c18479;
}
.cell_wrap{
    background-color: rgba(0,0,0,0.2);
    width: 35%;
    height: 35vw;
    padding: 2.5%;
    margin: 50px auto 0;
    border-radius: 20px;
}
.box{
    width: 100%;
    height: 30vw;
    position: relative;
}
.cell{
    float: left;
    height: 25%;
    width: 25%;
    box-sizing:border-box;
    border-radius: 15px;
    background-color: rgba(230,190,160,0.2);
    padding: 1.5px;
    background-clip: content-box;
}
.number_cell{
    position: absolute;
    box-sizing:border-box;
    width: 25%;
    height: 25%;
    padding: 1.5px;
    background-clip: content-box;
    left: 0;
    top: 0;
    transition: all 0.2s;
    color: #e8ddc7;
}
.number_cell_con{
    display: block;
          -webkit-border-radius: 15px;
          -moz-border-radius: 15px;
          border-radius: 15px;
    width: 100%;
    height:calc(100% - 5px);
    height:-moz-calc(100% - 5px);
    height:-webkit-calc(100% - 5px);
}
.span_wrap{
    position: absolute;
    float: left;
    top: 26%;
    left: 50%;
}
.number_cell_con span{
    position: relative;
    left: -50%;
    font-size: 65px;
    -webkit-border-radius: 15px;
    -moz-border-radius: 15px;
    border-radius: 15px;
}
/*position数组坐标位置*/
 .pos00{left:0;   top:0;}
 .pos01{left:25%; top:0; }
 .pos02{left:50%; top:0; }
 .pos03{left:75%; top:0; }
 .pos10{left:0;   top:25%; }
 .pos11{left:25%; top:25%; }
 .pos12{left:50%; top:25%; }
 .pos13{left:75%; top:25%; }
 .pos20{left:0;   top:50%; }
 .pos21{left:25%; top:50%; }
 .pos22{left:50%; top:50%; }
 .pos23{left:75%; top:50%; }
 .pos30{left:0;   top:75%; }
 .pos31{left:25%; top:75%; }
 .pos32{left:50%; top:75%; }
 .pos33{left:75%; top:75%; }
/*级别格子样式*/
.n2{
   background: #e5cdc4; color: #846767;
   box-shadow: 0 4px 0 #b6a7a1, 0 5px 2px rgba(0,0,0,.35);
}

.n4{
    background: #d8968a;
    box-shadow:0 4px 0 #ad867f,0 5px 2px rgba(0,0,0,.35);
}
.n8{
    background:#c26251;
    box-shadow:0 4px 0 #924c3f, 0 5px 2px rgba(0,0,0,.35);
}
.n16{
    background:#ef7964;
    box-shadow:0 4px 0 #c36a5a,0 5px 2px rgba(0,0,0,.35);
}
.n32{
    background:#b35c79;
    box-shadow:0 4px 0 #98556c,0 5px 2px rgba(0,0,0,.35);
}
.n64{
    background:#922b19;
    box-shadow:0 4px 0 #662418,0 5px 2px rgba(0,0,0,.35);
}
.n128{
    background:#992f44;
    box-shadow:0 4px 0 #782b3a,0 5px 2px rgba(0,0,0,.35);
}
.n256{
    background:#6a2938;
    box-shadow:0 4px 0 #4e2a32,0 5px 2px rgba(0,0,0,.35);
}
.n512{
    background:#ae3a71;
    box-shadow: 0 4px 0 #7e3356,0 5px 2px rgba(0,0,0,.35);
}
.n1024{
    background:#dc1071;
    box-shadow:0 4px 0 #9b1e59, 0 5px 2px rgba(0,0,0,.35);
}
.n2048{
    background:#e56416;
    box-shadow: 0 4px 0 #a54e19 0 5px 2px rgba(0,0,0,.35);
}
.n4096{
    background:#e8292c;
    box-shadow: 0 4px 0 #b03032,0 5px 2px rgba(0,0,0,.35);
}

.number_cell_con:after{
    font-size: 8px;
    display: block;
    width: 100%;
    text-align: center;
    position: relative;
    top: 70%;
}

.pop_box{
    width: 100%;
    position: fixed;
    top: 0;
    left: 0;
    height: 100%;
    background-color: rgba(35,30,30,0.95);
    z-index: 1;
}
.center_wrap{
    position: absolute;
    float: left;
    left: 50%;
    top: 20%;
}
.pop_head{
    border-radius: 30px 30px 0 0;
    height: 40px;
    background-color: #c26251;
    position: relative;
    top: -60px;
    line-height: 40px;
    color: #e5cdc4;
}
.pop_center{
    position: relative;
    left: -50%;
    z-index: 2;
    width: 40vw;
    height: 300px;
    text-align: center;
    background-color: #e5cdc4;
    border-radius: 30px;
    padding: 60px 0px;
}
.pop_center span{
    font-size: 20px;
    color: #c26251;
}
.closebtn{
    display: block;
    width: 100px;
    height: 60px;
    margin: 40px auto 0;
    border-radius: 20px;
    background-color: #c26251;
    border: 3px solid #c18479;
    color: #e5cdc4;
    font-size: 18px;
    outline: none;
}
.sign{
    float: right;
    margin-top: -80px;
    margin-right: 20px;
    border-radius: 50%;
    overflow: hidden;
    border: 3px solid #c18479;
    display:none;
}
.close{
    position: absolute;
    z-index: 3;
    background-color: #e5cdc4;
    border-radius: 50%;
    border: 2px solid #999;
    color: #777;
    cursor: pointer;
    transform:rotate(45deg);
    -ms-transform:rotate(45deg);     /* IE 9 */
    -moz-transform:rotate(45deg);     /* Firefox */
    -webkit-transform:rotate(45deg); /* Safari 和 Chrome */
    -o-transform:rotate(45deg);
    font-size: 45px;
    line-height: 45px;
    width: 45px;
    height: 45px;
    top: -10px;
    right: -10px;
}
.rank_wrap{
    margin-top: -30px;
}
#rank_cell{
    height: 55px;
    border-bottom: 0.5px dotted #c26251;
    line-height: 55px;
}
.ranking{
    float: left;
    margin-left: 30px;
    font-weight: bold;
    color: #666;
    font-size: 25px;
}
.headpic{
    float: left;
    margin-left: 30px;
    margin-top: 2.5px;
    background-color: #eee;
    width: 50px;
    height: 50px;
}
.name{
    float: left;
    margin-left: 10px;
}
.myscore{
    float: right;
    margin-right: 30px;
    color: #c33c12;
    font-size: 25px;
    font-weight: bold;
}
@media screen and (max-width: 850px){
.cell_wrap{
    width: 55%;
    height: 55vw;
    padding: 2.5%;
}
.box{
    height: 50vw;
}
.sign{
    margin-top: 20px;
}
}
@media screen and (max-width: 780px){
.cell_wrap{
    width: 95%;
    height: 95vw;
    padding: 7.5%;
    margin-top: 70px;
}
.span_wrap{
    top: 22%;
}
.box{
    height: 80vw;
}
.number_cell_con span{
    font-size: 40px;
}
.number_cell_con:after{
    font-size: 15px;
    top: 65%;
}
.pop_center{
    width: 85vw;
    height: 300px;
}
}
@media screen and (max-width: 480px){
.number_cell_con span{
    font-size: 33px;
}
.span_wrap{
    top: 22%;
}
.number_cell_con:after{
    font-size: 11px;
    top: 65%;
}
.pop_center{
    width: 90vw;
    height: 300px;
}
#headpic{
    margin-left: 17px;
}
#name{
    margin-left: 7px;
}
}
@media screen and (max-width: 400px){
.number_cell_con span{
    font-size: 28px;
}
.span_wrap{
    top: 20%;
}
.number_cell_con:after{
    font-size: 11px;
    top: 65%;
}
.pop_center{
    width: 90vw;
    height: 300px;
}
}

2048.js

Game2048.prototype = {
    constructor:Game2048,
    init:function(){
        this.score = 0;
        this.arr = [];
        this.moveAble = false;
        $("#score").html("0");
        $(".number_cell").remove();
        this.creatArr();
    },
    creatArr:function(){
        var i,j;
        for (i = 0; i < 4; i++) {
            this.arr[i] = [];
            for (j = 0; j < 4; j++) {
                this.arr[i][j] = {};
                this.arr[i][j].value = 0;
            }
        }
        var iRandom,jRandom;

        iRandom=getRandom(3);
        jRandom=getRandom(3);
        this.arrValueUpdate(2,iRandom,jRandom);
        this.drawCell(iRandom,jRandom);
    },

    arrValueUpdate:function(num,i,j){
        this.arr[i][j].value = num;
    },
    //画出格子时,是按照css样式来添加的
    drawCell:function(i,j){
        var item = '<div class="number_cell pos'+i+j+'" ><a class="number_cell_con n2"><div class="span_wrap"><span>'
        +this.arr[i][j].value+'</span></div></a></div>';
        $(".box").append(item);
    },
    addEvent:function(){
        var that = this;

        document.onkeydown=function(event){
            var e = event || window.event || arguments.callee.caller.arguments[0];
            var direction = that.direction;
            var keyCode = e.keyCode;
            switch(keyCode){
                case 39:
                that.moveAble = false;
                that.moveRight();
                that.checkLose();
                break;
                case 40:
                that.moveAble = false;
                that.moveDown();
                that.checkLose();
                break;
                case 37:
                that.moveAble = false;
                that.moveLeft();
                that.checkLose();
                break;
                case 38:
                that.moveAble = false;
                that.moveUp();
                that.checkLose();
                break;
            }

        };

    },

    newCell:function(){
        var i,j,len,index;
        var ableArr = [];
        if(this.moveAble != true){
            console.log('不能增加新格子,请尝试其他方向移动!');
            return;
        }
        //将所有的是0的点添加到ableArr数组中,
        for (i = 0; i < 4; i++) {
            for (j = 0; j < 4; j++) {
                if(this.arr[i][j].value == 0){
                    ableArr.push([i,j]);
                }
            }
        }
        len = ableArr.length;
        if(len > 0){
            index = getRandom(len);
            i = ableArr[index][0];
            j = ableArr[index][1];
            this.arrValueUpdate(2,i,j);
            this.drawCell(i,j);
        }
    },

    //向上
    moveUp:function(){
        for(var j = 0 ;j<=3;j++){
            for(var i=0;i<=3;i++){
                var curVal = this.arr[i][j].value;
                if(curVal != 0){
                    var  k = i + 1;
                    while(k<=3){
                        var nextVal = this.arr[k][j].value;
                        if(nextVal != 0){
                            if(nextVal == curVal){
                                this.moveAble = true;
                                this.mergeCells(k,j,i,j);
                            }
                            break;
                        }
                        k++;
                    }
                }
            }
        }

        for(var j = 0 ;j<=3;j++){
            for(var i=0;i<=3;i++){
                var curVal = this.arr[i][j].value;
                if(curVal == 0){
                    var k = i + 1;
                    while(k<=3){
                        var nextVal = this.arr[k][j].value;
                        if(nextVal !=0 ){
                            this.moveAble = true;
                            this.moveCell(k,j,i,j);
                            break;
                        }
                        k++;
                    }
                }
            }

        }
       this.newCell();
    },

    //向下
    moveDown:function(){
        for(var j = 0 ;j<=3;j++){
            for(var i=3;i>=0;i--){
                var curVal = this.arr[i][j].value;
                if(curVal != 0){
                    var  k = i - 1;
                    while(k>=0){
                        var nextVal = this.arr[k][j].value;
                        if(nextVal != 0){
                            if(nextVal == curVal){
                                this.moveAble = true;
                                this.mergeCells(k,j,i,j);
                            }
                            break;
                        }
                        k--;
                    }
                }
            }
        }

        for(var j = 0 ;j<=3;j++){
            for(var i=3;i>=0;i--){
                var curVal = this.arr[i][j].value;
                if(curVal == 0){
                    var k = i - 1;
                    while(k>=0){
                        var nextVal = this.arr[k][j].value;
                        if(nextVal !=0 ){
                            this.moveAble = true;
                            this.moveCell(k,j,i,j);
                            break;
                        }
                        k--;
                    }
                }
            }

        }
       this.newCell();
    },

    //向左
    moveLeft:function(){
        //合并
        //[4,4,8,8] - > [8,0,16,0]
        for(var i = 0 ; i<=3;i++){
            for(var j = 0 ; j<=3; j++){
                var curVal = this.arr[i][j].value;
                if(curVal != 0){
                    var k = j + 1;
                    while(k <= 3){
                        var nextVal = this.arr[i][k].value;
                        if(nextVal!=0){
                            if(nextVal == curVal){
                                this.moveAble = true;
                                this.mergeCells(i,k,i,j);
                            }
                            break;
                        }
                        k++;
                    }
                }
            }
        }

        //移动[8,0,16,0] -> [8,16,0,0]
        for(var i = 0 ; i<=3; i++){
            for(var j=0;j<=3; j++){
                    var  curVal = this.arr[i][j].value;
                    if(curVal == 0 ){
                        var k = j +1;
                        while(k <=3){
                            var nextVal = this.arr[i][k].value;
                            if(nextVal != 0){
                                this.moveCell(i,k,i,j);
                                break;
                            }
                            k++;
                        }
                    }
            }
        }
        this.newCell();
    },

    //向右
    moveRight:function(){
        console.log("右移动");
        //合并[4,4,8,8]  -> [0 , 4 , 0 , 16]
        //合并[4,8,0,8]   ->  [4,0,0,16]
        //合并[8,0,0,8]   -> [0,0,0,16]
        //合并[4,0,4,0]  ->  [0,0,8,0]
        //从右边找到第一个不为0的点,循环取他的下一个不为0的点,判断是不是和当前点的值相等
        //如果相等就合并,并且设置标志位,表示可以移动或者合并,不管相等不相等,都要跳出while循环
        for(var i = 0 ; i<=3;i++){
            for(var j = 3 ; j>=0; j--){
                var curVal = this.arr[i][j].value;
                if(curVal != 0){
                    var k = j - 1;
                    while(k >= 0){
                        var nextVal = this.arr[i][k].value;
                        if(nextVal!=0){
                            if(nextVal == curVal){
                                this.moveAble = true;
                                this.mergeCells(i,k,i,j);
//                                this.arr[i][j] = 2 * this.arr[i][j];
//                                 this.arr[i][k] = 0;
                            }
                            break;
                        }
                        k--;
                    }
                }
            }
        }

        //移动[0,0,4,0]  ->  [0,0,0,4]
        //移动[8,0,0,4]  ->  [0,0,8,4]
        //从右边找到第一个为0的点,循环取他的下一个不为0的点,重新设置两点的值
        for(var i = 0 ; i<=3; i++){
            for(var j=3;j>=0; j--){
                    var  curVal = this.arr[i][j].value;
                    if(curVal == 0 ){
                        var k = j -1;
                        while(k >= 0){
                            var nextVal = this.arr[i][k].value;
                            if(nextVal != 0){
                            //    this.moveAble = true;
                            //    this.arr[i][j].value =  nextVal;
                            //  this.arr[i][k].value = 0;
                                this.moveCell(i,k,i,j);
                                break;
                            }
                            k--;
                        }
                    }
            }
        }

        this.newCell();
    },


    mergeCells:function(i1,j1,i2,j2){
        //合并
        var temp =this.arr[i2][j2].value;
        var temp1 = temp * 2;
        this.moveAble = true;
        this.arr[i2][j2].value = temp1;
        this.arr[i1][j1].value = 0;
        $(".pos"+i2+j2).addClass('toRemove');
        var theDom = $(".pos"+i1+j1).removeClass("pos"+i1+j1).addClass("pos"+i2+j2).find('.number_cell_con');
        setTimeout(function(){
            $(".toRemove").remove();
            theDom.addClass('n'+temp1).removeClass('n'+temp).find('span').html(temp1);
        },200);
        this.score += temp1;
        $("#score").html(this.score);
        if(temp1 == 2048){
            alert('人才啊!祖国的明天就靠你了^o^');
            this.init();
        }
    },

    moveCell:function(i1,j1,i2,j2){
        this.arr[i2][j2].value = this.arr[i1][j1].value;
        this.arr[i1][j1].value = 0;
        this.moveAble = true;
        $(".pos"+i1+j1).removeClass("pos"+i1+j1).addClass("pos"+i2+j2);
    },

    //由于每个方向都有判断游戏是否结束,这里只判断两个方向的即可
    checkLose:function(){
        //判断游戏结束
        var i,j,temp;
        for (i = 0; i < 4; i++) {
            for (j = 0; j < 4; j++) {
                temp = this.arr[i][j].value;
                if(temp == 0){
                    return false;
                }
                if(this.arr[i+1] && (this.arr[i+1][j].value==temp)){
                    return false;
                }
                if((this.arr[i][j+1]!=undefined) && (this.arr[i][j+1].value==temp)){
                    return false;
                }
            }
        }
        alert('革命尚未成功,同志仍需努力^_^');
        this.init();
        return true;
    }
}

//弹出自定义提示窗口start
var showAlert= function(msg, url){
    //弹框存在
    if ( $("#alert_box").length > 0) {
        $('#pop_box_msg').html(msg);
    } else {
        var alertHtml = '<div id="alert_box" class="pop_box">'
                    +            '<div class="center_wrap">'
                    +               '<div class="pop_center">'
                    +            '<div class="pop_head"></div>'
                    +                   '<span id="pop_box_msg">' + msg + '</span>'
                    +                   '<button class="closebtn" onclick="closeAlert()">再来一次</button>'
                    +               '</div>'
                    +           '</div>'
                    +   '</div>';
        $("body").append(alertHtml);
    }
    $("#alert_box").show();
    if(url){
         setTimeout(function(){
            window.location.href = url + '?id=' + 10000*Math.random();
         } , 2000 );
    }
}
//重定义alert
window.alert=showAlert;
//点击遮罩关闭
function closeAlert(){
    $("#alert_box").hide();
}
//弹出自定义提示窗口end



//排行榜start  静静等待后台传数据
function showRanking(){
    if ( $("#ranking_box").length > 0) {
    } else {
        //id名为rank_cell  的div块随用户玩获取成绩而增++
        //id ranking 排名1 2 3...
        //id headpic 用户头像
        //id name 用户名
        //id score 用户成绩
        //
        var rankingHtml = '<div id="ranking_box" class="pop_box">'
                    +            '<div class="center_wrap">'
                    +               '<div class="pop_center">'
                    +                    '<div class="pop_head"><b>排行榜</b></div>'
                    +                    '<div class="rank_wrap">'
                    +                       '<div id="rank_cell">'
                    +                            '<span id="ranking" class="ranking">1</span>'
                    +                            '<img id="headpic" class="headpic">'
                    +                            '<span id="name" class="name">xxx</span>'
                    +                            '<span id="myscore" class="myscore"></span>'
                    +                        '</div>'
                    +                    '</div><div class="close" onclick="closeRanking()">+</div>'
                    +               '</div>'
                    +           '</div>'
                    +    '</div>';
        $("body").append(rankingHtml);
        $("#myscore").html(this.score);
    }
    $("#ranking_box").show();
}
function closeRanking(){
    $("#ranking_box").hide();
}
//排行榜end





function getRandom(n){
    return Math.floor(Math.random()*n)
}


function Game2048(){
    this.addEvent();
}
var g = new Game2048();
g.init();

还要在index.html中引入jquery.js。

02-10 06:06