2048小游戏——网页版(基础篇)

来源:互联网 发布:硬盘raw格式化软件 编辑:程序博客网 时间:2024/04/30 09:17

这是一个用js写的网页版2048游戏,实现2048游戏的基本功能。


比如:绘制网格、随机生成数字、动画移动数字、累计分数、重置游戏等。


同时,笔者在自己的理解下,对代码进行了非常详细的注释,相信有一点点基础的开发人员都能迅速看懂,快来试试吧!


当然,大神还可以在这个文档的基础上对游戏进行改进,比如添加一些更炫酷的动画效果,自定义数字、文字、图像等。


该项目的所有代码已上传,欢迎下载:点击打开链接


当然你也可以查看本文接下来给你展示的部分代码。


该项目主要由以下几个部分组成:


2048.css :是关于字体、表格、排版样式的定义文档。包括字体、表格、数字的大小、颜色、边距等。

index.html :是该网页的主界面设计文档。包括设置标题文字、分数、棋盘格,以及导入会用到的css文件、js文件。

main2048.js :是该游戏的主要功能的实现文档。包括开始游戏、初始化数据、随机生成数字、键盘上下左右的响应、数字移动的变化、游戏结束。

showAnimation.js :是该游戏的动画显示的实现文档。包括数字显示的动画、数字移动的动画、分数刷新显示。

support2048.js :是该游戏的一些小细节处理的实现文档。可以理解为对 main2048.js 中常用函数的封装,方便多次调用此类函数。包括获取单元格的坐标、设置数字的颜色、判断格子是否为空、判断数字能否移动等。

----------------------------------------------------------------------------------    具体代码实现如下    -------------------------------------------------------------------------------------------------------------------

2048.css

header {    display: block;    margin: 0 auto;    width: 500px;    text-align: center;}header h1 {    font-family: Arial;    font-size: 60px;    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;}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;}


index.html 
<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>2048</title>    <link rel="stylesheet" type="text/css" href="2048.css"/>    <script type="text/javascript" src="http://libs.baidu.com/jquery/1.9.0/jquery.min.js"></script>    <script type="text/javascript" src="support2048.js"></script>    <script type="text/javascript" src="showAnimation.js"></script>    <script type="text/javascript" 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>

main2048.js

/** * Created by Kay on 2016/3/7. */// --------------------------------------------------------------------------------------------------------------------var board = new Array();var score = 0;var hasConflicted = new Array();// 用来判断每个格子是否已经发生过碰撞,从而避免一下子加好几个格子$(document).ready(function () {    newgame();});function newgame() {    // 初始化棋盘格    init();    // 在随机两个格子生成数字    generateOneNumber();    generateOneNumber();}// --------------------------------------------------------------------------------------------------------------------/* *  1、初始化棋盘格 gridCell *  2、初始化二维数组 用于存储数据 board *  3、初始化数据 清零 updateBoardView(); */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', getPosition(i));            gridCell.css('left', getPosition(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();    score = 0;    updateScore(score);}// --------------------------------------------------------------------------------------------------------------------// 初始化数据,就是将数据可视化!根据board[i][j]存的数值来画图!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", getPosition(i) + 50);                theNumberCell.css("left", getPosition(j) + 50);            } else {                theNumberCell.css('width', '100px');                theNumberCell.css('height', '100px');                theNumberCell.css('top', getPosition(i));                theNumberCell.css('left', getPosition(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));    var randy = parseInt(Math.floor(Math.random() * 4));    // 设置一个时间参数,50次以内系统还未生成一个空位置,那么就进行人工找一个空位置    var times = 0;    while (times < 50) {        if (board[randx][randy] == 0)            break;        randx = parseInt(Math.floor(Math.random() * 4));        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;                }            }    }    // 随机一个数字    var randNumber = Math.random() < 0.5 ? 2 : 4;    // 在随机位置显示随机数字    board[randx][randy] = randNumber;    showNumberWithAnimation(randx, randy, randNumber);    return true;}// --------------------------------------------------------------------------------------------------------------------// 判断键盘的响应时间 上下左右$(document).keydown(function (event) {    event.preventDefault();    switch (event.keyCode) {        case 37: // left 向左移动            if (moveLeft()) {                setTimeout("generateOneNumber()", 210);                setTimeout("isgameover()", 300);            }            ;            break;        case 38: // up 向上移动            if (moveUp()) {                setTimeout("generateOneNumber()", 210);                setTimeout("isgameover()", 300);            }            ;            break;        case 39: // right 向右移动            if (moveRight()) {                setTimeout("generateOneNumber()", 210);                setTimeout("isgameover()", 300);            }            ;            break;        case 40: // down 向下移动            if (moveDown()) {                setTimeout("generateOneNumber()", 210);                setTimeout("isgameover()", 300);            }            ;            break;        default: // default            break;    }});// --------------------------------------------------------------------------------------------------------------------// 向左移动function moveLeft() {    // 1、首先,判断能否向左移动    if (!canMoveLeft(board))        return false;    /*2、如果可以向左移动:     *   ①当前的数字是否为0,不为0则进行左移 board[i][j] != 0     *   ②如果左侧为空格子,则数字进行一个移位操作 board[i][k] == 0     *   ③如果左侧有数字且不相等,则数字还是进行移位操作 noBlockHorizontal     *   ④如果左侧有数字且相等,则数字进行相加操作 board[i][k] == board[i][j]     */    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;                        //add score                        score += board[i][k];                        updateScore(score);                        hasConflicted[i][k] = true;                        continue;                    }                }            }        }    // 3、初始化数据 updateBoardView()    // 为显示动画效果,设置该函数的等待时间200毫秒    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                        showMoveAnimation(i, j, k, j);                        //add                        board[k][j] += board[i][j];                        board[i][j] = 0;                        //add score                        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                        showMoveAnimation(i, j, i, k);                        //add                        board[i][k] += board[i][j];                        board[i][j] = 0;                        //add score                        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                        showMoveAnimation(i, j, k, j);                        //add                        board[k][j] += board[i][j];                        board[i][j] = 0;                        //add score                        score += board[k][j];                        updateScore(score);                        hasConflicted[k][j] = true;                        continue;                    }                }            }        }    setTimeout("updateBoardView()", 200);    return true;}// --------------------------------------------------------------------------------------------------------------------// 游戏结束function isgameover() {    if (nospace(board) && nomove(board)) {        gameover();    }}function gameover() {    alert("游戏结束!您的得分为:" + score);}<strong></strong>


showAnimation.js

/** * Created by Kay on 2016/3/7. */// --------------------------------------------------------------------------------------------------------------------/* 显示数字的动画: * 在 x=i,y=j 的位置上 显示数字 该数字的值 = randNumber * 在这个显示过程中 设置了一个50毫秒的动画效果 */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: getPosition(i),        left: getPosition(j)    }, 50);}// --------------------------------------------------------------------------------------------------------------------/* 移动数字的动画: * 从 x=fromx,y=fromy 的位置 移动到  x=tox,y=toy 的位置 * 在这个显示过程中 设置了一个200毫秒的动画效果 */function  showMoveAnimation(fromx, fromy, tox, toy){    var numberCell = $('#number-cell-' + fromx + '-' +fromy );    numberCell.animate({        top:getPosition( tox ),        left:getPosition( toy )    },200);}// --------------------------------------------------------------------------------------------------------------------// 分数刷新显示,此处未设置动画function  updateScore(score){    $('#score').text(score);}


support2048.js

/** * Created by Kay on 2016/3/7. */// --------------------------------------------------------------------------------------------------------------------// 获取每个单元格的坐标function getPosition( pos ) {    return 20 + pos * 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 3192:            return "#93c";            break;    }    return "black";}// --------------------------------------------------------------------------------------------------------------------// 设置数字的颜色:2和4的颜色都为#776e65,其它数字的颜色为白色function getNumberColor(number) {    if ( number <= 4 )        return "#776e65";    return "white";}// --------------------------------------------------------------------------------------------------------------------// 判断当前格子是否有数字 即判断是不是一个“非空(nospace)”的格子function nospace(board) {    for ( var i = 0; i < 4; i++ )        for ( var j = 0; j < 4; j++ )            if ( board[i][j] == 0 ) // 如果没有数字,返回false                return false;    // 如果有数字,返回true    return true;}// --------------------------------------------------------------------------------------------------------------------/* 判断能否向左移动 * 1、只需要判断每一行的后3列格子即可。 * 2、可以移动的条件是: *   ①当前格子有数字,即 board[i][j] != 0 *   ②左侧格子没有数字,即 (board[i][j - 1] == 0 *   ③左侧格子和当前格子数字相同,即 board[i][j - 1] == board[i][j] */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 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 canMoveRight(board) {    for (var i = 0; i < 4; i++)        for (var j = 0; j < 3; j++)            if (board[i][j] != 0)                if (board[i][j+1] == 0 || board[i][j+1] == board[i][j])                    return true;    return false;}function canMoveDown(board) {    for (var j = 0; j < 4; j++)        for (var i = 0; i < 3; i++)            if (board[i][j] != 0)                if (board[i + 1][j] == 0 || board[i + 1][j] == board[i][j])                    return true;    return false;}// --------------------------------------------------------------------------------------------------------------------// 判断水平方向是否可移动,即水平方向的两个目标格子之间没有其他数字 noBlockHorizontalfunction noBlockHorizontal(row, col1, col2, board) {    for (var i = col1 + 1; i < col2; i++)        if (board[row][i] != 0) // 如果在这两者之间的其它格子有数字,返回false            return false;    // 如果两者之间没数字,返回true    return true;}// --------------------------------------------------------------------------------------------------------------------// 判断垂直方向是否可移动,即垂直方向的两个目标格子之间没有其他数字 noBlockHorizontalfunction noBlockVertical(col, row1, row2, board) {    for (var i = row1 + 1; i < row2; i++)        if (board[i][col] != 0) // 如果在这两者之间的其它格子有数字,返回false            return false;    // 如果两者之间没数字,返回true    return true;}function nomove( board ){    if( canMoveLeft( board ) ||        canMoveRight( board ) ||        canMoveUp( board ) ||        canMoveDown( board ) )        return false;    return true;}

接下来,可能会再出个 “2048小游戏——网页版(提高篇)”。主要是想对该游戏进行一个改进,2048的数字换成图片、支持手机端的滑动操作等。

看心情吧。


0 0
原创粉丝点击