前面两节,我们已经对《五子飞》有个初步的认识,对走棋路线也有了基本的了解,现在里沃特继续跟大家分享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 《五子飞》游戏实现(六)鼠标响应与多重选择

HTML5+JS 《五子飞》游戏实现(三)页面和棋盘棋子的更多相关文章

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

    很久没写文章了,这个游戏其实已经写了有段时间了,一直没有完善,赶在新年之际,分享给大家. 该<五子飞>游戏,不是平常大家所说的<五子棋>,这个玩法简单,是我们老家儿时常玩的一种 ...

  2. HTML5+JS 《五子飞》游戏实现(八)人机对战

    要想实现人机对战,就必须让电脑自动下棋,而且要知道自动去查找对方的棋子,看看有没有可以挑一对的,有没有可以夹一个的,这样下起来才有意思. 当电脑用户下完棋后,电脑应立即搜索用户的棋子,然后如果没有被吃 ...

  3. HTML5+JS 《五子飞》游戏实现(七)游戏试玩

    前面第一至第六章我们已经把<五子飞>游戏的基本工作都已经讲得差不多了,这一章主要是把所有的代码分享给大家,然后小伙伴们也可以玩一玩. 至于人机对战的我们放到后面讲进行分析. 试玩地址:ht ...

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

    上一章我们提到了如果有多条线上的棋子可以被吃掉,那么游戏需要提示用户,让用户选择吃哪条线上的.另外因为是网页游戏,所以一定要实现鼠标单击棋子可以进行操作. 当鼠标移动棋子上面后,切换鼠标指针为手形,移 ...

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

    上一章 我们知道了怎么处理两个重要的吃棋动作,想要吃对方的棋子,首先得移动自己的棋子.现在里沃特跟大家分享分享,怎么移动棋子. 想要移动棋子,在页面上,首先要点击一下要移动的棋子,然后再点击一下目标位 ...

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

    在第一章我们已经说了怎么才能“夹一个”以及怎样才能挑一对,但那毕竟只是书面上的,对码农来讲,我们还是用代码讲解起来会更容易了解. 为了更容易对照分析,我们先把路线再次贴出来: // 可走的路线 thi ...

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

    上一节 里沃特与我们分享了<五子飞>的下棋规则,可能有些伙伴看得不清楚,像我们码农还是看到代码比较靠谱.下面就把可以走棋的路线跟大家说一下. 假设从左上角开始,以0开始编号,往右数(没看第 ...

  8. 用html5+js实现掌机游戏赛车demo

    最近无聊,用html5+js做了一个以前玩过的掌机赛车游戏,顺便学习一下画布的api以及巩固一下js基础. 游戏界面,没做什么美化. 游戏规则:游戏界面分为三列,黑色方块随机落下,红色方块可以在三列自 ...

  9. 100行JS实现HTML5的3D贪吃蛇游戏

    js1k.com收集了小于1k的javascript小例子,里面有很多很炫很酷的游戏和特效,今年规则又增加了新花样,传统的classic类型基础上又增加了WebGL类型,以及允许增加到2K的++类型, ...

随机推荐

  1. 首先,编写一个类ChongZai,该类中有3个重载的方法void print();其次, 再编写一个主类来测试ChongZai类的功能

    //计算器 jisuanqi jsq=new jisuanqi(); System., )); System., , )); System.out.println("2.3和4.5 中最大的 ...

  2. 大型网站的 HTTPS 实践(1):HTTPS 协议和原理

    转自:http://op.baidu.com/2015/04/https-s01a01/ 1 前言 百度已经于近日上线了全站 HTTPS 的安全搜索,默认会将 HTTP 请求跳转成 HTTPS.本文重 ...

  3. c# 设置winform程序为默认打开软件 在运行中获取参数

    1.右键→打开方式→选择默认程序→选择winform程序 2.修改Program.cs 判断注册的事件是否存在,如果不存在则运行实例,并把参数传入MainForm里,如果存在则把参数写到txt文件中, ...

  4. Oracle安装前用户信息设置

    如果是重复安装,首先需要清除已经存在的软件安装记录: rm -fr /usr/local/bin/*oraenv rm -fr /usr/local/bin/dbhome rm -fr /usr/tm ...

  5. SQL Serve里你总要去改变的3个配置选项

    你用安装向导安装了全新的SQL Server,最后你点击了完成按钮.哇噢~~~现在我们可以把我们的服务器进入生产了!抱歉,那并不是真的,因为你的全新SQL Server默认配置是错误的. 是的,你没看 ...

  6. Jmeter之Bean shell使用(一)

    一.什么是Bean Shell BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法; BeanShell是一种松散类型的脚本语言(这点和JS类似); BeanS ...

  7. linux命令学习(一)—— 文件和目录管理命令

    首先需要知道的是命令提示符 [root@localhost ~] # 当前登录用户(root) 主机名(localhost) 当前所在目录(家目录) 超级用户提示符(#) 普通用户提示符($) 1.1 ...

  8. ES6函数默认参数(Default Parameters)

    语言更新时每一个新增的特性都是从千百万开发者需求里提取过来的,规范采用后能减少程序员的痛苦,带来便捷. 我们经常会这么写 function calc(x, y) { x = x || 0; y = y ...

  9. hw 要的是螺丝钉

    日前突然接到华为HR的电话,叫我去面试。本来我的工作和工资收入等各方面在本地也还算可以,没有想要跳槽。但是本着去看看有没有更好机会的想法就去了。  9:30到了现场后,在那里等了很久,一个考官上来问了 ...

  10. 查看centos系统版本

    1.查看系统版本 [root@yl-web yl]# cat /etc/redhat-release CentOS Linux release 7.1.1503 (Core) 2.查看内核版本 [ro ...