自己写的HTML5 Canvas + Javascript五子棋
看到一些曾经只会灌水的网友,在学习了前端之后,已经能写出下载量几千几万的脚本、样式,帮助大众,成为受欢迎的人,感觉满羡慕的。我也想学会前端技术,变得受欢迎呀。于是心血来潮,开始学习前端知识,并写下了这个小练习。
基本思路是这样的:
- 使用Canvas绘制棋盘、棋子。
- 用二维数组保存棋盘状态。
- 设置一个flag,用以标识落子顺序。
- 点击时,在数组中检测当前点击位置是否存在棋子,若存在,则不落子;如游戏已结束,亦不落子。
- 落子时,更新数组,并将当前落子所在的行、列、左上-右下列、左下-右上列四个方向的棋盘状态写入到一维数组中,用以判断新落子是否形成了五子连珠。
- 若形成了五子连珠,提示胜利,并结束游戏;反之,则交换顺序,继续进行游戏。
效果图:

代码如下:
<!DOCTYPE html>
<html lang="zh-CN">
<meta charset="utf-8">
<head><title>五子棋</title></head>
<body>
<canvas id="myCanvas" width="560" height="560" style="border:3px solid black;">
您的浏览器不支持 HTML5 canvas 标签。</canvas> <br/>
<button id="reset" onclick="controller.init(ctx)">重置</button>
</body>
<script>
var controller = {
round:true,
color:"black",
whiteTable:new Array(),
blackTable:new Array(),
row:0,
col:0,
over:false,
trans:function() {
this.round = !this.round;
if (!this.round) {
this.blackTable[this.row][this.col] = 1;
this.ifWin(this.blackTable)
this.color = "white";
}
else {
this.whiteTable[this.row][this.col] = 1;
this.ifWin(this.whiteTable)
this.color = "black";
}
},
ifWin:function(table) {
var arr1 = new Array();
var arr2 = new Array();
var arr3 = new Array();
var arr4 = new Array();
var n = 0;
for(x = 0; x<= lineNums; x++) {
for(y = 0; y <= lineNums; y++)
{
var x1 = this.row - n;
var x2 = this.row + n;
var y1 = this.col - n;
var y2 = this.col + n;
if(y == this.col) {
arr1[x] = table[x][y];
}
if(x == this.row) {
arr2[y] = table[x][y];
}
}
if(this.inBounds(x1) && this.inBounds(y2)) {
arr3[x1] = table[x1][y2];
}
if(this.inBounds(x1) && this.inBounds(y1)) {
arr4[x1] = table[x1][y1];
}
if(this.inBounds(x2) && this.inBounds(y1)) {
arr3[x2] = table[x2][y1];
}
if(this.inBounds(x2) && this.inBounds(y2)) {
arr4[x2] = table[x2][y2];
}
n = n + 1;
}
this.getSum(arr1, this.row);
this.getSum(arr2, this.col);
this.getSum(arr3, this.row);
this.getSum(arr4, this.row);
},
inBounds:function(i) {
if(i>=0 && i<=15){
return true;
}
else{
return false;
}
},
getSum:function(array, pos) {
num = 5;
posr = pos + 1;
while(num > 0){
if(array[pos]>0 && this.inBounds(pos)) {
num = num - 1;
pos = pos - 1;
}
else{
break;
}
}
while(num > 0){
if(array[posr]>0 && this.inBounds(pos)) {
num = num - 1;
posr = posr + 1;
}
else {
break;
}
}
if(num == 0) {
this.over = true;
this.gameOver();
}
},
exist:function(x, y) {
this.row = x / ratio;
this.col = y / ratio;
var nums = this.whiteTable[this.row][this.col] + this.blackTable[this.row][this.col];
if( nums > 0 {
return true;
}
else{
return false;
}
},
gameOver:function() {
ctx.font="30px Arial";
ctx.fillStyle = "#FF0000";
if(this.round) {
ctx.fillText("白棋胜利",240,240);
}
else {
ctx.fillText("黑棋胜利",240,240);
}
},
init:function() {
this.round = true;
this.color = "black";
this.over = false;
this.drawBoard();
for(i = 0; i<= lineNums; i++) {
this.whiteTable[i]=new Array();
this.blackTable[i]=new Array();
for(n = 0; n <= lineNums; n++) {
this.whiteTable[i][n]=0;
this.blackTable[i][n]=0;
}
}
},
drawBoard:function() {
ctx.beginPath();
ctx.clearRect(0,0,width,width);
ctx.fillStyle = "#FFBB00";
ctx.fillRect(0,0,width,width);
for(var i = 1; i < (lineNums - 1); i++) {
ctx.moveTo(i * ratio, 0);
ctx.lineTo(i * ratio, width);
ctx.stroke();
ctx.moveTo(0, i * ratio);
ctx.lineTo(width, i * ratio);
ctx.stroke();
}
},
drawPiece:function(posX, posY) {
ctx.beginPath();
ctx.arc(posX, posY, ratio/2, 0, 2*Math.PI);
ctx.fillStyle = this.color;
ctx.fill();
ctx.stroke();
}
};
//获取点击位置
function getMousePos(canvas, evt) {
var rect = canvas.getBoundingClientRect();
return {
x: evt.clientX - rect.left * (canvas.width / rect.width),
y: evt.clientY - rect.top * (canvas.height / rect.height)
}
} function getNode(pos) {
return ((pos / ratio).toFixed()) * ratio;
} var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
var lineNums = 15;
var ratio = 40;
var width = (lineNums - 1) * ratio; controller.init(); canvas.addEventListener("click", function (evt) {
var mousePos = getMousePos(canvas, evt);
mousePos.x = getNode(mousePos.x);
mousePos.y = getNode(mousePos.y);
var exist = controller.exist(mousePos.x, mousePos.y);
if (!exist && !controller.over) {
controller.drawPiece(mousePos.x, mousePos.y);
controller.trans();
}
}, false);
</script>
</html>
这算是自己学习Javascript的一个开端,未来的话,可能也要以这个例子为基础,利用学到的知识,进一步增加其它功能,优化代码。
本文链接:http://www.cnblogs.com/hhelibeb/p/6013188.html
自己写的HTML5 Canvas + Javascript五子棋的更多相关文章
- 高性能动画!HTML5 Canvas JavaScript框架KineticJS
高性能动画!HTML5 Canvas JavaScript框架KineticJS KineticJS是一款开源的HTML5 Canvas JavaScript框架,能为桌面和移动应用提供高性能动画,并 ...
- HTML5 Canvas JavaScript库 Fabric.js 使用经验
首先,表明我的态度:采用 Flash 才是最优方案,不建议使用 HTML 5 的 Canvas 做一些生产/工业级的网页应用. Flash的优势一是浏览器支持好,二是代码成熟稳定.而HTML5 的 C ...
- 【JavaScript游戏开发】使用HTML5+Canvas+JavaScript 封装的一个超级马里奥游戏(包含源码)
这个游戏基本上是建立在JavaScript模块化的开发基础上进行封装的,对游戏里面需要使用到的游戏场景进行了封装,分别实现了Game,Sprite,enemy,player, base,Animati ...
- 【原创】使用HTML5+canvas+JavaScript开发的原生中国象棋游戏及源码分享
目前已经实现的功能: V1.0 : 实现棋子的布局,画布及游戏场景的初始化V2.0 : 实现棋子的颜色改变V3.0 :实现所有象棋的走棋规则V4.0 : 实现所有棋子的吃子功能 GItHub源码下载地 ...
- 赠书:HTML5 Canvas 2d 编程必读的两本经典
赠书:HTML5 Canvas 2d 编程必读的两本经典 这两年多一直在和HTML5 Canvas 打交道,也带领团队开发了世界首款基于HTML5 Canvas 的演示文档工具---AxeSlide( ...
- HTML5 canvas绘制雪花飘落动画(需求分析、知识点、程序编写分布详解)
看到网上很多展示html5雪花飞动的效果,确实非常引人入胜,我相信大家也跟我一样看着心动的同时,也很好奇,想研究下代码如何实现:虽然哦很多地方也能下载这些源码,不过也不知道别人制作此类动画时的思路及难 ...
- JavaScript+html5 canvas实现本地截图教程
这篇文章主要介绍了JavaScript+html5 canvas实现本地截图教程,对截图功能感兴趣的小伙伴们可以参考一下 最近有时间了解了下html5的各API,发现新浪微博的头像设置是使用canva ...
- js实现一个简单钟表动画(javascript+html5 canvas)
第一次在博客园注册发博.有一次去人家单位开标,看到开标网站上有个钟表动画,一时兴起,就写了个简单的钟表动画. 用js和html5 canvas对象实现一个简单钟表程序 主要用到的就是h5的canvas ...
- 用html5 canvas和JS写个数独游戏
为啥要写这个游戏? 因为我儿子二年级数字下册最后一章讲到了数独.他想玩儿. 因为我也想玩有提示功能的数独. 因为我也正想决定要把HTML5和JS搞搞熟.熟悉一个编程平台,最好的办法,就是了解其原理与思 ...
随机推荐
- Nlog配置实例
彩色Console target <?xml version="1.0" encoding="utf-8" ?> <nlog xmlns= ...
- 网站缓存技术总结( ehcache、memcache、redis对比)
网站技术高速发展的今天,缓存技术已经成为大型网站的一个关键技术,缓存设计好坏直接关系的一个网站访问的速度,以及购置服务器的数量,甚至影响到用户的体验. 网站缓存按照存放的地点不同,可以分为客户端缓存. ...
- 好好了解一下Cookie
Cookie的诞生 由于HTTP协议是无状态的,而服务器端的业务必须是要有状态的.Cookie诞生的最初目的是为了存储web中的状态信息,以方便服务器端使用.比如判断用户是否是第一次访问网站.目前最新 ...
- Entity Framework 6 Recipes 2nd Edition(9-1)译->用Web Api更新单独分离的实体
第九章 在N层结构的应用程序中使用EF 不是所有的应用都能完全地写入到一个单个的过程中(就是驻留在一个单一的物理层中),实际上,在当今不断发展的网络世界,大量的应用程序的结构包含经典的表现层,应用程, ...
- Java中六大时间类的使用和区别
关于java中六个时间类的使用和区别 java.util.Date java.sql.Date java.sql.Time java.sql.Timestamp java.text.SimpleD ...
- Python下载网页的几种方法
get和post方式总结 get方式:以URL字串本身传递数据参数,在服务器端可以从'QUERY_STRING'这个变量中直接读取,效率较高,但缺乏安全性,也无法来处理复杂的数据(只能是字符串,比如在 ...
- 5.SVM核函数
核函数(Kernels) 定义 1.1 (核或正定核) 设是中的一个子集,称定义在上的函数是核函数,如果存在一个从到Hilbert空间的映射 使得对任意的,都成立.其中表示Hilbert空间中的内积. ...
- Task三个列子的分享
这次要分享的是C#Task任务的几个列子,感觉最实用的是封装的分页任务执行方法,这个方法步奏也是目前在我工作中执行多任务常用的,不知道各位也有这用的情况,那么开始吧. 1.顺序任务执行 //顺序任务执 ...
- C++服务器开发之笔记三
为什么需要原子性操作? 我们考虑一个例子:(1)x++这个常见的运算符在内存中是怎样操作的?从内存中读x的值到寄存器中,对寄存器加1,再把新值写回x所处的内存地址 若是有两个线程同时对同一个变量++, ...
- 学习JVM--垃圾回收(一)原理
1. 前言 Java和C++之间显著的一个区别就是对内存的管理.和C++把内存管理的权利赋予给开发人员的方式不同,Java拥有一套自动的内存回收系统(Garbage Collection,GC)简称G ...