资讯专栏INFORMATION COLUMN

一个自制的2048小游戏(一)

CHENGKANG / 2507人阅读

摘要:导语本次将会从头到尾讲一个游戏的制作过程,中间也会穿插自己的理解一项目结构除了和文件外,分了,以及引入。我们将两个方法写在中是格子之间的距离,是一个小格子的宽度定位完成后我们进行的是数组的初始化,初始化为一个的二维数组,值为。

导语

本次将会从头到尾讲一个2048游戏的制作过程,中间也会穿插自己的理解

一.项目结构

除了html和css文件外,分了main.js,support.js,showanimation.js,以及引入jquery。

html文件




    
    
    
    2048
    


    

我的2048

NewGame

score:0

css文件

html, body, div, span, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
abbr, address, cite, code,
del, dfn, em, img, ins, kbd, q, samp,
small, strong, sub, sup, var,
b, i,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, figcaption, figure, 
footer, header, hgroup, menu, nav, section, summary,
time, mark, audio, video {
    margin:0;
    padding:0;
    border:0;
    outline:0;
    font-size:100%;
    vertical-align:baseline;
    background:transparent;
}
body {
    font-size:12px;
    line-height:120%;
    text-align:center;
    color:#333;
    padding:20px;
    font:12px/1.5 "微软雅黑",tahoma,arial,"Hiragino Sans GB",宋体,sans-serif;
}
table{    border-collapse:collapse;
    border-spacing:0;
}
fieldset,img{border:0;}
address,caption,cite,code,dfn,em,strong,th,var{
    font-style:normal;
    font-weight:normal;
}
img{border:none;}
ol,ul{list-style:none;}
input, select,textarea{
    vertical-align:middle;
    outline:none;
}
textarea{resize:none;}
a{
    color:#333;
    text-decoration:none;
}
a:hover{
    text-decoration:underline;
}
/*清浮*/
.clearfix:after{
    content:"";
    display:block;
    clear:both;
}
.clearfix{zoom:1}

/********************************************/
body{
    background:#978E81;
}
header{
    display:block;
    margin:0 auto;
    width:100%;     /*为了兼容移动端*/
    text-align:center;
}
header h1{
    font-family:Arial;
    font-size:30px;
    font-weight:bold;
}
header #newGameBtn{
    display: block;
    margin:10px auto;
    width:100px;
    padding:5px 10px;
    background-color:#8f7a66;
    font-family:Arial;
    color:white;
    border-radius:10px;
    text-decoration:none;
}
header #newGameBtn:hover{
    background-color:#9f8b77;
}
header p{
    font-family:Arial;
    font-size:25px;
    margin:10px auto;

}
#grid-container{
    width:460px;
    height:460px;
    padding:20px;
    margin:30px auto;
    background-color: #bbada0;
    border-radius:10px;
    position:relative;
}
.grid-cell{
    width:100px;
    height:100px;
    border-radius:12px;
    background-color:#ccc0b3;
    position:absolute;

}
.number-cell{
    border-radius:4px;
    font-family:Arial;
    font-weight:bold;
    font-size:60px;
    line-height:100px;
    text-align:center;
    position:absolute;
}
二.游戏逻辑循序渐进,初始化

首先毫无疑问,需要先初始化游戏,渲染方块之类的。
我们声明两个变量。

var board=new Array();  //存储游戏的数据
var score=0;    //得分

然后定义一个newGame函数,并且等document加载完后调用它

$(document).ready(function(){
    newGame();
})
function newGame(){
    //为移动端初始化宽度
    prepareForMobile();
    //初始化棋盘格
    init();
    //在随机两个格子生成数字
    generateOneNumber();
    generateOneNumber();
}

先忽略那个兼容移动端的,我们根据游戏的逻辑,在newGame里面写了两件事,一个是初始化,一个是随机在格子中生成一个数字,一开始要有两个,所以这个方法调用两遍。下面是init里的内容

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),
                "left":getPosLeft(i,j)
            });
        }
    }
    //初始化board数组
    for(var i=0;i<4;i++){
        board[i]=new Array();
        for(var j=0;j<4;j++){
            board[i][j]=0;

        }
    }
    //有操作,更新界面
    updateBoardView();

    score=0;
    $("#score").text(score);
}

在init初始化里面,我们先做的是给16个背景小方块,因为在css文件里面我们只写了定位方式absolute。
通过遍历得到每个格子,css()方法给他们设置定位。我们将getPosTop,getPosLeft两个方法写在support.js中

//20是格子之间的距离,100是一个小格子的宽度
function getPosTop(i,j){
    var top=20+i*(100+20);
    return top;
}
function getPosLeft(i,j){
    var left=20+j*(100+20);
    return left;
}

定位完成后我们进行的是board数组的初始化,初始化为一个4*4的二维数组,值为false。board初始化完成后我们则根据board来将游戏界面更新。因为后续我们会经常使用到根据board数组更新游戏画面,所以将其写成一个updateBoardView()方便调用

updateBoardView()函数
因为有注释,所以简单说一下。我们是动态加载有数字的方块的,每次更新先将所有的数字方块全部移除,在弄个循环创建它们,并且创建的同时用css设置样式。设置样式时先判断这个位置的board是不是0,为零的话则将宽高设置为0,并将它们的top,left设置在背景方格的中间(这里是为了后面的animate动画是从中间变化)。对于board中有值的,则需要多设置他们的background-color和color。最后将值显示在html中,即theNumberCell.text(board[i][j])

//更新棋盘上显示的方块
function updateBoardView(){
    //如果有number-cell后先删除
    $(".number-cell").remove();
    //遍历格子,改变样式
    for(var i=0;i<4;i++){
        for(var j=0;j<4;j++){
            $("#grid-container").append("
") var theNumberCell=$("#number-cell-"+i+"-"+j); if(board[i][j]==0){ theNumberCell.css({ "width":"0px", "height":"0px", "top":getPosTop(i,j)+50,/*这里是为了把它放中间,动画才好看*/ "left":getPosLeft(i,j)+50 }); }else{ theNumberCell.css({ "width":100+"px", "height":100+"px, "top":getPosTop(i,j), "left":getPosLeft(i,j), "background-color":getNumberBackgroundColor(board[i][j]), "color":getNumberColor(board[i][j]) }); theNumberCell.text(board[i][j]); } } $(".number-cell").css({ "line-height":cellSideLength+"px", "font-size":0.6*cellSideLength+"px" }) } }

数字方块的背景色与前景色的获取
我们将这两个函数写在support.js中,就使用了一个switch,简单明了,不多解释

function getNumberBackgroundColor(number){
    var color="black";
    switch(number){
        case 2:
            color="#eee4da";
            break;
        case 4:
            color="#ede0c8";
            break;
        case 8:
            color="#f2b179";
            break;
        case 16:
            color="#f59563";
            break;
        case 32:
            color="#f67c5f";
            break;
        case 64:
            color="#f65e3b";
            break;
        case 128:
            color="#edcf72";
            break;
        case 256:
            color="#edcc61";
            break;
        case 512:
            color="#9c0";
            break;
        case 1024:
            color="#33b5e5";
            break;
        case 2048:
            color="#09c";
            break;
    }
    return color;
}
function getNumberColor(number){
    if(number<=4){
        return "#776e50";
    }
    return "white";
}
三.初始化最后一步:generateOneNumber()

要想在格子上随机生成一个数字,首先我们需要先确定还有空格子可以生成,没有的话直接返回,所以先判断

//先看有无空格
    if(nospace(board)){
        return false;
    }

将nospace(board)写在support.js中

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

接着要随机生成一个坐标,并且判断这个点是不是为空,不为空则继续随机生成。实在是找不到了,就遍历格子,选第一个为空的格子

//随机生成一个位置
    var randx=parseInt(Math.floor(Math.random()*4));
    var randy=parseInt(Math.floor(Math.random()*4));
//看是不是空格,优化随机
    var times=0;
    while(times<50){
        if(board[randx][randy]==0){
            break;
        }
        //重复
        var randx=parseInt(Math.floor(Math.random()*4));
        var randy=parseInt(Math.floor(Math.random()*4));

        times++;
    }
    if(times==50){
        for(var i=0;i<4;i++){
            for(var j=0;j<4;j++){
                if(board[i][j]==0){
                    randx=i;
                    randy=j;
                }
            }
        }
    }

然后随机生成个2或4 var randNumber=Math.random()<0.65?2:4;
最后将这个数字格子用动画表现出来,并更新board数组

    showNumberWithAnimation(randx,randy,randNumber);
    board[randx][randy]=randNumber;

最后,我们将showNumberWithAnimation()写在showanimation.js中。
主要是通过jq的animate实现动画效果。

function showNumberWithAnimation(i,j,randNumber){
    var numberCell=$("#number-cell-"+i+"-"+j);

    numberCell.css({
        "background-color":getNumberBackgroundColor(randNumber),
        "color":getNumberColor(randNumber)
    });
    
    numberCell.animate({
        width:100,
        height:100,
        top:getPosTop(i,j),
        left:getPosLeft(i,j)
    },50);
    numberCell.text(randNumber);
}

至此,我们的游戏的初始化就完成了,在浏览器里运行一下吧

因为一篇写完的话太长,所以先写到这里,后续的请看接下来的文章,谢谢

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/81646.html

相关文章

  • 自制2048游戏()

    摘要:导语本次将会从头到尾讲一个游戏的制作过程,中间也会穿插自己的理解一项目结构除了和文件外,分了,以及引入。我们将两个方法写在中是格子之间的距离,是一个小格子的宽度定位完成后我们进行的是数组的初始化,初始化为一个的二维数组,值为。 导语 本次将会从头到尾讲一个2048游戏的制作过程,中间也会穿插自己的理解 一.项目结构 除了html和css文件外,分了main.js,support.js,...

    lentrue 评论0 收藏0
  • 自制2048游戏()

    摘要:导语本次将会从头到尾讲一个游戏的制作过程,中间也会穿插自己的理解一项目结构除了和文件外,分了,以及引入。我们将两个方法写在中是格子之间的距离,是一个小格子的宽度定位完成后我们进行的是数组的初始化,初始化为一个的二维数组,值为。 导语 本次将会从头到尾讲一个2048游戏的制作过程,中间也会穿插自己的理解 一.项目结构 除了html和css文件外,分了main.js,support.js,...

    alexnevsky 评论0 收藏0
  • 自制2048游戏(2)

    摘要:所以我们在全局写一个键盘的事件监听函数。一个是移动后应该立马检测游戏有没有结束,如果四个方向都不能移动的话,游戏就应该了。 先声明哈:我做的这个也是跟着被人学习的,写文章是为了复习思路,还有巩固一下。总而言之呢,就是为了多理解思路,多折腾代码。 咳咳,上次我们已经将游戏的初始化全部完成了,包括游戏过程中需要的updataBoardView(); generateOneNumber();...

    dcr309duan 评论0 收藏0
  • 自制2048游戏(2)

    摘要:所以我们在全局写一个键盘的事件监听函数。一个是移动后应该立马检测游戏有没有结束,如果四个方向都不能移动的话,游戏就应该了。 先声明哈:我做的这个也是跟着被人学习的,写文章是为了复习思路,还有巩固一下。总而言之呢,就是为了多理解思路,多折腾代码。 咳咳,上次我们已经将游戏的初始化全部完成了,包括游戏过程中需要的updataBoardView(); generateOneNumber();...

    zhangqh 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<