zoukankan      html  css  js  c++  java
  • 基于jQuery的2048小游戏设计(网页版)

    上周模仿一个2048小游戏,总结一下自己在编写代码的时候遇到的一些坑。

    游戏规则:省略,我想大部分人都玩过,不写了

    源码地址:https://github.com/xinhua6/2048game.git

    文件结构:

    2048.css  编写游戏样式

    index.html  页面结构内容

    main2048.js 游戏主逻辑文件,包含初始化格子,随机生成2个数字

    game.js 游戏交互逻辑文件,主要包含上下左右移动逻辑

    support.js 游戏的基础逻辑文件,提供游戏结束判断,数字移动的前提条件判断

    animation.js 游戏的动画逻辑文件,包含数字格子的颜色设计,移动的动画设计

    ps:这里我只是写一下注意点,不会把详细的代码都罗列出来,要想看详细的编写代码,请到源码地址:https://github.com/xinhua6/2048game.git 下载。

    1.在css样式中没有对每个格子的位置进行设置,利用循环来初始化每个格子。

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

     main.js中

     1 function init() {
     2     for (var i =0;i<4;i++){
     3         board[i] = new Array();
     4         for (var j= 0;j<4;j++){
     5             board[i][j] = 0;
     6             //通过双重遍历获取每个格子的元素
     7             var eachGrid = $('#grid-cell-'+i+'-'+j);
     8             //通过getPostTop()获取每个格子距离顶部的高度和到左端的距离
     9             //eachGrid.css({"top":getPos(i),"left":getPos(j)});无效
    10             eachGrid.css('top',getPos(i));
    11             eachGrid.css('left',getPos(j));
    12         }
    13     }
    14     updateBoardView();
    15 }

    support.js文件中

    //格子到顶部/左端的距离
    function getPos(num) {
        return 20+num*120;
    }

    注意:在这里子元素grid-cell的position要设置为absolute,父元素container的position要设置为relative,这样才可以基于父元素框向左向下偏移位置,否则子元素grid-cell会基于整个屏幕来向左,向下移动

    2.随机生成两个数字。(2或者4)。这里三步走:生成一个随机的位置;生成一个随机的数字;在随机的位置上显示随机的数字

    function generateOneNumber() {
        //生成一个随机位置的随机数
        //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 = Math.floor(Math.random()*4);
            var randy = 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);
    }

    3.这里就向左移来讲解,其余方向的移动逻辑都是类似的。

    开始是判断是否能够左移,左移的条件是当前数字所在的格子左边相邻的值为0或者值相等。该函数返回的是boolean值

    function canMoveLeft(board) {
        for (var i =0;i<4;i++){
            for (var j = 1;j<4;j++){
                if (board[i][j] != 0){
                    //当前数字格的左边前一个值为0或者当前数字格的值与左边第一个数字格的值相等
                    if (board[i][j-1] == 0 || board[i][j-1] == board[i][j]){
                        return true;
                    }
                }
            }
        }
        return false;
    }

    紧接着如果判断成立,则进行左移。左移的时候要进行判断,相邻的格子数是否相等,相等要相加,同时成绩上要增加分数;否则,当前的格子的数字移动到相应格子。

    function moveLeft() {
        //moveLeft 左移要注意不是第一列,第一列无法左移
        for (var i = 0; i < 4; i++){
            for (var j = 1; j < 4; j++){
                if (Number(board[i][j]) != 0){
                    for (var k = 0;k<j;k++){
                        if (board[i][k]==0 && noBoardHorizontal(i,k,j,board)) {
                            //向左移动
                            showMoveAnimation(i,j,i,k);
                            board[i][k] = board[i][j];
                            board[i][j] = 0;
                            continue;
                        }else if (board[i][k] == board[i][j] && noBoardHorizontal(i,k,j,board)){
                            //向左移动
                            showMoveAnimation(i,j,i,k);
                            board[i][k] += board[i][j];
                            score += board[i][k];
                            updateScore(score);
                            board[i][j] = 0;
                        }
                    } 
    
                }
            }
        }
        //设置刷新时间是为了让运动的动画走完再进行跟新数字格,否则数字格运动的动画将会被打断
        setTimeout(updateBoardView(),200);
    }
    //判断当前数字格水平的数字格是否值为0
    function noBoardHorizontal(row,col1,col2,board) {
        for (var i = col1 + 1; i< col2;i++){
            if (board[row][i]!=0){
                return false;
            }
        }
        return true;
    }
    function showMoveAnimation(fromx,fromy,tox,toy) {
        //获取当前的数字格的元素
        var numberCell = $("#number-cell-"+ fromx + "-" + fromy);
        numberCell.animate({
            top:getPos(tox),
            left:getPos(toy),
        },200)

    4.最后判断是否游戏结束,以及分数跟新

    //跟新分数
    function updateScore(num){
        $('#score').text(num);
    }
    
    //判断游戏是否结束
    function isgameover(board){
        if (!canMoveLeft(board) && !canMoveUp(board) && !canMoveRight(board) && !canMoveDown(board)) {
            alert("游戏结束,请重新开始游戏!");
        }
    }

    总结:

    这个游戏编程总体不难,只要理清思路,就可以写了,最后调试的时候,比较注意的是:设置setTimeOut时,要注意最后的时间设置。

  • 相关阅读:
    Chrome 已经原生支持截图功能,还可以给节点截图!
    【promise| async/await】代码的控制力
    移动端各种分辨率手机屏幕----适配方法集锦
    Web Storage事件无法触发
    【php学习】图片处理三步走
    NYOJ 36 LCS(最长公共子序列)
    NYOJ 252 01串 普通dp
    NYOJ 18 The Triangle 填表法,普通dp
    NYOJ-171 聪明的kk 填表法 普通dp
    NYOJ17 最长单调递增子序列 线性dp
  • 原文地址:https://www.cnblogs.com/lanhuo666/p/9933267.html
Copyright © 2011-2022 走看看