【亚洲必赢官网】Canvas编写五彩连珠,代码完毕四种双人对弈游戏

百行 HTML5 代码达成四种双人对弈游戏

2012/06/30 · HTML5 · 1
评论 ·
HTML5

来源:于丙超@developerworks

简介: 本文是一个卓殊具有挑衅性的编程,因为 100 行代码,约莫 10000
个字符左右,将促成围棋、五子棋、四子棋和扭转棋四种双人对弈游戏。请小心,那八个对弈游戏不是中低档编程者的习作,而是兼具棋盘、立体棋子、事件、走棋规则判断、输赢判断的总体对弈游戏,并且可以离线存储到
三星平板、Android
平板中,试想一下,把那种娱乐下载到平板中,就足以在高铁,旅游景区,等没有信号的地方开展对弈,是还是不是增添了机械电脑的效益,是或不是一种很满意的事务。而且,关键是,那些顺序尚未图片,不要求去接纳商店付费下载,仅仅是用
HTML5 技术写的 100
行代码而已,相对是现阶段最迷您精悍的双人对弈游戏源码。(编者注:由于网页代码的宽度有限量,所以小编的源代码经过了有些换行处理,特此表明。)

目标

要做一个完好无损的双人对弈游戏,至少要做如下事情,第一步:绘制棋盘。不一样的棋类游戏棋盘分化,那一点亟待开展动态处理;第二步:绘制棋子。须求证实的是,围棋,五子棋等这一个棋子都是圆的啊,请不要为了图片困扰,在
HTML5
时代,大家用代码就可以已毕立体圆形棋子;第三步:判断落子事件。当然是要定位手指的点击地点,那四种棋中,有的是落在框里面的,有的却是落在复杂的棋盘十字线上,要求动态处理;第四步:判断落子规则。下棋都有规则,不要因为代码少,就将规则打折扣,否则程序不成熟,会变成孩子的玩具了;第五步:判断输赢。最终,大家要一口咬定输赢。也就是要数子,这一个工作必须由程序来成功,因为下棋总得须要一个裁定嘛;第六步:就是生硬电脑时代,大家得落到实处离线应用。这几个太紧要了,否则,假诺在台式电脑上,接根网线玩的游艺,已经各处可见了,您写得再牛,有啥样用?就是要运动,在没有信号的地点,才有市场,现在机械,智能手机这么多,在尚未网络信号的地点,掏出活动装备来下棋,才是一件很牛的工作。

绘制棋盘

面前说了围棋、五子棋、四子棋和扭转棋的棋盘并差距,围棋是纵横 18
个格,其余三种棋则是 8
个格。所以绘制棋盘是索要有参数。那是个小意思,大题目是,采取怎么着点子来绘制棋盘?

HTML5 框架下,有最少 3 种办法:第一种,用 Canvas 画线;第二种,用
DIV,CSS3 里面增加了行列属性;第三种,用 table 标签。

用哪种速度最快,代码少啊?答案是:第三种。多少有点失望啊,HTML5
不是全能的。详细代码如下:

XHTML

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(“<div style=\”margin:”+minL+”px;\”> “+
“<table border=1 cellspacing=0 width=\””+(aW*col)+”\”
height=\””+(aH*row)+”\”>”); for(var i=0;i<row;i++){
array.push(“<tr>”); for(var j=0;j<col;j++){array.push(“<td
align=center>”+
evt(i,j,minL,minL,aW*j+minL/2+8,aH*i+minL/2)+”</td>”);}
if(nameBak!=”four”&&nameBak!=”turnover”)/* 将事件添加到表格中 */
array.push(evt(i,col,minL,minL,aW*col+minL/2+8,aH*i+minL/2));
array.push(“</tr>”); } 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(“”)+”</table></div>”);
setClick(row,col,minL,minL);/* 开端化事件 */ start();/* 初阶化棋子
*/ }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
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("<div style=\"margin:"+minL+"px;\"> "+
"<table border=1 cellspacing=0 width=\""+(aW*col)+"\"
height=\""+(aH*row)+"\">");
for(var i=0;i<row;i++){
       array.push("<tr>");
       for(var j=0;j<col;j++){array.push("<td align=center>"+
evt(i,j,minL,minL,aW*j+minL/2+8,aH*i+minL/2)+"</td>");}
       if(nameBak!="four"&&nameBak!="turnover")/* 将事件添加到表格中 */
             array.push(evt(i,col,minL,minL,aW*col+minL/2+8,aH*i+minL/2));
             array.push("</tr>");
}
   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("")+"</table></div>");
setClick(row,col,minL,minL);/* 初始化事件 */
start();/* 初始化棋子 */
}

地点代码中,最重大的是标草书的第 6 行代码,这其间有四个诀窍,首个就是
table 的概念,第三个就是选拔了 Array
数组。为何要动用数组,而不是概念一个字符串呢?答案是优化,就是 Array
数组的 push 方法的速度要远远快于 String 字符串的加 + 运算。共计 16
行代码,一个棋盘就画好了,当然这其间不仅是画线,还有棋子处理,事件定义等措施的调用,前边将接力谈到。

绘图棋子

制图完棋盘,大家来绘制棋子。大家拔取的那四种棋,就算棋盘差距,可是棋子都是同一的,都是黑白棋子。那在从前,做在线对弈,除了
Flash 能落成美观效果外,其他的总得先请美工做几副小图片,HTML5
时代,美工的人力和关系费用就节约了。

咱俩起码有二种方法绘制棋子,第一种是:canvas 类,第二种就是 css
的圆角属性。用哪一种速度又快代码又少吗?答案是第二种,圆角。代码如下:

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
id=\”man_”+color+”_”+order+”\” style=\”display:block;-webkit-”
+r+”-moz-“+r+””+r+”-moz-box-shadow:inset 0 -10px 40px rgba(0,0,0,1);”+
“box-shadow:inset 0 -10px 40px rgba(0,0,0,1);”+
“background:-webkit-gradient(radial, 50 40, 30, center center, 80,
from(#”+color+”), to(rgba(255,255,255,1)));”+
“width:”+width+”px;height:”+height+”px;\”></div>”; }

1
2
3
4
5
6
7
8
9
10
11
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 id=\"man_"+color+"_"+order+"\" style=\"display:block;-webkit-"
   +r+"-moz-"+r+""+r+"-moz-box-shadow:inset 0 -10px 40px rgba(0,0,0,1);"+
   "box-shadow:inset 0 -10px 40px rgba(0,0,0,1);"+
   "background:-webkit-gradient(radial, 50 40, 30, center center, 80, from(#"+color+"),
      to(rgba(255,255,255,1)));"+
   "width:"+width+"px;height:"+height+"px;\"></div>";
}

地点代码中,大家看来,我们将每一个棋子定义了一个 DIV,使用了 CSS3 的
shadow,gradient
属性,并且可以按照棋盘的大小活动测算棋子的轻重缓急,其它,若是用户不欣赏黑白颜色,甚至足以定义成红黄颜色,女人和娃娃估量会喜欢。这5
行代码是画一个棋子的主意,做一个简单的大循环,就足以画出五个棋子,方法如下。

CSS

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

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

处理事件

制图完棋盘和棋子,我们来分析一下用户的动作。用户的动作仅仅就是二种,一种是点击棋盘
table,其余一种就是点击棋子 DIV。难点在点击 table
那里,大家要获知用户点击 table 的职位。

历史观思路可能是那样,使用 event 方法,得到 x,y 的坐标,然后与 table
的左上角做减法,然后再跟单元格 cell 做除法。听起来都忙绿。

若是你仔细阅读了前方的代码,就相应发现,其实在画棋盘是,大家向 array
数组中 push 了一个 evt 方法,很明显,这几个 evt
方法要回到一个字符串变量的,那么她的内容是怎么样呢?答案发布:

CSS

function evt(i,j,width,height,left,top){ /* 单一单元格事件 */ return
“<div id=\””+nameBak+”_”+i+”_”+j+”\” style=\”position:”+
(nameBak==”four”||nameBak==”turnover”?”block”:”absolute”)+ “;border:0px
solid #000;width:”+
width+”px;height:”+height+”px;top:”+top+”px;left:”+left+”px;\”></div>”;
}

1
2
3
4
5
6
function evt(i,j,width,height,left,top){ /* 单一单元格事件 */
  return "<div id=\""+nameBak+"_"+i+"_"+j+"\" style=\"position:"+
(nameBak=="four"||nameBak=="turnover"?"block":"absolute")+
";border:0px solid #000;width:"+
width+"px;height:"+height+"px;top:"+top+"px;left:"+left+"px;\"></div>";
}

规律是一个
DIV。对了,这些添加事件的不二法门充裕分外,实际上是在各样棋盘的交叉的地方画了一个
DIV,然后给 DIV 添加事件。

CSS

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);}; } } }

1
2
3
4
5
6
7
8
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
行代码,把事件问题搞定了。

落子规则

眼前说了,用户点击事件有三种,点击棋盘 table 事件大家拔取额外增加 DIV
的主意巧妙解决了,第三种点击棋子的法门又该怎样呢?

先要表达的是,点击棋子其实是一种错误的轩然大波,点击棋盘可以落子,点击棋子是如何看头?黑白棋点击棋子是架空的,大家不可能不要开展判断,不可能在有子的地点落子,那是平整之一。所以必须求定义一个方法,判断是或不是点击的地点是还是不是有棋子。代码如下:

CSS

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;}

1
2
3
4
5
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 的的再次回到值来判断是不是有子,而是要看清出有啥颜色的子。

对于五子棋和围棋,这一条规则够用了,可是对于翻转棋和四子棋,还有第二条规则:无法在方圆空白的地方落子,就是说必须是延绵不断的。也就是说,不仅仅要判断点击的地点是否有棋子,还要判断其周围是还是不是有棋子,这几个,不是可以有,而是,必须有。要求做一个小循环啊,代码如下:

CSS

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; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
方法,那里再采纳一个小技巧,就可以轻松搞定这一个输赢判断。先看看五子棋和四子棋的高下判断代码,然后相比较代码来分析。

CSS

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; }

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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=[[],[],[],[]],那种概念多维数组的措施,挑出来重点说可瑞康(Karicare)(阿博特(Abbott))下,因为搜索引擎上都是搜不到的,我讲课时差不离遭逢的学员也都不明了,他们大多使用
new Array,然后加循环的蜗牛方法。

其次步:从落子的地点初步循环,注意,不是循环整个棋盘,为的就是节省时间啊。循环设计参差不齐三个趋势,有棋子的地方,就向那几个四维数组
push 棋子的颜色。

其三步:把数组 join 起来就 ok 啦,如果有 4 个或 5 个 1
相连,自然就是白棋胜,否则就是黑棋胜。

涂抹那里,就有点意思啊,注意大家处理的数额的法子,我叫作“块数据”的处理格局,就是充裕利用
array
数组,保存一块一块的数据,无论写入,读取,仍然计算分析,都是指向这一块数据举行,那样既可以增强内聚度,便于提炼出可以拔取的章程,就可以大大的增加速度进行进度。

拍卖相连都不在话下,数子就更简便易行了,使用块数据处理措施,3 行搞定。

CSS

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(num<total/2)alert(“黑棋胜”+(total-num*2)+”子”); else
if(num>row*col/2)alert(“白棋胜”+(num*2-total)+”子”); else
alert(“平局”); }

1
2
3
4
5
6
7
8
9
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(num<total/2)alert("黑棋胜"+(total-num*2)+"子");
else if(num>row*col/2)alert("白棋胜"+(num*2-total)+"子");
else alert("平局");
}

棋子起头化

严密地写到那里,还有最后一个关于棋子的问题亟待处理。那就是,下五子棋是从一贫如洗棋盘伊始,其他三种棋却一开头都是有子的。其实给一个空手棋盘也行,可是其他二种棋因为相似的前几步走法都是稳定的,大家为了增加智能化水平,不得不在浪费四行代码,毕竟,大家的对象是一个市场化的出品,而不是一个初大方不考虑用户体验的主次。

CSS

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]);
} }

1
2
3
4
5
6
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 服务器的陈设文件中声称一下。汤姆(Tom)cat 和 Apache
的扬言形式不雷同,需求留意;

第二步:定义 manifest 文件,文件格式须求留意;

其三步:在 HTML 的公文中调用一下 manifest 文件。

基于那四个步骤,读者可以自行检索细节,那里就不赘述了,我只讲搜索引擎搜不到的。

除此以外索要证实的是,三星GALAXY Tab 和 Android
平板上浏览器落成全屏的措施也不一样,针对 iPad用户,咱们还非得定义一行可以完结全屏的代码。

  1. 职能图、在线演示、开放源代码

正文的在线演示网址是:,效果图如下图所示:

图 1. 效果图

亚洲必赢官网 1

图中加了一个增选棋类型和安装背景效用,如要得到全套源代码,只要选取浏览器的查看源代码功用即可,限于篇幅,这里就不贴了。

总结

用作一个程序员,最高的境地不是写得代码更加多越好,而是用最少的代码完结最多的计量,解决最多的题目。回顾当年,盖茨在编辑
Basic
时,为了节省多少个字符必要心劳计绌夜以继日,以至于遗留了千年虫世纪难题,反观今天,在云计算时代,随着硬盘和内存的容量越来越大,CPU
的运算越来越快,很多大型项目的程序员就像失去了凝练代码的习惯。可是运动计量的硬件,近期还不曾那么高的配置,本文通过
HTML5
对弈游戏,使用“块数据”计算办法,落成了用最少代码完毕最多划算的对象,越发适用移动计量,与大家共勉。

 

赞 收藏 1
评论

亚洲必赢官网 2

简介: 本文是一个不胜富有挑战性的编程,因为 100 行代码,约莫 10000
个字符左右,将贯彻围棋、五子棋、四子棋和扭转棋四种双人对弈游戏。请小心,那三个对弈游戏不是低档编程者的习作,而是具有棋盘、立体棋子、事件、走棋规则判断、输赢判断的共同体对弈游戏,并且能够离线存储到
三星平板、Android
平板中,试想一下,把那种娱乐下载到平板中,就可以在火车,旅游景区,等尚未信号的地点开展对弈,是或不是扩张了华为平板的机能,是否一种很满意的事体。而且,关键是,那么些程序尚未图片,不必要去行使集团付费下载,仅仅是用
HTML5 技术写的 100
行代码而已,相对是眼前最迷您精悍的双人对弈游戏源码。(编者注:由于网页代码的增幅有限量,所以小编的源代码经过了有些换行处理,特此表明。)
目标
要做一个完好的双人对弈游戏,至少要做如下事情,第一步:绘制棋盘。分化的棋类游戏棋盘不一样,那点亟需进行动态处理;第二步:绘制棋子。要求验证的是,围棋,五子棋等那么些棋子都是圆的呀,请不要为了图片苦恼,在
HTML5
时代,大家用代码就足以兑现立体圆形棋子;第三步:判断落子事件。当然是要定点手指的点击地点,那四种棋中,有的是落在框里面的,有的却是落在纷纷的棋盘十字线上,须要动态处理;第四步:判断落子规则。下棋都有平整,不要因为代码少,就将规则打折扣,否则程序不成熟,会成为孩子的玩具了;第五步:判断输赢。最终,我们要看清输赢。也就是要数子,这一个工作必须由程序来成功,因为下棋总得必要一个评判嘛;第六步:就是干巴巴计算机时代,我们得落实离线应用。那些太重大了,否则,即使在台式电脑上,接根网线玩的玩耍,已经随地可见了,您写得再牛,有如何用?就是要运动,在尚未信号的地方,才有市场,现在机械,智能手机这么多,在并未网络信号的地点,掏出活动装备来下棋,才是一件很牛的政工。
绘制棋盘
眼前说了围棋、五子棋、四子棋和扭转棋的棋盘并不同,围棋是纵横 18
个格,其余二种棋则是 8
个格。所以绘制棋盘是索要有参数。那是个小题目,大题目是,选拔什么艺术来绘制棋盘?
HTML5 框架下,有至少 3 种方式:第一种,用 Canvas 画线;第三种,用
DIV,CSS3 里面伸张了行列属性;第三种,用 table 标签。
用哪一类速度最快,代码少吗?答案是:第两种。多少有点失望啊,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(“<div style=\”margin:”+minL+”px;\”> “+
 “<table border=1 cellspacing=0 width=\””+(aW*col)+”\”
 height=\””+(aH*row)+”\”>”);
 for(var i=0;i<row;i++){
       array.push(“<tr>”);
       for(var j=0;j<col;j++){array.push(“<td align=center>”+
 evt(i,j,minL,minL,aW*j+minL/2+8,aH*i+minL/2)+”</td>”);}
       if(nameBak!=”four”&&nameBak!=”turnover”)/* 将事件添加到表格中
*/
            
array.push(evt(i,col,minL,minL,aW*col+minL/2+8,aH*i+minL/2));
             array.push(“</tr>”);
         }
       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(“”)+”</table></div>”);
 setClick(row,col,minL,minL);/* 开端化事件 */
 start();/* 开首化棋子 *【亚洲必赢官网】Canvas编写五彩连珠,代码完毕四种双人对弈游戏。/
     }
地方代码中,最重点的是标大篆的第 6 行代码,那之中有三个门槛,第四个就是
table 的定义,第一个就是应用了 Array
数组。为啥要利用数组,而不是概念一个字符串呢?答案是优化,就是 Array
数组的 push 方法的速度要远远快于 String 字符串的加 + 运算。共计 16
行代码,一个棋盘就画好了,当然那之中不仅是画线,还有棋子处理,事件定义等方法的调用,前边将陆续谈到。
绘图棋子
绘制完棋盘,大家来绘制棋子。大家挑选的那四种棋,即使棋盘分歧,不过棋子都是如出一辙的,都是黑白棋子。那在往日,做在线对弈,除了
Flash 能达成美丽效果外,其余的总得先请美工做几副小图片,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 id=\”man_”+color+”_”+order+”\”
style=\”display:block;-webkit-“
   +r+”-moz-“+r+””+r+”-moz-box-shadow:inset 0 -10px 40px
rgba(0,0,0,1);”+
   “box-shadow:inset 0 -10px 40px rgba(0,0,0,1);”+
   “background:-webkit-gradient(radial, 50 40, 30, center center, 80,
from(#”+color+”),
      to(rgba(255,255,255,1)));”+
   “width:”+width+”px;height:”+height+”px;\”></div>”;
     }
上面代码中,大家看来,我们将每一个棋子定义了一个 DIV,使用了 CSS3 的
shadow,gradient
属性,并且可以根据棋盘的轻重活动测算棋子的轻重,此外,如果用户不喜欢黑白颜色,甚至足以定义成红黄颜色,女人和幼儿估量会喜欢。那5
行代码是画一个棋子的章程,做一个粗略的巡回,就可以画出多个棋子,方法如下。
 
function moreMan(array){for(var i=0;i<array.length;i++)
man(minL,minL,nameBak+”_”+array[i]);}
/* 绘制多个棋子 */
处理事件
绘制完棋盘和棋子,我们来分析一下用户的动作。用户的动作仅仅就是两种,一种是点击棋盘
table,别的一种就是点击棋子 DIV。难点在点击 table
这里,大家要获知用户点击 table 的职位。
观念思路可能是这么,使用 event 方法,获得 x,y 的坐标,然后与 table
的左上角做减法,然后再跟单元格 cell 做除法。听起来都劳苦。
比方您精心翻阅了前方的代码,就相应发现,其实在画棋盘是,大家向 array
数组中 push 了一个 evt 方法,很驾驭,那个 evt
方法要回到一个字符串变量的,那么他的始末是怎么样吧?答案公布:
 
function evt(i,j,width,height,left,top){ /* 单一单元格事件 */
  return “<div id=\””+nameBak+”_”+i+”_”+j+”\”
style=\”position:”+
 (nameBak==”four”||nameBak==”turnover”?”block”:”absolute”)+
 “;border:0px solid #000;width:”+
 width+”px;height:”+height+”px;top:”+top+”px;left:”+left+”px;\”></div>”;
     }
原理是一个
DIV。对了,那些添加事件的形式丰盛特殊,实际上是在每个棋盘的接力的地方画了一个
DIV,然后给 DIV 添加事件。
 
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
行代码,把事件问题搞定了。
落子规则
眼前说了,用户点击事件有二种,点击棋盘 table 事件大家采纳额外扩大 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=[[],[],[],[]],那种概念多维数组的点子,挑出来重点说贝拉米下,因为搜索引擎上都是搜不到的,我讲解时大都遭受的学童也都不知情,他们大都选用new Array,然后加循环的蜗牛方法。
第二步:从落子的地方开始循环,注意,不是循环整个棋盘,为的就是节省时间啊。循环设计犬牙相制八个趋势,有棋子的地方,就向那么些四维数组
push 棋子的颜色。
其三步:把数组 join 起来就 ok 啦,若是有 4 个或 5 个 1
相连,自然就是白棋胜,否则就是黑棋胜。
涂抹那里,就有点意思啊,注意大家处理的数码的章程,我叫作“块数据”的拍卖措施,就是丰裕利用
array
数组,保存一块一块的多少,无论写入,读取,依旧统计分析,都是对准这一块数据开展,那样既可以增加内聚度,便于提炼出可以引用的方法,就足以大大的加速实施进度。
处理相连都不在话下,数子就更简明了,使用块数据处理办法,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(num<total/2)alert(“黑棋胜”+(total-num*2)+”子”);
 else if(num>row*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 服务器的安顿文件中宣示一下。汤姆(Tom)cat 和 Apache
的宣示方式不等同,须要留意;
其次步:定义 manifest 文件,文件格式须求注意;
其三步:在 HTML 的文本中调用一下 manifest 文件。
根据那多个步骤,读者可以活动检索细节,那里就不赘述了,我只讲搜索引擎搜不到的。
其余索要表达的是,三星平板 和 Android
平板上浏览器落成全屏的方法也不等同,针对 iPad用户,大家还非得定义一行可以已毕全屏的代码。

这只是一个不难易行的JAVAscript和HTML5小程序,没有兑现人机对阵。
五子棋棋盘落子点对应的二维数组。数组的因素对应落子点。比如数组元素值为0表示该因素对应的落子点没有棋子,数组元素值为1象征该因素对应的落子点有白棋子,数组元素值为2代表该因素对应的落子点有黑棋子;
认清五子棋赢棋的算法是透过对五子棋棋盘落子点对应的二维数组的操作来落实的。

在看了几篇Canvas相关的小说后,发现前两节的代码完结仍然有问题,因为了然的少,所以只好在融洽已知的知识上做已毕。但是还好,那是一个发觉的历程,也是一个纠错和周详的长河。我第一回尝试一边上学一次写博客,我想那也有助我的读书,可以把知识了解的稳固些,起码忘的慢一些呢:)。

  1. 功能图、在线演示、开放源代码
    职能图如下图所示:
    图 1. 效果图

判定五子棋赢棋算法
上面的函数能够兑现判断五子棋赢棋的算法,也能够根据教材中相应的算法达成。
中间函数的参数xx.yy为数组下标,chess数组完毕五子棋棋盘落子点的数据结构映射。
算法的思辨方法是:以当下降子点对应的下标为重心,向其周围8个样子拓展检索,如若有同色子连五子,再次回到1,或2,否则重回0。再次回到1表示白棋方胜,再次来到2象征黑棋方胜。重临0代表没有发出赢棋数据结构状态。
亚洲必赢官网 3 
亚洲必赢官网 4
亚洲必赢官网 5 

  前两节学习了多少个主导绘制的主意,line汤姆oveTo和arc,也询问坐标的气象,但写的可比傻,只是单纯的完成。
比如棋盘的发端坐标如若有偏移量,大家还要计算他的现实性初叶坐标和终止坐标,实际上Canvas有古已有之的格局提供偏移的成效。
他叫
translate,此外还有缩放scale、旋转rotate,他们都得以用transform代替。所以,在代码方面还会微微调整。不过这几个的就学恰巧也让自己晓得什么样促成动画效果。要是七个要素在一个Canvas上,达成动画,必然会需要擦除重绘的情景,倘诺元素之间有覆盖的场合,擦除就要求多着想了。当然,不难的艺术就是把全路画布依照当然所有因素的岗位再次绘制五回。所以在代码设计方面,须求把不一致的元素独立出来,每个元素都有协调的draw方法,并且要遵守程序绘制Canvas。

亚洲必赢官网 6
图中加了一个摘取棋类型和装置背景功用,如要得到全套源代码,只要采纳浏览器的查看源代码功用即可,限于篇幅,这里就不贴了。
总结
用作一个程序员,最高的地步不是写得代码更多越好,而是用最少的代码完毕最多的总计,解决最多的问题。回看当年,盖茨在编制
Basic
时,为了节省多少个字符须求冥思苦想焚膏继晷,以至于遗留了千年虫世纪难题,反观后天,在云总结时代,随着硬盘和内存的容量越来越大,CPU
的运算越来越快,很多大型项目标程序员就像失去了精简代码的习惯。但是运动计量的硬件,近来还没有那么高的安顿,本文通过
HTML5
对弈游戏,使用“块数据”总结格局,达成了用至少代码完成最多划算的对象,越发适用移动计量,与我们共勉。
 

复制代码 代码如下:

  分析一下嬉戏所需的要素:1、棋盘(地图)2、泡泡
3、等待区域(新的3个即将进入棋盘的泡泡)4、奖励区域(白搭星、一级百搭星、炸弹)5、计算新闻6、按钮
  所以在目标的规划方面起码要有几类
棋盘(map)、新泡泡区(ready)、奖励区(awards)、泡泡(bubble)、星星1(star1)
、星星2(star2)
、炸弹(boom)、总括积分(score),还要包含游戏背后的数量(data)。
OK,先那样设计,挨个的去落到实处。先把map和bubble重写了。
  之前把map写成了类,分明是不确切的,因为那么些游乐无法会有三个map,所以直接定义为对象更有益于。而泡沫明显必要广大,所以需求写成类相比有利。游戏之中装有目的急需拜访的全局变量和常量须求定义在一个game对象里,游戏开首则是调用game.start()的法门。所以先看下game的定义:

本文是一个万分富有挑衅性的编程,因为 100
行代码,约莫 10000
个字符左右,将落到实处围棋、五子棋、四子棋和扭转棋四种双人对弈游…

<!DOCTYPE html>
< html xmlns=”;
< head>
<meta http-equiv=”Content-Type” content=”text/html; charset=utf-8″
/>
<title></title>
<style type=”text/css”>
body {
margin: 10px;
}
</style>
<script type=”text/javascript”>
var canvas;
var context;
var is惠特e = true;//设置是不是该轮到白棋
var isWell = false;//设置该局棋盘是不是赢了,假设赢了就不可以再走了
var img_b = new Image();
img_b.src = “images/b.png”;//白棋图片
var img_w = new Image();
img_w.src = “images/w.png”;//黑棋图片
var chessData = new
Array(15);//那一个为棋盘的二维数组用来保存棋盘新闻,初叶化0为没有度过的,1为白棋走的,2为黑棋走的
for (var x = 0; x < 15; x++) {
chessData[x] = new Array(15);
for (var y = 0; y < 15; y++) {
chessData[x][y] = 0;
}
}
function drawRect() {//页面加载已毕调用函数,开头化棋盘
canvas = document.getElementById(“canvas”);
context = canvas.getContext(“2d”);
for (var i = 0; i <= 640; i += 40) {//绘制棋盘的线
context.beginPath();
context.moveTo(0, i);
context.lineTo(640, i);
context.closePath();
context.stroke();
context.beginPath();
context.moveTo(i, 0);
context.lineTo(i, 640);
context.closePath();
context.stroke();
}
}
function play(e) {//鼠标点击时暴发
var x = parseInt((e.clientX – 20) /
40);//统计鼠标点击的区域,要是点击了(65,65),那么就是点击了(1,1)的岗位
var y = parseInt((e.clientY – 20) / 40);
if (chessData[x][y] != 0) {//判断该职位是还是不是被下过了
alert(“你不可以在那些职分下棋”);
return;
}
if (isWhite) {
isWhite = false;
drawChess(1, x, y);
}
else {
isWhite = true;
drawChess(2, x, y);
}
}
function drawChess(chess, x, y)
{//参数为,棋(1为白棋,2为黑棋),数组地方
if (isWell == true) {
alert(“已经完毕了,如果急需重新玩,请刷新”);
return;
}
if (x >= 0 && x < 15 && y >= 0 && y < 15) {
if (chess == 1) {
context.drawImage(img_w, x * 40 + 20, y * 40 + 20);//绘制白棋
chessData[x][y] = 1;
}
else {
context.drawImage(img_b, x * 40 + 20, y * 40 + 20);
chessData[x][y] = 2;
}
judge(x, y, chess);
}
}
function judge(x, y, chess) {//判断该局棋盘是还是不是赢了
var count1 = 0;
var count2 = 0;
var count3 = 0;
var count4 = 0;
//左右断定
for (var i = x; i >= 0; i–) {
if (chessData
[y] != chess) {
break;
}
count1++;
}
for (var i = x + 1; i < 15; i++) {
if (chessData
[y] != chess) {
break;
}
count1++;
}
//上下判断
for (var i = y; i >= 0; i–) {
if (chessData[x]
!= chess) {
break;
}
count2++;
}
for (var i = y + 1; i < 15; i++) {
if (chessData[x]
!= chess) {
break;
}
count2++;
}
//左上右下判断
for (var i = x, j = y; i >= 0, j >= 0; i–, j–) {
if (chessData
[j] != chess) {
break;
}
count3++;
}
for (var i = x + 1, j = y + 1; i < 15, j < 15; i++, j++) {
if (chessData
[j] != chess) {
break;
}
count3++;
}
//右上左下判断
for (var i = x, j = y; i >= 0, j < 15; i–, j++) {
if (chessData
[j] != chess) {
break;
}
count4++;
}
for (var i = x + 1, j = y – 1; i < 15, j >= 0; i++, j–) {
if (chessData
[j] != chess) {
break;
}
count4++;
}
if (count1 >= 5 || count2 >= 5 || count3 >= 5 || count4 >=
5) {
if (chess == 1) {
alert(“白棋赢了”);
}
else {
alert(“黑棋赢了”);
}
isWell = true;//设置该局棋盘已经赢了,不得以再走了
}
}
</script>
< /head>
< body onload=”drawRect()”>
<div>
<canvas width=”640″ id=”canvas” onmousedown=”play(event)”
height=”640″>你的浏览器不帮助HTML5 canvas,请使用 google chrome
浏览器 打开.
</canvas>
</div>
< /body>
< /html>

[javascript]
var game = { canvas: document.getElementById(“canvas”), ctx:
this.canvas.getContext(“2d”), cellCount: 9, cellWidth: 30, lineCount: 5,
mode: 7, colors: [“red”, “#039518”, “#ff00dc”, “#ff6a00”, “gray”,
“#0094ff”, “#d2ce00”], over: function () { alert(“GAME OVER”); },
getRandom: function (max) { return parseInt(Math.random() * 1000000 %
(max)); }, }; 

你或许感兴趣的稿子:

  • 纯JS已毕五子棋游戏包容各浏览器(附源码)
  • JavaScript
    井字棋人工智能完结代码
  • javascript
    7行代码画出一个围棋棋盘
  • 中国象棋js代码,仅演示,未能真下
  • JS小游戏之象棋暗棋源码详解
  • 诘屈聱牙之javascript中国象棋
  • js 钻石棋网页游戏代码
  • 原生JS+Canvas完结五子棋游戏实例
  • 原生JS+Canvas完结五子棋游戏
  • 基于JavaScript完结五子棋游戏
  • html5 canvas-1.canvas介绍(hello
    canvas)

var game = { canvas: document.getElementById(“canvas”), ctx:
this.canvas.getContext(“2d”), cellCount: 9, cellWidth: 30, lineCount: 5,
mode: 7, colors: [“red”, “#039518”, “#ff00dc”, “#ff6a00”, “gray”,
“#0094ff”, “#d2ce00”], over: function () { alert(“GAME OVER”); },
getRandom: function (max) { return parseInt(Math.random() * 1000000 %
(max)); }, };
 cellCount就是格子的总额,cellwidth是每个格子的小幅,因为不仅map里必要那几个,所以就定义在了那边,mode
是游玩格局 5是概括 7是辛劳。
 再看下map的代码:

[javascript]
game.map = { startX: 40.5, startY: 60.5, width: game.cellCount *
game.cellWidth, height: game.cellCount * game.cellWidth, bubbles: [],
init: function () { for (var i = 0; i < game.cellCount; i++) { var
row = []; for (var j = 0; j < game.cellCount; j++) { row.push(new
Bubble(i, j, null)); } this.bubbles.push(row); } }, draw: function () {
var ctx = game.ctx; ctx.save(); ctx.translate(this.startX, this.startY);
ctx.beginPath(); for (var i = 0; i <= 9; i++) { var p1 = i *
game.cellWidth;; ctx.moveTo(p1, 0); ctx.lineTo(p1, this.height); var p2
= i * game.cellWidth; ctx.moveTo(0, p2); ctx.lineTo(this.width, p2); }
ctx.strokeStyle = “#555”; ctx.stroke();
//绘制子元素(所有在棋盘上的泡) this.bubbles.forEach(function (row) {
row.forEach(function (bubble) { bubble.draw(); }); }); ctx.restore(); },
addBubble: function (bubble) { var thisBubble =
this.bubbles[bubble.x][bubble.y]; thisBubble.color = bubble.color;
}, getBubble: function (x, y) { var thisBubble = this.bubbles[x][y];
if (!thisBubble.color) { return null; } else { return thisBubble; } }
}; 

game.map = { startX: 40.5, startY: 60.5, width: game.cellCount *
game.cellWidth, height: game.cellCount * game.cellWidth, bubbles: [],
init: function () { for (var i = 0; i < game.cellCount; i++) { var
row = []; for (var j = 0; j < game.cellCount; j++) { row.push(new
Bubble(i, j, null)); } this.bubbles.push(row); } }, draw: function () {
var ctx = game.ctx; ctx.save(); ctx.translate(this.startX, this.startY);
ctx.beginPath(); for (var i = 0; i <= 9; i++) { var p1 = i *
game.cellWidth;; ctx.moveTo(p1, 0); ctx.lineTo(p1, this.height); var p2
= i * game.cellWidth; ctx.moveTo(0, p2); ctx.lineTo(this.width, p2); }
ctx.strokeStyle = “#555”; ctx.stroke();
//绘制子元素(所有在棋盘上的泡) this.bubbles.forEach(function (row) {
row.forEach(function (bubble) { bubble.draw(); }); }); ctx.restore(); },
addBubble: function (bubble) { var thisBubble =
this.bubbles[bubble.x][bubble.y]; thisBubble.color = bubble.color;
}, getBubble: function (x, y) { var thisBubble = this.bubbles[x][y];
if (!thisBubble.color) { return null; } else { return thisBubble; } }
};
map的init开端化方法里我先把拥有的泡泡安插好了,可是都不曾染色,我并没有在ui的私自维护一个数组,因为自身觉着泡泡有没有颜色就表示
0,1了,所以就那样也行。
draw方法不再想此前那么把开始坐标总结进去了,而是采纳了translate方法,那样就很方便写代码了。
addBubble其实就是染色而已,接收参数是一个泡泡对象,那些目的来自ready区域的泡沫。

Ready区域实际就像是俄联邦方块那样,有多个备选的泡沫即将进入map区域。

[javascript]
game.ready = { startX: 40.5, startY: 20.5, width: game.cellWidth * 3,
height: game.cellWidth, bubbles: [], init: function () {
this.genrate(); var me = this; me.flyin(); }, genrate: function () { for
(var i = 0; i < 3; i++) { var color =
game.colors[game.getRandom(game.mode)]; this.bubbles.push(new
Bubble(i, 0, color)); } }, draw: function () { var ctx = game.ctx;
ctx.save(); ctx.translate(this.startX, this.startY); ctx.beginPath();
ctx.strokeStyle = “#555”; ctx.strokeRect(0, 0, this.width,
this.height); ctx.stroke(); //绘制准备的泡 this.bubbles.forEach(function
(bubble) { bubble.draw(); }); ctx.restore(); }, }; 

game.ready = { startX: 40.5, startY: 20.5, width: game.cellWidth * 3,
height: game.cellWidth, bubbles: [], init: function () {
this.genrate(); var me = this; me.flyin(); }, genrate: function () { for
(var i = 0; i < 3; i++) { var color =
game.colors[game.getRandom(game.mode)]; this.bubbles.push(new
Bubble(i, 0, color)); } }, draw: function () { var ctx = game.ctx;
ctx.save(); ctx.translate(this.startX, this.startY); ctx.beginPath();
ctx.strokeStyle = “#555”; ctx.strokeRect(0, 0, this.width,
this.height); ctx.stroke(); //绘制准备的泡 this.bubbles.forEach(function
(bubble) { bubble.draw(); }); ctx.restore(); }, };
ready.init
起先化3个泡泡,并且把那3个泡泡“飞入”到map里,ready.draw很粗略就是绘制一个小矩形和3个泡泡。

嗯,对了,我们的泡沫的绘图代码也稍作了修改,现在的旗帜不是前边的纯色了,有了水晶效果。。。不妨看看:

[javascript]
Bubble.prototype.draw = function () { if (!this.color) { return; } var
ctx = game.ctx; ctx.beginPath(); //console.log(“x:” + px + “y:” + py);
var gradient = ctx.createRadialGradient(this.px – 5, this.py – 5, 0,
this.px, this.py, this.light); gradient.addColorStop(0, “white”);
gradient.addColorStop(1, this.color); ctx.arc(this.px, this.py, 11, 0,
Math.PI * 2); ctx.strokeStyle = this.color; ctx.fillStyle = gradient;
ctx.fill(); ctx.stroke(); }; 

 Bubble.prototype.draw = function () { if (!this.color) { return; } var
ctx = game.ctx; ctx.beginPath(); //console.log(“x:” + px + “y:” + py);
var gradient = ctx.createRadialGradient(this.px – 5, this.py – 5, 0,
this.px, this.py, this.light); gradient.addColorStop(0, “white”);
gradient.addColorStop(1, this.color); ctx.arc(this.px, this.py, 11, 0,
Math.PI * 2); ctx.strokeStyle = this.color; ctx.fillStyle = gradient;
ctx.fill(); ctx.stroke(); };
 createRadialGradient方法是画一个放射性的圆,开首在左上角,那样就有个光照效果,如故不错的。
看下效果图吧
  亚洲必赢官网 7

摘自  君之蘭
 

网站地图xml地图