看到一些曾经只会灌水的网友,在学习了前端之后,已经能写出下载量几千几万的脚本、样式,帮助大众,成为受欢迎的人,感觉满羡慕的。我也想学会前端技术,变得受欢迎呀。于是心血来潮,开始学习前端知识,并写下了这个小练习。

基本思路是这样的:

  1. 使用Canvas绘制棋盘、棋子。
  2. 用二维数组保存棋盘状态。
  3. 设置一个flag,用以标识落子顺序。
  4. 点击时,在数组中检测当前点击位置是否存在棋子,若存在,则不落子;如游戏已结束,亦不落子。
  5. 落子时,更新数组,并将当前落子所在的行、列、左上-右下列、左下-右上列四个方向的棋盘状态写入到一维数组中,用以判断新落子是否形成了五子连珠。
  6. 若形成了五子连珠,提示胜利,并结束游戏;反之,则交换顺序,继续进行游戏。

  效果图:

  

代码如下:

 <!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五子棋的更多相关文章

  1. 高性能动画!HTML5 Canvas JavaScript框架KineticJS

    高性能动画!HTML5 Canvas JavaScript框架KineticJS KineticJS是一款开源的HTML5 Canvas JavaScript框架,能为桌面和移动应用提供高性能动画,并 ...

  2. HTML5 Canvas JavaScript库 Fabric.js 使用经验

    首先,表明我的态度:采用 Flash 才是最优方案,不建议使用 HTML 5 的 Canvas 做一些生产/工业级的网页应用. Flash的优势一是浏览器支持好,二是代码成熟稳定.而HTML5 的 C ...

  3. 【JavaScript游戏开发】使用HTML5+Canvas+JavaScript 封装的一个超级马里奥游戏(包含源码)

    这个游戏基本上是建立在JavaScript模块化的开发基础上进行封装的,对游戏里面需要使用到的游戏场景进行了封装,分别实现了Game,Sprite,enemy,player, base,Animati ...

  4. 【原创】使用HTML5+canvas+JavaScript开发的原生中国象棋游戏及源码分享

    目前已经实现的功能: V1.0 : 实现棋子的布局,画布及游戏场景的初始化V2.0 : 实现棋子的颜色改变V3.0 :实现所有象棋的走棋规则V4.0 : 实现所有棋子的吃子功能 GItHub源码下载地 ...

  5. 赠书:HTML5 Canvas 2d 编程必读的两本经典

    赠书:HTML5 Canvas 2d 编程必读的两本经典 这两年多一直在和HTML5 Canvas 打交道,也带领团队开发了世界首款基于HTML5 Canvas 的演示文档工具---AxeSlide( ...

  6. HTML5 canvas绘制雪花飘落动画(需求分析、知识点、程序编写分布详解)

    看到网上很多展示html5雪花飞动的效果,确实非常引人入胜,我相信大家也跟我一样看着心动的同时,也很好奇,想研究下代码如何实现:虽然哦很多地方也能下载这些源码,不过也不知道别人制作此类动画时的思路及难 ...

  7. JavaScript+html5 canvas实现本地截图教程

    这篇文章主要介绍了JavaScript+html5 canvas实现本地截图教程,对截图功能感兴趣的小伙伴们可以参考一下 最近有时间了解了下html5的各API,发现新浪微博的头像设置是使用canva ...

  8. js实现一个简单钟表动画(javascript+html5 canvas)

    第一次在博客园注册发博.有一次去人家单位开标,看到开标网站上有个钟表动画,一时兴起,就写了个简单的钟表动画. 用js和html5 canvas对象实现一个简单钟表程序 主要用到的就是h5的canvas ...

  9. 用html5 canvas和JS写个数独游戏

    为啥要写这个游戏? 因为我儿子二年级数字下册最后一章讲到了数独.他想玩儿. 因为我也想玩有提示功能的数独. 因为我也正想决定要把HTML5和JS搞搞熟.熟悉一个编程平台,最好的办法,就是了解其原理与思 ...

随机推荐

  1. 使用四元数解决万向节锁(Gimbal Lock)问题

    问题 使用四元数可以解决万向节锁的问题,但是我在实际使用中出现问题:我设计了一个程序,显示一个三维物体,用户可以输入绕zyx三个轴进行旋转的指令,物体进行相应的转动. 由于用户输入的是绕三个轴旋转的角 ...

  2. iOS开发系列--Swift进阶

    概述 上一篇文章<iOS开发系列--Swift语言>中对Swift的语法特点以及它和C.ObjC等其他语言的用法区别进行了介绍.当然,这只是Swift的入门基础,但是仅仅了解这些对于使用S ...

  3. 使用tornado,我们可以做什么?

    以下介绍都是建立在python2.x的基础上面,tornado使用任意版本皆可. 如果我们需要对外提供一个http server(web api)/websocket server时,我们都可以使用t ...

  4. DAO层,Service层,Controller层、View层 的分工合作

    DAO层:DAO层主要是做数据持久层的工作,负责与数据库进行联络的一些任务都封装在此,DAO层的设计首先是设计DAO的接口,然后在Spring的配置文件中定义此接口的实现类,然后就可在模块中调用此接口 ...

  5. iOS-开发进阶

    iOS完整学习路线图 iOS进阶介绍: 一.iOS-常用的第三方框架的介绍 二.iOS-提高iOS开发效率的方法和工具 三.常用的调试方法 1.iOS-调试技巧 2.iOS-Xcode的使用技巧 四. ...

  6. WCF学习之旅—TcpTrace工具(二十六)

    止文(WCF学习之旅—TcpTrace工具(二十五))介绍了关于TcpTrance的一种使用方式,接下来介绍第二种使用方式. 三.通过ListenUri实现基于tcpTracer的消息路由 对于路由的 ...

  7. 解析大型.NET ERP系统 权限模块设计与实现

    权限模块是ERP系统的核心模块之一,完善的权限控制机制给系统增色不少.总结我接触过的权限模块,以享读者. 1 权限的简明定义 ERP权限管理用一句简单的话来说就是:谁 能否 做 那些 事. 文句 含义 ...

  8. 缩放因子和UI设计

    一.PPI 1.像素密度PPI:PPI(Pixel Per Inch by diagonal):表示沿着对角线,每英寸所拥有的像素(Pixel)数目. 根据勾股定理(直角三角形两边为a和b,斜边为c, ...

  9. 构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(12)-系统日志和异常的处理②

    系列目录 上一讲我们做了日志与异常的结果显示列表,这一节我们讲要把他应用系统中来. 首先我们在App.Common类库中创建一个通用类ResultHelper,这个类里面写了,获取一个GUID,获取当 ...

  10. Android动画效果之初识Property Animation(属性动画)

    前言: 前面两篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画).Frame Animation(逐帧动画)Andr ...