自己写的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搞搞熟.熟悉一个编程平台,最好的办法,就是了解其原理与思 ...
随机推荐
- 跟着老男孩教育学Python开发【第五篇】:模块
递归的案例:阶乘 1*2*3*4*5*6*7- def func(num): if num == 1: return 1 return num * func(num - ...
- 【初码干货】在Window Server 2016中使用Web Deploy方式发布.NET Web应用的重新梳理
在学习和工作的过程中,发现很多同事.朋友,在做.NET Web应用发布的时候,依然在走 生成-复制到服务器 这样的方式,稍微高级一点的,就是先发布到本地,再上传到服务器 这种方式不仅效率低下,而且不易 ...
- Visual Studio Code预览版Ver 0.3.0试用体验
当你开始阅读这篇文章时,请先不要把Visual Studio Code和.net.Windows联想到一起,因为VS Code是一个跨平台,支持30多种语言的开箱代码编辑器.不管你是.Net.Java ...
- 用Go实现的简易TCP通信框架
接触到GO之后,GO的网络支持非常令人喜欢.GO实现了在语法层面上可以保持同步语义,但是却又没有牺牲太多性能,底层一样使用了IO路径复用,比如在LINUX下用了EPOLL,在WINDOWS下用了IOC ...
- 简化SSH框架的整合
一.开发环境: (1) OS:Windows 7 (2) DB:MySql 5.1.6 (3) JDK:1.8.0_17 (4) Server:Apache Tomcat 8. ...
- 数据库中树形列表(以easyui的tree为例)
构造一棵easyui前台框架的一个树形列表为例后台框架是spring MVC+JPA. 先看一下数据库是怎么建的,怎么存放的数据 下面是实体类 /** * 部门类 用户所属部门(这里的部门是一个相对抽 ...
- Python初学者之网络爬虫
声明:本文内容和涉及到的代码仅限于个人学习,任何人不得作为商业用途. 本文将介绍我最近在学习Python过程中写的一个爬虫程序,将力争做到不需要有任何Python基础的程序员都能读懂.读者也可以先跳到 ...
- lua解析赋值类型代码的过程
我们来看看lua vm在解析下面源码并生成bytecode时的整个过程: foo = "bar" local a, b = "a", "b" ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(2)-easyui构建前端页面框架[附源码]
系列目录 前言 为了符合后面更新后的重构系统,本文于2016-10-31日修正一些截图,文字 我们有了一系列的解决方案,我们将动手搭建新系统吧. 后台系统没有多大的UI视觉,这次我们采用的是标准的左右 ...
- react+redux教程(六)redux服务端渲染流程
今天,我们要讲解的是react+redux服务端渲染.个人认为,react击败angular的真正“杀手锏”就是服务端渲染.我们为什么要实现服务端渲染,主要是为了SEO. 例子 例子仍然是官方的计数器 ...