zoukankan      html  css  js  c++  java
  • HTML5+JS 《五子飞》游戏实现(三)页面和棋盘棋子

    前面两节,我们已经对《五子飞》有个初步的认识,对走棋路线也有了基本的了解,现在里沃特继续跟大家分享HTML页面,另外把棋盘棋子也画出来。

    演示地址:http://www.lyout.com/projects/fiveflychess/FiveflyChess3.htm

    HTML页面非常简单:

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>五子飞</title>
        <style type="text/css">
        .fiveflychess {
            margin-left: auto;
            margin-right: auto;
        }
        </style>
        <script language="javascript" type="text/javascript" src="http://common.cnblogs.com/script/jquery.js"></script>
        <script language="javascript" type="text/javascript" src="canvas.js"></script>
        <script language="javascript" type="text/javascript" src="FiveflyChess.js"></script>
    </head>
    <body style="text-align: center;">
        <canvas id="fiveflychess" class="fiveflychess" width="800" height="600">
            Your brower is not support canvas!
        </canvas>
        <script language="javascript" type="text/javascript">
            $(document).ready(function () {
                var chesspanel = $("#fiveflychess");
    
                var ffc = new GameChess();
                ffc.start(chesspanel);
            });
        </script>
    </body>
    </html>

    其中,jquery.js 被调用的函数不多,完全可以自行实现,但为了省时间,就用它处理了。canvas.js 是一个简单的在 html5 Canvas 上画图的类,实现了画圆、线、文字、圆角矩形、填充矩形、空心矩形、球等一些比较基础的函数。有时候没必要做一个小游戏还加载一些大型的框架:

    var Canvas = {
        // 画圆弧路径
        drawArc: function (c, x, y, r, a1, a2, anticlockwise) {
            c.arc(x, y, r, a1 * Math.PI / 180, a2 * Math.PI / 180, anticlockwise);
        },
        // 画两条射线相切的的圆弧
        drawArcTo: function (c, x1, y1, x2, y2, o1, o2, r) {
            c.moveTo(x1, y1);
            c.arcTo(o1, o2, x2, y2, r);
        },
        // 画线
        drawLine: function (c, strokestyle, lw, x1, y1, x2, y2) {
            c.strokeStyle = strokestyle;
            c.lineWidth = lw;
            c.beginPath();
            c.moveTo(x1, y1);
            c.lineTo(x2, y2);
            c.closePath();
            c.stroke();
        },
        // 画文字
        drawText: function (c, text, x, y, fillstyle) {
            c.fillStyle = fillstyle;
            c.fillText(text, x, y);
        },
        // 画个圆角矩形
        drawRoundRect: function (c, strokestyle, x1, y1, x2, y2, r, fillstyle) {
            c.strokeStyle = strokestyle;
            c.fillStyle = fillstyle;
            c.beginPath();
            c.moveTo(x1 + r, y1);
            c.lineTo(x2 - r, y1);
            c.quadraticCurveTo(x2, y1, x2, y1 + r);
            c.lineTo(x2, y2 - r);
            c.quadraticCurveTo(x2, y2, x2 - r, y2);
            c.lineTo(x1 + r, y2);
            c.quadraticCurveTo(x1, y2, x1, y2 - r);
            c.lineTo(x1, y1 + r);
            c.quadraticCurveTo(x1, y1, x1 + r, y1);
            c.fill();
            c.stroke();
        },
        // 画填充矩形
        drawFillRect: function (c, strokestyle, lw, x1, y1, x2, y2, fillstyle) {
            c.fillStyle = fillstyle;
            c.fillRect(x1, y1, x2 - x1, y2 - y1);
            if (lw > 0) this.drawRect(c, strokestyle, lw, x1, y1, x2, y2);
        },
        // 画空心矩形
        drawRect: function (c, strokestyle, lw, x1, y1, x2, y2) {
            c.strokeStyle = strokestyle;
            c.lineWidth = lw;
            c.beginPath();
            c.moveTo(x1 - lw / 2, y1);
            c.lineTo(x2, y1);
            c.lineTo(x2, y2);
            c.lineTo(x1, y2);
            c.lineTo(x1, y1 - lw / 2);
            c.stroke();
        },
        // 画线
        drawLine: function (c, strokestyle, lw, x1, y1, x2, y2) {
            c.strokeStyle = strokestyle;
            c.lineWidth = lw;
            c.beginPath();
            c.moveTo(x1, y1);
            c.lineTo(x2, y2);
            c.closePath();
            c.stroke();
        },
        // 画只有边的球
        drawCircleStroke: function (c, strokestyle, lw, x, y, r) {
            c.strokeStyle = strokestyle;
            c.lineWidth = lw;
            c.beginPath();
            this.drawArc(c, x, y, r, 0, 360, true);
            c.closePath();
            c.stroke();
        },
        // 画填充有边的球
        drawCircleFill: function (c, strokestyle, lw, x, y, r, fillstyle) {
            c.strokeStyle = strokestyle;
            c.lineWidth = lw;
            c.fillStyle = fillstyle;
            c.beginPath();
            this.drawArc(c, x, y, r, 0, 360, true);
            c.closePath();
            c.fill();
            c.stroke();
        },
        // 画球
        drawBall: function (c, x, y, r, fillstyle) {
            c.fillStyle = fillstyle;
            c.beginPath();
            this.drawArc(c, x, y, r, 0, 360, true);
            c.closePath();
            c.fill();
        },
        // 判断点是否在某个区块内
        inRegion: function (p, r) {
            if (p[0] > r[0] && p[0] < r[2] && p[1] > r[1] && p[1] < r[3]) {
                return true;
            } else {
                return false;
            }
        },
        //判断两个矩形对象是否重合
        coincide: function (a, b) {
            if (this.inRegion([a[0], a[1]], b)) return true;
            if (this.inRegion([a[0], a[3]], b)) return true;
            if (this.inRegion([a[2], a[1]], b)) return true;
            if (this.inRegion([a[2], a[3]], b)) return true;
    
            if (this.inRegion([b[0], b[1]], a)) return true;
            if (this.inRegion([b[0], b[3]], a)) return true;
            if (this.inRegion([b[2], b[1]], a)) return true;
            if (this.inRegion([b[2], b[3]], a)) return true;
            return false;
        },
        getContext: function (el) {
            if (!(el && el.length && el.length > 0)) { return null; }
    
            return (function () {
                if (el[0].getContext) { var c = el[0].getContext("2d"); if (c) { return c; } }
                return null;
            })();
        }
    };
     

    现在我们看看怎么把棋盘和棋子画出来:

    /// <reference path="../common/jquery.js" />
    /// <reference path="../common/canvas.js" />
    
    var Player = { A: 0, B: 1, None: -1 };
    function Size(w, h) {
        this.w = w;
        this.h = h;
    }
    function Point(x, y, index) {
        this.x = x;
        this.y = y;
        this.index = index;
    }
    function Bounds(x, y, w, h) {
        this.x = x;
        this.y = y;
        this.w = w;
        this.h = h;
    
        this.toArray = function () {
            return [this.x, this.y, this.w, this.h];
        };
    
        this.toArrayXY = function () {
            return [this.x, this.y, this.x + this.w, this.y + this.h];
        };
    }
    function Chess(player) {
        this.player = player;
        this.point = new Point(-1, -1, -1);
        this.bounds = new Bounds(-1, -1, -1, -1);
        this.moveTo = function (chess) {
            chess.player = this.player;
            this.player = Player.None;
        };
    }
    function GameChess() {
        // 可走的路线
        this.lines = [
            [ 0,  1,  2,  3,  4],
            [ 5,  6,  7,  8,  9],
            [10, 11, 12, 13, 14],
            [15, 16, 17, 18, 19],
            [20, 21, 22, 23, 24],
            [ 0,  5, 10, 15, 20],
            [ 1,  6, 11, 16, 21],
            [ 2,  7, 12, 17, 22],
            [ 3,  8, 13, 18, 23],
            [ 4,  9, 14, 19, 24],
            [ 0,  6, 12, 18, 24],
            [ 4,  8, 12, 16, 20],
            [ 2,  6, 10],
            [ 2,  8, 14],
            [10, 16, 22],
            [14, 18, 22]
        ];              
        this.cpc = 0;                       // 单方初始棋子数
        this.ctc = 0;                       // 棋子可走的点数
        this.chesses = [];                  // 棋子(包含空棋子)
        this.chessarray = null;             // 多选棋子
        this.chessreplace = [];             // 被替换的棋子
        this.chesssize = new Size(32, 32);  // 棋子大小
        this.panel = null;                  // 作画的画板
        this.width = 0;                     // 画板宽度
        this.height = 0;                    // 画板高度
        this.chessblack = new Image();      // 黑棋子图片
        this.chesswhite = new Image();      // 白棋子图片
        this.imagestate = 0;                // 棋子图片加载状态
        this.imagetimer = null;             // 判断棋子图片加载的时钟
        this.currentIndex = -1;             // 当前棋子
        this.currentPlayer = Player.B;      // 当前玩家是哪一方
        this.computerPlayer = Player.A;     // 电脑是哪一方
        this.computerUsed = true;           // 是否与电脑对弈
        this.player = Player.B;             // 轮到谁玩了
        this.timetimer = null;              // 倒计时
        this.timecount = 30;                // 每步30秒
        this.winner = Player.None;          // 谁赢了
        this.isover = false;                // 是否结束了
    
        // 初始配置
        this.init = function () {
            this.chesses = [];
            this.cpc = 5;
            this.ctc = Math.pow(this.cpc, 2);
    
            var i;
            // 分配棋子
            for (i = 0; i < this.cpc; i++) {
                this.chesses.push(new Chess(Player.A));
            }
            for (i = this.cpc; i < this.ctc - this.cpc; i++) {
                this.chesses.push(new Chess(Player.None));
            }
            for (i = this.ctc - this.cpc; i < this.ctc; i++) {
                this.chesses.push(new Chess(Player.B));
            }
            for (i = 0; i < this.ctc; i++) {
                this.chesses[i].point = new Point(i % this.cpc, parseInt(i / this.cpc, 10), i);
            }
        };
        this.play = function () {
            this.replay();
        };
        // 重玩,重置所有棋子
        this.replay = function () {
            this.isover = false;
            this.changePlayer();
    
            var i;
            // 分配棋子
            for (i = 0; i < this.cpc; i++) {
                this.chesses[i].player = Player.A;
            }
            for (i = this.cpc; i < this.ctc - this.cpc; i++) {
                this.chesses[i].player = Player.None;
            }
            for (i = this.ctc - this.cpc; i < this.ctc; i++) {
                this.chesses[i].player = Player.B;
            }
            for (i = 0; i < this.ctc; i++) {
                this.chesses[i].point = new Point(i % this.cpc, parseInt(i / this.cpc, 10), i);
            }
        };
        this.changePlayer = function () {
            this.timecount = 30;
        };
        // 获取索引号
        this.getIndex = function (pDest, pSrc) {
            var t1 = typeof (pDest), t2 = typeof (pSrc);
            var i1 = -1, i2 = -1;
            if ((t1 == "number") && (t2 == "number")) {
                i1 = pDest; i2 = pSrc;
            } else if ((t1 == "object") && (t2 == "object")) {
                i1 = pDest.index || -1; i2 = pSrc.index || -1;
            }
            if (i1 >= 0 && i1 < this.ctc) {
                return { destIndex: i1, srcIndex: i2 };
            }
            return false;
        };
        // 得到对方是哪个玩家
        this.getAnotherPlayer = function (player) {
            return player == Player.A ? Player.B : Player.A;
        };
        this.paint = function () {
            var i;
            var cw = this.width > this.height ? this.height : this.width;
    
            // 画棋盘
            Canvas.drawRoundRect(this.panel, "#225C21", 0, 0, this.width, this.height, 5, "#225C21");
            Canvas.drawFillRect(this.panel, "#000000", 1, 20, 20, cw - 20, cw - 20, "#E8BC7D");
            Canvas.drawRect(this.panel, "#000000", 5, 50, 50, cw - 50, cw - 50);
    
            var startp = 58;
            var w = cw - startp * 2;
            var h = cw - startp * 2;
            for (i = 0; i < this.cpc; i++) {
                Canvas.drawLine(this.panel, "#000000", 1, startp + i * w / (this.cpc - 1), startp, startp + i * w / (this.cpc - 1), cw - startp);
            }
            for (i = 0; i < this.cpc; i++) {
                Canvas.drawLine(this.panel, "#000000", 1, startp, startp + i * h / (this.cpc - 1), cw - startp, startp + i * h / (this.cpc - 1));
            }
            // 长对角线
            Canvas.drawLine(this.panel, "#000000", 1, startp, startp, cw - startp, cw - startp);
            Canvas.drawLine(this.panel, "#000000", 1, startp, cw - startp, cw - startp, startp);
            // 短对角线
            Canvas.drawLine(this.panel, "#000000", 1, startp, startp + (this.cpc - 1) / 2 * h / (this.cpc - 1), startp + (this.cpc - 1) / 2 * w / (this.cpc - 1), startp);
            Canvas.drawLine(this.panel, "#000000", 1, startp, startp + (this.cpc - 1) / 2 * h / (this.cpc - 1), startp + (this.cpc - 1) / 2 * w / (this.cpc - 1), cw - startp);
            Canvas.drawLine(this.panel, "#000000", 1, startp + (this.cpc - 1) / 2 * w / (this.cpc - 1), cw - startp, cw - startp, startp + (this.cpc - 1) / 2 * h / (this.cpc - 1));
            Canvas.drawLine(this.panel, "#000000", 1, startp + (this.cpc - 1) / 2 * w / (this.cpc - 1), startp, cw - startp, startp + (this.cpc - 1) / 2 * h / (this.cpc - 1));
    
            Canvas.drawRect(this.panel, "#000000", 2, startp, startp, cw - startp, cw - startp);
    
            if (this.imagestate == 2) {
                if (this.imagetimer) {
                    clearInterval(this.imagetimer);
                    this.imagetimer = null;
                }
    
                var b;
                // 画棋子
                for (i = 0; i < this.chesses.length; i++) {
                    this.chesses[i].bounds = new Bounds(startp + this.chesses[i].point.x * w / (this.cpc - 1) - this.chesssize.w / 2, startp + this.chesses[i].point.y * h / (this.cpc - 1) - this.chesssize.h / 2, this.chesssize.w, this.chesssize.h);
                    switch (this.chesses[i].player) {
                        case Player.A:
                            this.panel.drawImage(this.chessblack, this.chesses[i].bounds.x, this.chesses[i].bounds.y, 32, 32);
                            break;
                        case Player.B:
                            this.panel.drawImage(this.chesswhite, this.chesses[i].bounds.x, this.chesses[i].bounds.y, 32, 32);
                            break;
                        default:
                            break;
                    }
                }
            }
    
            // 画棋子
        };
        this.repaint = function () {
            this.panel.clearRect(0, 0, this.width, this.height);
            this.paint();
        };
        this.start = function (el) {
            this.init();
            this.width = el.width();
            this.height = el.height()
            this.panel = Canvas.getContext(el);
            if (this.panel != null) {
                var t = this;
                // 加载棋子图片
                $(this.chessblack).load(function () {
                    t.imagestate++;
                });
                $(this.chesswhite).load(function () {
                    t.imagestate++;
                });
                this.chessblack.src = "chessblack.png";
                this.chesswhite.src = "chesswhite.png";
                if (this.imagestate < 2) {
                    this.paint();
                }
                this.imagetimer = setInterval(function () {
                    if (t.imagestate == 2) {
                        t.repaint();
                        t.play();
                    }
                }, 100);
                return true;
            }
    
            return false;
        };
    }

    怎么样?熟悉javascript的伙伴应该看起来没什么难度吧:)

    这节我们就讲到这里,下次里沃特再跟大家分享怎么分析和处理“移动棋子”、“夹一个”和“挑一对”,敬请期待。

    HTML5+JS 《五子飞》游戏实现(一)规则

    HTML5+JS 《五子飞》游戏实现(二)路线分析和资源准备

    HTML5+JS 《五子飞》游戏实现(四)夹一个和挑一对

    HTML5+JS 《五子飞》游戏实现(五)移动棋子

    HTML5+JS 《五子飞》游戏实现(六)鼠标响应与多重选择

  • 相关阅读:
    浅谈JS异步轮询和单线程机制
    nginx、php-fpm、swoole HTTP/TCP压测对比
    HTTP.Socket.TCP详解
    HTTP 的长连接和短连接
    docker 解决network has active endpoints
    centos7.5 ab压力测试安装和swoole压力测试
    win7下docker环境centos容器中安装mysql5.7
    centos7 lamp环境搭建
    在 Windows 上进行 Laravel Homestead 安装、配置及测试
    laravel windows安装(composer)
  • 原文地址:https://www.cnblogs.com/lyout/p/fiveflychess3.html
Copyright © 2011-2022 走看看