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 《五子飞》游戏实现(六)鼠标响应与多重选择

  • 相关阅读:
    Java实现 蓝桥杯 算法训练 Number Challenge(暴力)
    Java实现 蓝桥杯 算法训练 Number Challenge(暴力)
    Java实现 蓝桥杯 算法训练 Number Challenge(暴力)
    Java实现 蓝桥杯 算法训练 Rotatable Number(暴力)
    Java实现 蓝桥杯 算法训练 Rotatable Number(暴力)
    Java实现 蓝桥杯 算法训练 Rotatable Number(暴力)
    Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)
    Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)
    Java实现 蓝桥杯 算法训练 猴子吃包子(暴力)
    Python位运算符
  • 原文地址:https://www.cnblogs.com/lyout/p/fiveflychess3.html
Copyright © 2011-2022 走看看