棋盘游戏源码棋盘游戏源码-HTML5游戏开发教程实战:五子棋、五子棋、围棋、逆棋四种棋类游戏

这篇文章是一篇很有挑战性的编程,因为100行代码,约10000个字符,将实现国际象棋、五子棋、四连棋和逆棋四种单人棋类游戏。 请注意,这四款棋局并不是中级程序员的作品,而是有棋盘、三维棋子、事件、棋规、输赢判断的完整棋局,并且可以在iPad和Android平板电脑上离线存储。 试想一下,将这些游戏下载到平板电脑上,你就可以在火车、旅游公园等没有信号的地方下棋。 是否扩展了平板电脑的功能? 是不是一件很悠闲的事情呢? 而且,关键是这个程序没有图片,不需要去应用商店付费下载。 它只是用 HTML5 技术编写的 100 行代码。 绝对是目前最简洁、功能最强大的单人棋牌游戏源码。 (编者注:由于网页代码长度限制,作者源码进行了一些换行处理,特此说明。)

目标

要做一个完整的单人象棋游戏,至少要做好以下几件事,第一步:画棋盘。 不同的棋盘是不同的,需要动态处理; 第二步:画棋子。 需要注意的是,围棋五子棋等棋子都是圆的。 请不要担心图片。 HTML5时代,我们可以用代码实现三维方形棋子; 第三步:判断情况。 当然,还要定位右手的点击位置。 这四种棋中,有的落在框架上,有的落在纵横交错的棋盘十字线上,需要动态处理; 第四步:判断走棋规则。 下棋是有规则的。 不要因为代码少而忽视规则,否则程序不成熟,就会成为小孩子的玩具; 第五步:判断输赢。 最后,我们必须决定是赢还是输。 也就是算数,这个事情必须由程序来完成,因为比赛总是需要裁判的; 第六步:在平板电脑时代,我们要实现离线应用。 这一点很重要,不然的话,如果你接上网线在台式电脑上玩游戏,已经是满地都是了,你写得再好又有什么用呢? 就是中国联通,没有信号的地方,就有市场。 现在平板电脑、智能手机这么多,在没有网络信号的地方拿出联通设备玩游戏是一件非常好的事情。

画棋盘

前面说过,国际象棋、五子棋、四连棋、逆棋的棋盘并不相同。 围棋有纵横各18格,而其他三盘棋有8格。 因此,需要有参数来勾画棋盘。 这是小问题,大问题是,选择哪种方式来勾画板?

在HTML5的框架下,至少有三种方式:第一种方式是使用Canvas画线; 第二种方式是使用DIV,减少了CSS3中的行列属性; 第三种方法是使用表标签。

哪一个最快并且代码更少? 答案是:第三个。 有点令人沮丧的是,HTML5 并不是万能药。 详细代码如下:

 this.board=function(name,width,height,rowBak,colBak){ /* 画棋盘 */ 
 nameBak=name; 
 if("turnover"==name){row=8;col=8;}else if("gogame"==name){row=18;col=18;} 
 var aW=Math.floor(width/(col+2)),aH=Math.floor(height/(row+2)); 
 minL=(aW>aH?aH:aW)-4;// 这个减法很重要,否则填空时会把表格撑大
 var array=new Array("
"+ ""); for(var i=0;i<row;i++){ array.push(""); for(var j=0;j<col;j++){array.push("");} if(nameBak!="four"&&nameBak!="turnover")/* 将事件添加到表格中 */ array.push(evt(i,col,minL,minL,aW*col+minL/2+8,aH*i+minL/2)); array.push(""); } if(nameBak!="four"&&nameBak!="turnover"){ for(var j=0;j<=col;j++){ array.push(evt(row,j,minL,minL,aW*j+minL/2+8,aH*row+minL/2)); } } document.write(array.join("")+"
"+ evt(i,j,minL,minL,aW*j+minL/2+8,aH*i+minL/2)+"
"); setClick(row,col,minL,minL);/* 初始化事件 */ start();/* 初始化棋子 */ }

上面的代码中,最重要的是标准歌曲中的第6行代码。 这里面有两个技巧。 第一个是table的定义,第二个是Array数组的使用。 为什么使用链表而不是定义字符串? 答案是优化,即Array数组的push方法比String字符串的加法+操作要快很多。 一共16行代码,就画出了一个棋盘。 当然不仅仅是画线,还有棋子处理、事件定义等的调用,后面会提到。

画棋子

画完棋盘后,我们来画棋子。 我们选择的四种国际象棋的棋盘虽然不同棋盘游戏源码棋盘游戏源码,但是棋子都是一样的,都是黑白棋子。 以前在网上下棋,除了Flash的美观效果外,还得先请美工制作几张小图。 HTML5时代,节省了艺术家的人力和沟通成本。

棋盘游戏源码棋盘游戏源码-HTML5游戏开发教程实战:五子棋、五子棋、围棋、逆棋四种棋类游戏

我们至少有两种方法来勾画棋子的轮廓,第一种是:canvas类,第二种是css的圆角属性。 哪个速度更快并且代码更少? 答案是第二个,圆角。 代码如下所示:

 function man(width,height,id,colorBak){ /* 画棋子 */ 
   var color=colorBak==null?(order++%2==0?"000":"CCC"):colorBak; 
   var r="border-radius:"+width/2+"px;"; 
   var obj=id==null?event.srcElement:_$(id); 
   obj.innerHTML="
"; }

在上面的代码中,我们看到我们为每个棋子定义了一个DIV,利用CSS3的阴影和渐变属性,根据棋盘的大小手动估计棋子的大小。 另外,如果用户不喜欢黑白颜色,甚至可以定义红色和黄色,女孩和孩子可能会喜欢。 这5行代码就是绘制一个棋子的方法,一个简单的循环就可以绘制多个棋子,方法如下。

function moreMan(array){for(var i=0;i<array.length;i++) 
man(minL,minL,nameBak+"_"+array[i]);}
/* 绘制多个棋子 */

应对风暴

画完棋盘和棋子后,我们来分析用户的行为。 用户的操作无非两种,一种是点击棋盘桌,另一种是点击棋子DIV。 困难在于点击桌子。 我们需要知道用户点击表格的位置。

传统的思维方式可能是这样的,使用事件方法获取x,y坐标,然后添加到表格的左上角,然后添加到单元格中。 听起来好像很麻烦。

如果你仔细阅读上面的代码,你应该发现,在绘制棋盘时,我们向数组数组中推送了一个evt方法。 显然,这个evt方法返回的是一个字符串变量,那么它的内容是什么呢? 呢绒? 答案已经出来了:

function evt(i,j,width,height,left,top){ /* 单一单元格事件 */ 
  return "
"; }

原则是DIV。 顺便说一句,这种添加风暴的方式很特别。 其实就是在每个棋盘的交点处绘制一个DIV,然后将风暴添加到这些DIV中。

棋盘游戏源码棋盘游戏源码-HTML5游戏开发教程实战:五子棋、五子棋、围棋、逆棋四种棋类游戏

function setClick(row,col,width,height){ 
	    for(var i=0;i<=row;i++){ 
            for(var j=0;j<=col;j++){ 
                var els=_$(nameBak+"_"+i+"_"+j); 
                if(els!=null)els.onclick=function(){if(rule())man(width,height);}; 
			 } 
	    } 
	 }

需要注意的是,必须先定义DIV,即输出document.write,然后再执行onclick的定义,否则会返回DIV未定义的错误。 仅仅10行代码,风暴问题就解决了。

比赛规则

正如前面提到的,用户点击事件有两种类型。 我们巧妙地通过减小DIV的方式解决了点击棋盘桌的事件。 那么第二种点击棋子的方式呢?

首先要说明的是,虽然点击棋子是一个错误,但是点击棋盘可以下棋,那么点击棋子是什么意思呢? 在黑白棋中点击棋子是没有意义的。 我们必须做出判断,不能把一块放在有一块的地方。 这是规则之一。 所以需要定义一种方法来判断被点击的地方是否有棋子。 代码如下所示:

function isMan(row,col){var obj=_$(nameBak+"_"+row+"_"+col,1);
if(obj==null||obj.indexOf("man_")==-1)return null;
else if(obj.indexOf("000")!=-1)
  return 0;
else if(obj.indexOf("CCC")!=-1)return 1;}

没想到,其实只用一行代码就可以判断是否有一块。 怎么判断,诀窍是判断DIV的颜色。 该块要么是黑色,返回 0,要么是白色棋盘游戏源码棋盘游戏源码,返回 1,但空白区域没有颜色,返回 null。 一定要注意这里的返回值,后面判断游戏输赢的时候会用到这个值。 所以不能简单的用返回值true或false来判断是否有棋子,而是判断有哪些颜色的棋子。

对于五子棋和国际象棋来说,这一条规则就足够了,但是对于倒棋和四连棋来说,还有第二条规则:不能将棋子放在它周围的空白处,也就是说,它必须是相连的。 也就是说,不仅要判断点击的地方是否有棋子,还要判断其周围是否有棋子。 这是不可能的,但必须如此。 需要做一个小循环,代码如下:

 function rule(){/* 走棋规则 */ 
 var id=event.srcElement.id; 
 if(id.indexOf("man_")==0){alert("不能在有子的地方落子");return false;}else{ 
     var p=id.indexOf("_"),p1=id.lastIndexOf("_"); 
     var row=id.substr(p+1,p1-p-1)*1,col=id.substr(p1+1)*1; 
     if("gobang"==nameBak)return gobang(row,col); 
        else if("four"==nameBak){ 
     if(isMan(row,col+1)==null&&isMan(row,col-1)==null&& 
     isMan(row+1,col)==null&& 
     isMan(row-1,col)==null){ 
     alert("四子棋不能在四周空白的地方落子!"); 
     return false; 
 } 
 return gobang(row,col,3); 
 }else if("turnover"==nameBak){ 
 if(isMan(row,col+1)==null&&isMan(row,col-1)==null&& 
 isMan(row+1,col)==null&&isMan(row-1,col)==null&& 
 isMan(row-1,col-1)==null&& 
 isMan(row+1,col+1)==null){ 
 alert("翻转棋不能在四周空白的地方落子!"); 
 return false; 
 } 
  turnover(); 
 }else if("gogame"==nameBak){ 
     } 
     } 
  return true; 
 }

循环中会反复调用isMan方法来判断是否有棋子,所以如果isMan不写得简洁快速的话,不知道要花多少时间。 算起来,总共有19行代码来处理放置规则。

到目前为止,我们已经画出了棋盘、棋子的草图,获取了点击时间,判断了走棋规则,只用了大约40行代码。 其实程序基本上是可以用的,但是我们还不满意,还得让它变得更聪明,我们还需要一个裁判来判断胜负。

判断输赢

要决定输赢,我们必须了解游戏规则:

双陆棋为每个方向连成五个棋子为胜,四子棋为每个方向连成四个棋子为胜,通过翻转棋子来计算棋子数量。 围棋就比较麻烦了,不仅要计算棋子的数量,还要计算围成的面积。

逻辑上看起来很复杂,而且似乎是估算最多的地方,有点像人工智能。 没错,如果后面的基础打不好的话,这里确实要花很多代码,但是既然我们定义了DIV的iaMan方法,用颜色来判断是否有棋子,这里又一个小方法,可以轻松实现处理胜负判断。 先看五子棋和四月棋的输赢判断代码,然后对照代码进行分析。

 function gobang(row,col,num){ 
 num=num==null?4:num; 
 var rs=[[],[],[],[]],b=[],w=[];/* 这里采用四维数组来存储棋子位置 */ 
 for(var i=0,j=0;i<num*2+1;i++,j++){ 
 rs[0].push(isMan(row-num+i,col)); 
 rs[1].push(isMan(row,col-num+j)); 
 rs[2].push(isMan(row-num+i,col-num+j)); 
 rs[3].push(isMan(row-num+i,col-num+j)); 
 if(i<num){b.push(0);w.push(1);} 
		 } 
 if(rs.join("#").indexOf(b.join(","))!=-1){alert("黑棋胜");return false; 
 }else if(rs.join("#").indexOf(w.join(","))!=-1){alert("白棋胜");return false;} 
     return true; 
	 }

一共9行代码就可以搞定,明白了吗? 首先定义一个Javascript多维字段rs=[[],[],[],[]]。 这种定义多维字段的方式将被选择并解释,因为它在搜索引擎上找不到。 我会教我当时遇到的中学生也不清楚。 他们中的大多数都使用了新的Array,然后添加了循环蜗牛技术。

步骤2:从放置棋子的地方开始循环。 注意,并不是循环整个棋盘,只是为了节省时间。 圆形设计跨越四个方向。 有棋子的地方,将棋子的颜色推到这个四维场中。

第三步:加入链表就可以了。 如果有4个或5个1相连,那么白棋自然获胜,否则黑棋获胜。

这里写的有点意思,注意一下我们处理数据的方式,我称之为“块数据”,就是充分利用数组数组来一块一块的保存数据,无论是写入、读取还是统计对这条数据进行分析,不仅可以提高内聚性,还可以方便提取可重用的方法,可以大大提高执行速度。

处理连接不成问题,计数就更简单了。 采用块数据处理方式,3行即可完成。

 function turnover(){ 
    if(order<64)return; 
    var num=0;var total=row*col;for(var i=0;i<row;i++){ 
        for(var j=0;j<col;j++){num+=isMan(i+"_"+j);} 
    } 
 if(numrow*col/2)alert("白棋胜"+(num*2-total)+"子");
 else alert("平局"); 
	 }

棋子初始化

话虽如此,还有最后一个关于棋子的问题需要解决。 也就是说,双陆棋是从白棋开始的,而其他三种国际象棋一开始都是有棋子的。 其实给一个空白棋盘是可以的,但其他三种棋通常都是固定在前几步的。 为了提高智能,我们不得不浪费四行代码。 毕竟我们的目标是一个面向市场的产品,而不是一个初学者不考虑用户体验的程序。

 function start(){ 
   if("turnover"==nameBak){moreMan([3+"_"+3,4+"_"+3,4+"_"+4,3+"_"+4]); 
   }else if("four"==nameBak){man(minL,minL,nameBak+"_"+row/2+"_"+0); 
   }else if("gogame"==nameBak){moreMan([3+"_"+3,15+"_"+3,15+"_"+15,3+"_"+15]);
   } 
	 }

事实上,调用的是moreMan方法。 请注意,它也是块数据引用。 传输一个字段,纵横坐标用逗号分隔。

使其成为离线应用程序

正如本文开头提到的,桌面计算机上已经有很多单人或多人下棋程序。 只有联通应用才有市场。 我们的目标就是朝着这个方向跑,所以最终一定要做成离线应用。

如何实现HTML5的离线应用,搜索引擎能够快速找到结果,其实只需要三个关键步骤。

第一步; 在Web服务器的配置文件中声明它。 Tomcat和Apache的声明方式不同,需要注意;

步骤2:定义manifest文件,需要注意文件格式;

步骤3:在HTML文件中调用manifest文件。

按照这三个步骤,读者可以自行搜索详细内容,这里不再赘述,只讲搜索引擎查不到的内容。

另外,需要注意的是,iPad和Android平板上的浏览器实现全屏的方式不同。 对于iPad用户来说,我们必须定义一行代码来实现全屏。

效果图、在线演示、开源

本文在线演示网址为: ,效果图如下图所示:

图1.效果图

图中增加了选择棋型和设置背景的功能。 如果想要获取全部源代码,只需要使用浏览器的查看源代码功能即可。 由于篇幅限制,这里就不贴出来了。

官方验证

可惜firefox下棋时没有css效果。 请在 chrome 中测试一下。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

悟空资源网 游戏源码 棋盘游戏源码棋盘游戏源码-HTML5游戏开发教程实战:五子棋、五子棋、围棋、逆棋四种棋类游戏 https://www.wkzy.net/game/170283.html

常见问题

相关文章

官方客服团队

为您解决烦忧 - 24小时在线 专业服务