jQuery翻转拼图游戏
发布在jQuery2015年2月2日view:3927前端开发BrettBatjQuery
在文章任何区域双击击即可给文章添加【评注】!浮到评注点上可以查看详情。

jQuery翻转拼图游戏

一、实验说明

1. 环境介绍

本实验环境采用Ubuntu Linux桌面环境,实验中会用到的程序:

Xfce终端: Linux命令行终端,打开后会进入Bash环境,可以使用Linux命令

Firefox及Opera:浏览器,可以用在需要前端界面的课程里,只需要打开环境里写的HTML/JS页面即可

gvim:非常好用的Vim编辑器,最简单的用法可以参考课程Vim编辑器 其他编辑器:如果Vim不熟悉可以使用gedit或brackets,其中brackets比较适合开发前端代码。

二 、游戏说明

初始时,所有的图块都是橙色。游戏时,每个图块一面橙色,一面蓝色。点击一个图块,这个图块的颜色会翻转,并且,与它邻接的图块的颜色也会翻转。当所有图块颜色都变为蓝色时,游戏过关。

此游戏通过jQueryBootstrap 3实现,UI主要使用了BootstrapModal弹窗,对其他模块涉及较少,所以不需要特别熟悉Bootstrap,游戏逻辑通过jQueryJavaScript实现。

项目效果图如下:

三、HTML结构

game/index.html文件中的代码如下:

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>
            蓝色拼图
        </title>
        <!-- 引入Bootstrap css -->
        <link rel="stylesheet" href="bootstrap/css/bootstrap.css">
        <!-- 引入自定义 css -->
        <link rel="stylesheet" href="css/style.css">

        <!-- 引入jQuery和Bootstrap js -->
        <script src="js/jquery-1.11.1.js"></script>
        <script src="bootstrap/js/bootstrap.js"></script>
        <!-- 引入游戏主程序js -->
        <script src="js/game.js"></script>
    </head>

    <body>
        <div class="container">
            <div class="heading">
                <h1 class="title">
                    jQuery翻转拼图游戏
                </h1>
                <div class="scoresContainer">
                    <!-- 现实当前游戏级别 -->
                    <div class="currLevel">
                        当前级别:<b>1</b>
                    </div>
                </div>
            </div>
            <div class="aboveGame">
                <!-- 游戏按钮 -->
                <a class="reset btn btn-primary" data-toggle="modal" data-target="#restartLevel">重置级别</a>
                <a class="newgame btn btn-primary" data-toggle="modal" data-target="#newGame">重新开始</a>
                <a class="instruct btn btn-primary" data-toggle="modal" data-target="#instructions">玩法说明</a>
            </div>
            <div class="board">
                <!-- 游戏区域 -->
                <div class="gamerow">
                    <div class="gamesquare coord0q0"></div>
                </div>
            </div>
        </div>

        <!-- 游戏玩法 modal -->
        <div class="modal fade" id="instructions" tabindex="-1" role="dialog" aria-hidden="true">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h4 class="modal-title">游戏玩法</h4>
                    </div>
                    <div class="modal-body">
                        <p>如何才算赢:使拼板全部变成蓝色。</p>
                        <p>玩法:每个方块一面橙色,一面蓝色。点击一个方块,这个方块的颜色会翻转,并且,与它邻接的方块的颜色也会翻转。</p>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-primary" data-dismiss="modal">开始游戏</button>
                    </div>
                </div>
            </div>
        </div>

        <!-- 新游戏 modal -->
        <div class="modal fade" id="newGame" tabindex="-1" role="dialog" aria-hidden="true">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h4 class="modal-title">重新开始</h4>
                    </div>
                    <div class="modal-body">
                        <p>你真的想重新开始吗?</p>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-primary" id="newGameConfirm" data-dismiss="modal">开始游戏</button>
                    </div>
                </div>
            </div>
        </div>

        <!-- 重新开始本级别游戏 modal -->
        <div class="modal fade" id="restartLevel" tabindex="-1" role="dialog" aria-hidden="true">
            <div class="modal-dialog">
                <div class="modal-content">
                    <div class="modal-header">
                        <h4 class="modal-title">重新开始本级别游戏</h4>
                    </div>
                    <div class="modal-body">
                        <p>你真的想重新开始吗?</p>
                    </div>
                    <div class="modal-footer">
                        <button type="button" class="btn btn-primary" id="resetLevelConfirm" data-dismiss="modal">重置</button>
                    </div>
                </div>
            </div>
        </div>
    </body>
</html>

BootstrapModal弹窗类似于alert弹窗,但是样式比较美观。

四、CSS样式 游戏的CSS样式比较简单,game/css/style.css中的代码如下所示:

.container {
    width: 600px;
    margin: 0 auto;
}

/* 游戏级别 */
.scoresContainer {
    float: right;
    text-align: right;
    font-size: 18px;
}

/* 游戏按钮 */
.aboveGame:after {
    display: block;
    margin: 20px 0;
    content: "";
    clear: both;
}

/* 游戏区域 */
.board {
    position: absolute;
    background-color: #5f5f5f;
    border-radius: 4px;
}
.gamesquare {
    float: left;
    margin-right: 15px;
    border-radius: 3px;
}

五、游戏逻辑实现 游戏面板中的图块保存为一个二维数组,每个元素的值为0(设置为橙色)或1(设置为蓝色),初始时所有的值均为0。点击图块时,翻转此图块颜色,并找到周围图块坐标,再翻转其颜色,同时改变二元数组中的值。当二维数组中的值变为全1时(即图块颜色全变为蓝色),游戏过关。

游戏逻辑在代码注释中说明,game/js/game.js中的代码如下所示:

function StyleHelper() {
    //
    // 控制游戏区域中的块大小
    //
    this.setGridSize = function(level) {

        var margin = this.getMargin(level);
        var res = ($('.container').width() - margin * level) / (level);

        // 设置块的大小和间距
        $('.gamesquare').css('margin-right', margin);
        $('.gamesquare').css('width', res);
        $('.gamesquare').css('height', res);

        // 设置每行的高度、右边距和下边距
        $('.gamerow').css('height', res);
        $('.gamerow').css('margin-right', margin * (-1));
        $('.gamerow').css('margin-bottom', margin);

        // 设置游戏区域的内边距
        $('.board').css('padding', margin);
        $('.board').css('padding-bottom', 0);
    };

    // 获取边距
    this.getMargin = function(level) {
        if (level <= 6) return 15;
        if (level > 15) return 5;
        return 20 - level;
    };
}

function Game() {
    //
    // 控制游戏
    //
    var self = this;

    // 游戏级别
    this.level = 1;

    // 创建用于控制游戏的对象
    this.gb;
    this.sh = new StyleHelper();

    this.processClick = function(w, h) {
        this.gb.processClick(w, h);
        this.updateCounts();
        if (this.gb.isGameWin()) {
            this.gameEnd();
        }
    }

    // 开始游戏
    this.beginGame = function() {
        self.setupLevel();
    }

    // 游戏结束
    this.gameEnd = function() {
        this.level++;
        this.resetGame();
    }

    // 游戏过关
    this.resetGame = function() {
        $('#levelDescriptor').html("进入级别 " + this.level);
        setTimeout(function() {
            self.setupLevel();
        }, 500);
    }

    // 初始化游戏级别
    this.setupLevel = function() {
        this.gb = new GameBoard(this.level, this.level);
        $('.board').html("");            // 清空游戏面板
        this.gb.populate();              // 重置所有图块为橙色
        self.gb.renderBoard();           // 渲染游戏面板并创建图块
        self.sh.setGridSize(this.level); // 控制游戏区域中的块大小
        self.updateCounts();             // 更新显示当前级别
        self.applyBindings();            // 翻转所点图块周围图块的颜色
    }

    // 显示当前级别
    this.updateCounts = function() {
        $(".currLevel").html("当前级别: <b>" + this.level + "</b>");
    }

    this.applyBindings = function() {
        $('.gamesquare').click(function(){
            // 获取所点击的图块的位置
            var cname = $(this).context.className.split(" ")[1];
            var coord = cname.substring(5).split("q");
            var height = parseInt(coord[1]);
            var width = parseInt(coord[0]);
            self.processClick(width, height); // 翻转所点图块周围图块的颜色
        });
    }

    // 开始新游戏
    this.onNewGameClick = function() {
        this.level = 1;
        this.setupLevel();
    }
}

function GameBoard (wd, hi) {
    //
    // 游戏面板
    //

    // 图块坐标
    this.high = hi - 1;
    this.wide = wd - 1;

    this.count = 0;

    // 横向坐标为 wide,纵向坐标为 high
    //    0 | 1 | 2 | 3 | ....
    //  - - - - - - - - - - - -
       //  0   |   |   |   | 
    //  - - - - - - - - - - - -
    //  1   |   |[2][1]
    //  -
    //  2
    //  :
    //  :
    //

    // 创建图块二维数组
    this.board = new Array(wd);
    for (var i = 0; i <= this.wide; i++) {
        this.board[i] = new Array(hi);
    }

    // 渲染游戏面板并创建图块
    this.renderBoard = function() {
        var s = "";
        for (var j = 0; j <= this.high; j++) {
            s += "<div class='gamerow'>";
            for (var i = 0; i <= this.wide; i++) {
                s += "<div class='gamesquare coord" + i + "q" + j + "'></div>";
            }
            s += "</div>";
        }
        $('.board').html(s);


        for (var i = 0; i <= this.wide; i++) {
            for (var j = 0; j <= this.high; j++) {
                this.processCLickView(i, j);
            }
        }
    }

    this.processClick = function(w, h) {
        //
        // 翻转所点图块周围图块的颜色
        //

        // 找到所点图块周围需要翻转颜色的图块
        var lowx = w - 1;
        var highx = w + 1;
        var lowy = h - 1;
        var highy = h + 1;

        // 检查被点击的图块是否是边缘图块
        if (w == 0) lowx = 0;
        if (w == this.wide) highx = this.wide;
        if (h == 0) lowy = 0;
        if (h == this.high) highy = this.high;

        // 翻转所点图块垂直方向图块
        for (var i = lowy; i <= highy; i++) {
            if (this.board[w][i] == 0) {
                this.board[w][i] = 1;
                this.count++;
            } else {
                this.board[w][i] = 0;
                this.count--;
            }
            this.processCLickView(w, i);
        }

        // 翻转所点图块水平方向的图块
        for (var i = lowx; i <= highx; i++) {
            if (i == w) continue;
            if (this.board[i][h] == 0) {
                this.board[i][h] = 1;
                this.count++;
            } else {
                this.board[i][h] = 0;
                this.count--;
            }
            this.processCLickView(i, h);
        }
    }

    // 翻转图块颜色
    this.processCLickView = function(w, h) {
        var coord = ".coord" + w + "q" + h;
        if (this.board[w][h] == 0) {
            $(coord).css("background-color", "#e8BB39");
        } else {
            $(coord).css("background-color", "#6060e0");
        }
    }

    // 重置所有图块为橙色
    this.populate = function() {
        for (var i = 0; i <= this.wide; i++) {
            for (var j = 0; j <= this.high; j++) {
                this.board[i][j] = 0;
            }
        }
    }

    // 游戏胜利
    this.isGameWin = function() {
        return this.count == (this.wide + 1) * (this.high + 1);
    }
}

// 初始化游戏
$(document).ready(function() {
    // 创建游戏
    var game = new Game();
    // 开始游戏
    game.beginGame();

    // 重置游戏区域图块
    $('#resetLevelConfirm').click(function() {
        game.setupLevel();
    });

    // 开始新游戏
    $('#newGameConfirm').click(function() {
        game.onNewGameClick();
    });
});

看到这里,有没有很想跃跃欲试呢~猛戳这里—为你免费搭建好在线编译环境

评论
发表评论
2年前

不错,学习一下!

WRITTEN BY
实验楼官方微博
“实验楼——www.shiyanlou.com",一个致力于通过动手实践方式提升IT人群(包括拟就业的大学生和从业者)在求职和职业规划中所必备的职业技能的网站!
TA的新浪微博
PUBLISHED IN
jQuery

关于jQuery的一些项目课

我的收藏