自己写的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搞搞熟.熟悉一个编程平台,最好的办法,就是了解其原理与思 ...
随机推荐
- 机器学习之sklearn——EM
GMM计算更新∑k时,转置符号T应该放在倒数第二项(这样计算出来结果才是一个协方差矩阵) from sklearn.mixture import GMM GMM中score_samples函数第 ...
- 开源发布:VS代码段快捷方式及可视化调试快速部署工具
前言: 很久前,我发过两篇文章,分别介绍自定义代码版和可视化调试: 1:Visual Studio 小技巧:自定义代码片断 2:自定义可视化调试工具(Microsoft.VisualStudio.De ...
- 认识ASP.NET 5项目结构和项目文件xproj
ASP.NET 5 在项目结构上做了很大的改变,我们以前熟悉的目录结构与项目文件内容都不太一样了,本篇文章带大家了解 ASP.NET 5 到底跟以前有哪些不一样的地方. 我们先用 Visual Stu ...
- 四、可空类型Nullable<T>到底是什么鬼
值类型为什么不可以为空 首先我们都知道引用类型默认值都是null,而值类型的默认值都有非null. 为什么引用类型可以为空?因为引用类型变量都是保存一个对象的地址引用(就像一个url对应一个页面),而 ...
- ubuntu 14.10 lts 64-bits环境下使用Android Studio
距离google发布android studio 1.0正式版已经两个月左右了.由于一直习惯使用eclipse+ADT的模式,而且曾在windows下试用一次Android Studio预览版,感觉卡 ...
- 「标准」的 JS风格
首先,这份 JS风格指南已经在我司的前端团队实行半年多了: 其次,在程序员的世界里,从入行到资深都需要面对几个世界级的难题,如: 世界上最好的编辑器是什么? 是用空格还是 TAB?用空格还特么衍生出 ...
- ABP源码分析六:依赖注入的实现
ABP的依赖注入的实现有一个本质两个途径:1.本质上是依赖于Castle这个老牌依赖注入的框架.2.一种实现途径是通过实现IConventionalDependencyRegistrar的实例定义注入 ...
- iOS集成sharesdk遇到的坑
分享新浪微博 ★★★分享新浪微博★★★ 前言: 写这个目地是为了记录那些过坑,直接先上效果图.大家看看如果你遇到了应该如果处理更好,因为刚一看到这个效果的时候就明白其实很简单不就是分享微博吧.但是要求 ...
- es6 新特性2
es6其他几个非常有用的新特性. import export 这两个家伙对应的就是es6自己的module功能. 我们之前写的Javascript一直都没有模块化的体系,无法将一个庞大的js工程拆分成 ...
- 阿里云本地FTP怎么连接?通用win7,win8,win8.1,win10