xml地图|网站地图|网站标签 [设为首页] [加入收藏]
代码实现四种双人对弈游戏
分类:web前端

百行 HTML5 代码实现四种双人博弈游戏

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

来源:于丙超@developerworks

简介: 本文是三个不胜富有挑衅性的编制程序,因为 100 行代码,大略 一千0 个字符左右,将贯彻围棋、五子棋、四子棋和扭转棋多样双人博艺游戏。请在意,这多少个博弈游戏不是下等编制程序者的习作,而是全数棋盘、立体棋子、事件、走棋准绳判定、输赢判别的总体博艺游戏,况且能够离线存储到 三星GALAXY Tab、Android 平板中,试想一下,把这种游戏下载到平板中,就能够在列车,旅游景区,等尚未数字信号的地方开展博弈,是否增添了平板Computer的法力,是或不是大器晚成种很乐意的业务。而且,关键是,那么些程序没有图片,没有要求去行使公司付费下载,仅仅是用 HTML5 技巧写的 100 行代码而已,相对是现阶段最迷您精悍的双人博艺游戏源码。(编者注:由于网页代码的大幅度有限定,所以作者的源代码经过了部分换行管理,特此表明。)

目标

要做一个安然照旧的双人博艺游戏,起码要做如下事情,第一步:绘制棋盘。分化的棋牌游戏棋盘区别,那一点需求举办动态管理;第二步:绘制棋子。须求表明的是,围棋,五子棋等这个棋子都以圆的哟,请不要为了图片烦恼,在 HTML5 时期,咱们用代码就可以完结立体圆形棋子;第三步:剖断落子事件。当然是要固定手指的点击地点,这种种棋中,有的是落在框里面包车型大巴,有的却是落在纵横交叉的棋盘十字线上,须求动态管理;第四步:推断落子法规。下棋都有平整,不要因为代码少,就将准则优惠扣,不然程序不成熟,会化为孩子的玩意儿了;第五步:推断输赢。最终,大家要判定输赢。也便是要数子,那么些业必得需由程序来产生,因为下棋总得必要三个裁定嘛;第六步:正是刚毅电脑时期,大家得完毕离线应用。这么些太首要了,不然,假如在台式计算机上,接根网线玩的游戏,已经四处都是了,您写得再牛,有啥用?就是要活动,在并未有实信号的位置,才有商铺,现在机械,智能手提式有线电话机这么多,在平昔不网络非确定性信号的地点,掏出活动设备来下棋,才是生机勃勃件很牛的职业。

绘图棋盘

眼下说了围棋、五子棋、四子棋和扭转棋的棋盘并差别样,围棋是驰骋 20个格,其余两种棋则是 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 行左右的代码,其实程序基本上可用了,但是大家不可能满意啊,还得让他更是智能一些,大家还索要三个评剖断输赢。

看清输赢

要认清输赢,我们务须求驾驭下棋的规行矩步:

五子棋是逐意气风发方向的五子相连算赢,四子棋是各类方向四个子相连算赢,翻转棋数棋子的个数,围棋则要麻烦些,不仅数棋子个数,还要数围住的区域。

逻辑上临近很复杂啊,就如也是计量最多的地点,有一点智能AI的情致。没错,倘使前方的底子打得不佳,这里确确实实要消耗点不西夏码,然则因为大家前边定义了 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=[[],[],[],[]],这种概念多维数组的秘技,挑出来入眼说美素佳儿下,因为搜索引擎上都是搜不到的,小编执教时大概遇到的学生也都不精晓,他们大都使用 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 方法,注意也是块数据援用,传输了多个数组,用下划线分割横向和纵向坐标。

做成离线应用

本文领头就说过,台式Computer的双人或四人博艺程序已经不可胜举烂大街了,唯有移动应用才干有市集,大家的目标正是奔着那么些来的,所以最终必需做成离线应用。

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

先是步;在 Web 服务器的安排文件中声称一下。汤姆cat 和 Apache 的扬言形式不雷同,须要在乎;

第二步:定义 manifest 文件,文件格式必要在乎;

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

据他们说那七个步骤,读者能够自动物检疫索细节,这里就不赘述了,笔者只讲搜索引擎搜不到的。

除此以外部要求要验证的是,GALAXY Tab 和 Android 平板上浏览器完毕全屏的艺术也不郁郁苍苍致,针对 三星GALAXY Tab客商,大家还必得定义如日方升行能够落成全屏的代码。

  1. 功效图、在线演示、开放源代码

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

图 1. 效果图

澳门新葡亰手机版 1

图中加了八个挑选棋类型和安装背景作用,如要获得全套源代码,只要利用浏览器的查看源代码作用就可以,限于篇幅,这里就不贴了。

总结

用作八个工程师,最高的境界不是写得代码越多越好,而是用最少的代码实现最多的简政放权,消除最多的标题。回顾当年,盖茨在编排 Basic 时,为了省去多少个字符须求思前想后燃膏继晷,以致于遗留了千年虫世纪难点,反观前几天,在云计算时期,随着硬盘和内部存款和储蓄器的体量越来越大,CPU 的运算越来越快,非常多大型项指标工程师就好像失去了简要代码的习贯。可是运动计量的硬件,目前还尚未那么高的布置,本文通过 HTML5 博艺游戏,使用“块数据”总括方法,达成了用起码代码完成最多划算的目的,非常适用移动计量,与大家共勉。

 

赞 收藏 1 评论

澳门新葡亰手机版 2

危险的 target=”_blank” 与 “opener”

2018/09/05 · JavaScript · target

原来的文章出处: 创宇前端   

澳门新葡亰手机版 3

在网页中选择链接时,假使想要让浏览器自动在新的标签页展开钦定的地方,经常的做法就是在 a 标签上增加 target等于"_blank" 属性。

不过,便是其意气风发性格,为钓鱼攻击者带来了可乘之机。

李秉骏:在Phonegap下实现oAuth认证

2012/07/18 · HTML5 · 2 评论 · 来源: 李秉骏     · HTML5

本文由李秉骏(@CashLee李秉骏)投稿于伯乐在线,也接待任何朋友投稿。提醒:投稿时记念留下和讯账号哦 澳门新葡亰手机版 4

方今做过五回关于Phonegap的现场沟通会议分享。基本上把Phonegap的局地特点和豪门沟通了热气腾腾晃,我们对于Phonegap的 兴趣也是相当的多的。不过因为Phonegap相对于原生应用来讲,唯有多个View,这些View正是叁个Web的容器,那使得Phonegap就存在非常多限制。在那之中有个别的限量大家曾经经过HTML5的API以致Phonegap为大家搭建的桥去完毕了,别的一些大家就得经过Phonegap plugins来完毕,而实质上本人个人感到Phonegap最苍劲的地点也在于有那么大的一个部落在为她提供琳琅满指标Plugins,以便去应对实在项 目中相见的主题素材。

自个儿纪念在和豪门交流的时候大家日常会问Phonegap如何做本地的缓存啊(WebSQL),怎么着近乎原生应用(那几个关系到架构,分界面渲染难题,这 里本身也不好深刻讲,终究不是本文要商量的剧情),还有贰个很发烧的难点正是黄金年代旦要做一个开放平台的选择,怎么着落到实处oAuth认证。从前自身也境遇过类似的一 些情形,当自家再也相见这一个棘手的主题材料的时候,笔者唯命是从一定会将也是有Phonegap的观众碰到类似的地方包车型地铁。于是自个儿就计算下来何我们讨论一下什么化解那几个主题素材吧。

先是目的:消除oAuth认证。

拟虞升卿顿:1. 知道oAuth原理;2.精晓Phonegap在拍卖那些难题时候的运维机制;3. 制定布置贯彻代码。

上边大家就来一步一步地分析,看哪样消除那个状态呢。(因为自个儿在类型中遇见的是Tencent腾讯网开放平台的oAuth认证,那么上面笔者就用TencentoAuth认证为例吧)

有关oAuth认证,相信做过开放平台应用的相恋的人都早就足够熟稔了,尽管您还从来不做过照旧对于oAuth认证流程特不打听,那么小编建议您先精通一 下原理,在这里地自个儿不指望花太多的字数去介绍那一个东西,因为在比很多地点都足以找到,下边小编推荐八个地点方便我们去读书,一定要读书,那会对你精通下边包车型地铁稿子 有可观的推来推去的。

Tencent天涯论坛开放平台:

博客园今日头条开放平台:

理所必然在这里处上面须求演讲表明的是oAuth认证机制是一个通用的花招,不过因为各样开放平台有协调的攻略,因而大概在中间稍有改换,并且最后赢得的权位也会各个地区别。而近日博客园乐乎实在太多坑爹的事务了,实在忍受不住,于是小编转战到Tencent的平台了。

好的,借使您看完了oAuth认证的流水生产线,就直接到这里来。深入人心,在oAuth认证的流程中,有八个授权页面,而那一个授权页面是透过开放平台提供的,具体的体裁见下图:

澳门新葡亰手机版 5

本条页面用于输入开放平台的帐户以致密码,通过授权获取响应的openid以致openkey,最后换取access-token(待会作者会结合Tencent果壳网oAuth认证流程的特征,以致代码和我们深入分析的)。

本条页面是弹出的,倘诺在Phonegap里面做的话会很想获得:1,因为属于弹窗,在Phonegap中本身正是三个WebView假若你还弹的话 就能飞到了Safari的浏览器中,那就跳出应用本身,跳出来认证还应该有戏呢?2,通过iFrame,首先体验拾贰分倒霉,其次iFrame自身又属于跨域的 难题,那就不佳解决了(为何体验倒霉吧,首要是因为授权页面包车型大巴体裁是不固定的,类似Tencent和讯开放平台,就比网易的授权页面做得差,根本不和手提式有线话机包容的, 何况有个别做得好的,认证页宽度正是320px,就占了您任何应用的版面,体验很倒霉)那么Phonegap中该怎么促成啊?

带着主题素材,大家就可望在Phonegap中重复引进贰个WebView。刚刚提到Phonegap的苍劲还在于很几个人以至合法的团队,为其提供了黄金时代套很好的插件机制,以消除五颜六色的内需。在Phonegap中有一个插件叫做ChildBrowser,望文生义便是:子浏览器。(其实小编在上一回的 Phonegap专项论题技能分享中甚至聊到到让大家用这一个东西去消除,可是当下享受时间有限只可以够草率带过,抱歉)子浏览器的功力其实就是令你在 Phonegap应用内部调起三个浏览器的View,令你实行pdf,图片,录制,以致网页阅读的工具。(实际上你看本身下面的截图,就是用 ChildBrowser来达成的)那就好了,那就足以让您调起浏览器何况不跳出应用本身了,能够很好地化解oAuth认证的标题。 ChildBrowser下载地址:

在地方上边,你应有已经见到ChildBrowser的安装方式以致采纳方法了,特别简单,真正的即插即用。若是你感觉英语太难,那笔者就帮不了你 了,你就机关谷歌(Google)翻译一下吧。相信你连忙就足以做出多个ChildBrowser的德姆o的。在这里个地址上面,其实你回到上旭日初升层目录,其实您也 已经观看有滋有味的Phonegap Plugins,通过这么些事物,你还是可以调用起手提式有线话机内部更加多有意思的能源的!这些将要靠你和谐去开采啦!(其余平台的运用也可以有照顾的插件的Android开荒者不要骂果粉哦!)

好了日益地大家将在涉及到代码部分了。首先大家看看调用ChildBrowser的Javascript代码:

JavaScript

cb = window.plugins.childBrowser; /* if(cb != null) { cb.onLocationChange = function(loc){ root.locChanged(loc); };//地址爆发更换时候试行的函数 cb.onClose = function(){root.onCloseBrowser(); };//通过js关闭ChildBrowser的不二等秘书籍cb.onOpenExternal = function(){root.onOpenExternal(); }; */ cb.showWebPage("");

1
2
3
4
5
6
7
8
        cb = window.plugins.childBrowser;
/*
        if(cb != null) {
        cb.onLocationChange = function(loc){ root.locChanged(loc); };//地址发生改变时候执行的函数
        cb.onClose = function(){root.onCloseBrowser(); };//通过js关闭ChildBrowser的办法
        cb.onOpenExternal = function(){root.onOpenExternal(); };
*/
        cb.showWebPage("http://google.com");

里面cb正是开首化的ChildBrowser,而showWebPage正是调起那些页面包车型客车艺术。可见代码中要开荒的网站正是谷歌(Google).com啦,那个地球人都能够看得懂了。于是大家就足以立时想到我们要用ChildBrowser张开的网站是我们在英特网钦定的运用授权站点 了。而自个儿是布置在SAE上边的,所以上面包车型客车例证也用PHP来讲吧,期望语言也是一样的道理,转义就能够了。在说代码在此之前,大家先来讲说现实通信的流水生产线,以致大家接下去要高达的对象。

澳门新葡亰手机版 6
在这里处,大家的手提式有线电话机端是通过会见SAE服务器,由SAE服务器管理数据并与腾讯和讯开放平台通信的,这里手提式有线电话机端并从未直接和Tencent天涯论坛开放平台通信(笔者那样 管理的来头是1,方便在服务器端管理帐户,那样的话能够洞察自个儿的应用的帐户情况;2,服务器端完成推送机制,方便处理token以致做api;3,服务 器端还足以和别的开放平台帐户绑定)。因而,大家的任何认证方案会在劳务器端完毕。

而基于Tencent今日头条开放平台,大家第一会在开放平台上边注册自个儿的选用,注册的流程以致艺术自身不说了,注册的地址是:,注册你的使用后,你对号入座能够赢得的东西是:

JavaScript

接纳名称:mobile_test_api 应用类型:客商端应用 App Key:88888888 App Secret:ainidenideiienfeomeomroemrome

1
2
3
4
应用名称:mobile_test_api
应用类型:客户端应用
App Key:88888888
App Secret:ainidenideiienfeomeomroemrome

在此我的App key以至App Secret是假的(你懂的,你应有有你谐和的),上面大家就选取Tencent提须求大家的PHP SDK,下载地址:。有了SDK后我们就足以把SDK放到本身的情况方面,然后配置服务器端的代码了。下图是自己大约安排的服务端的代码,lib下存放的便是腾讯网易的sdk。当然实际生产条件和那一个有例外。这里仅仅作为示范使用:

澳门新葡亰手机版 7

上边就依据微博易表达的流水生产线,逐风流倜傥讲授一下那一个文件以至此中的代码吧。

index.php

PHP

<?php require_once 'app_config.php'; $url=" header('Location:'.$url);

1
2
3
4
5
6
<?php
require_once 'app_config.php';
 
$url="https://open.t.qq.com/cgi-bin/oauth2/authorize?client_id=".$client_id."&APP_KEY=".$app_key."&wap=2&response_type=code&redirect_uri=http://yoururl.com/get_auth.php";//指定URL地址
 
header('Location:'.$url);

此地引入的app_config.php

PHP

<?php $client_id = '8888888888'; $app_key = 'anienineiienrieireowq2839289';

1
2
3
4
5
<?php
 
$client_id = '8888888888';
 
$app_key = 'anienineiienrieireowq2839289';

因为依照腾讯和讯开放平台,我们率先步要得到的是Code,如下所述,大家要做的正是抓牢安插,获取这一个Code

JavaScript

第一步:诉求code 乞求方法: GET 诉求地址: 再次回到结果: 假设授权成功,授权服务器会将客商的浏览珍视定向到redirect_uri,并带上code,openid和openkey等参数,重定向的url如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
第一步:请求code
 
请求方法:
GET
 
请求地址:
 
https://open.t.qq.com/cgi-bin/oauth2/authorize?client_id=APP_KEY&amp;response_type=code&amp;redirect_uri=http://www.myurl.com/example
 
返回结果:
如果授权成功,授权服务器会将用户的浏览器重定向到redirect_uri,并带上code,openid和openkey等参数,重定向的url如下:
 
http://www.myurl.com/example?code=CODE&amp;openid=OPENID&amp;openkey=OPENKEY

切实须要要求附带的参数,须要求遵守oAuth2.0鉴权的页面提醒的扩充。()

下一场我们再来看看大家所布署的公文:

get_auth.php

PHP

<?php require_once 'app_config.php'; $code = $_REQUEST['code']; $openid = $_REQUEST['openid']; $openkey = $_REQUEST['openkey']; $url = ""; $message = file_get_contents($url); /* success to print the access token message */ $access = explode("=",$message); print_r("<br />"); $access_message = explode("&",$access[1]); $access_token = $access_message[0]; $user_name = $access[4]; print_r($access_token ." " . $user_name);

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
<?php
 
require_once 'app_config.php';
 
$code = $_REQUEST['code'];
 
$openid = $_REQUEST['openid'];
 
$openkey = $_REQUEST['openkey'];
 
$url = "https://open.t.qq.com/cgi-bin/oauth2/access_token?client_id=".$client_id."&client_secret=".$app_key."&grant_type=authorization_code&code=".$code."&redirect_uri=http://yoururl.com/get_auth.php";
 
$message = file_get_contents($url);
 
/* success to print the access token message */
 
$access = explode("=",$message);
 
print_r("<br />");
 
$access_message = explode("&",$access[1]);
 
$access_token = $access_message[0];
 
$user_name = $access[4];
 
print_r($access_token ."   " . $user_name);

骨子里到以上停止,大家的布置文件已经弄好了。在这里个布局文件中,实际上大家要做的正是Tencent乐乎开放平新北谈起的第二步:

JavaScript

第二步:乞请accesstoken 央浼地址: 再次来到结果: 再次来到字符串: access_token=ACCESS_TOKEN&expires_in=60&refresh_token=REFRESH_TOKEN

1
2
3
4
5
6
7
8
9
第二步:请求accesstoken
 
请求地址:
 
https://open.t.qq.com/cgi-bin/oauth2/access_token?client_id=APP_KEY&amp;client_secret=APP_SECRET&amp;redirect_uri=http://www.myurl.com/example&amp;grant_type=authorization_code&amp;code=CODE
 
返回结果:
返回字符串:
access_token=ACCESS_TOKEN&amp;expires_in=60&amp;refresh_token=REFRESH_TOKEN

意气风发经您未来早已安顿好您的服务端口,已经陈设好手提式无线电话机端的ChildBrowser,你就早就足以在小弟大方面看看整个认证的流水生产线了。未来的专门的学业早已完成了一大半了,然而留心的心上人只怕会意识,对啊,认证是成功了,手机上依旧未有博得授权啊,因为授权后的消息还不可以透过手机去获取。不要 急,ChildBrowser风趣的地方还未有完呢。在手机端方面我们成功了oAuth认证,总有震耳欲聋对参数重回,不管accesstoken是不是存在手提式有线电话机端,你必得有个帐户机制和服务端通信。笔者的服务端在SAE上边,我就成立一个唯后生可畏id给手提式有线电话机,于是本人就组建了二个帐户机制,存在服务端上,服务端上囤积的东西是:

MySQL

CREATE TABLE IF NOT EXISTS `auth_user` ( `id` int(10) NOT NULL AUTO_INCREMENT, `muser` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `access_token` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `openid` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `openkey` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL, `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;

1
2
3
4
5
6
7
8
9
10
CREATE TABLE IF NOT EXISTS `auth_user` (
  `id` int(10) NOT NULL AUTO_INCREMENT,
  `muser` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `access_token` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `openid` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `openkey` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=1 ;

实际上这一个表也还并未有健全,笔者不可能不还要纪录那个客商是还是不是在线(借使有推送机制)。此后手提式有线电电话机端和服务端通信就由此地方的id以致token等的音讯进行通信,再通过服务端想Tencent和讯开展api的通信,获取我们想要的消息。那么申明后大家透过哪些路径获得表达后回去的新闻呢?我们看看下边JS调整ChildBrowser的代码。会意识内部有多个情势:

JavaScript

cb.onLocationChange = function (loc){ console.warn(loc); };

1
cb.onLocationChange = function (loc){ console.warn(loc); };

倘诺你在xCode上边跑这段代码的话,你会发觉loc打出去的是历次ChildBrowser里面浏览的网页改动的地址。那个时候大家就能够相机行事,根据这里提供的方法,用url的法子把地方再次回到到Phonegap担当逻辑管理的JS代码中,同时将有关供给通信的新闻也回到。再次来到后还可以通过回 调的主意奉行关闭ChildBrowser的代码:

JavaScript

cb.close();

1
cb.close();

自然,你还足以施行更加多异步诉求的代码。至于说还足以由此什么样的点子开展报道其实还应该有众多主意,小编这里唯有是提供一下思路引导以致艺术。具体的 话,还要奉行出真理论,做到万分安全的报纸发表还值得我们后续浓烈斟酌。那么自个儿要介绍的差相当少就到那边甘休。因为实在项目中大家还应该有push notification的编写制定,所以事后本人应该还有大概会联同@Jeff_Kit 完结一下Phonegap的推送方案,并整治出sdk,成文后开放出来方便我们调换。

对于本文借使有如何疑点照旧提议都能够平昔向自个儿举报,小编的乐乎和讯是:@CashLee李秉骏 ,笔者还常常分享部分代码片段在github上边(开源的生气相当的少,所以开源项目少之甚少,希望以往追加吗。)作者的Github账号, 款待您和自家任何时候进行交换,也指望Phonegap的神州开垦者社区会变得越发杰出。

小心:ChildBrowser控件在实际上条件中因为安全难题大概供给修改,通信进程中参数也建议加密。:-)

 

正文由李秉骏(@CashLee李秉骏)投稿于伯乐在线,也接待任何朋友投稿。提醒:投稿时记得留下微博账号哦 澳门新葡亰手机版 8

【如需转发,请评释并保留原来的书文链接和作者等新闻,感激同盟!】

 

 

1 赞 收藏 2 评论

澳门新葡亰手机版 9

起源

parentopener

在说 opener 早先,可以先聊聊 <iframe> 中的 parent

我们知晓,在 <iframe> 中提供了多少个用以父子页面交互的靶子,叫做 window.parent,大家得以通过 window.parent 对象来从框架中的页面访谈父级页面包车型地铁 window

opener 与 parent 同样,只然而是用来 <a target="_blank"> 在新标签页展开的页面包车型客车。通过 <a target="_blank"> 展开的页面,能够直接利用 window.opener 来访谈来源页面包车型客车 window 对象。

同域与跨域

浏览器提供了完全的跨域爱惜,在域名一样不经常候,parent 对象和 opener 对象实际就径直是上一流的 window 对象;而当域名不一致期,parentopener 则是经过包装的三个 global 对象。这个 global 对象仅提供非常轻松的性子访问,而且在这里唯有的几特个性中,抢先59%也都是差别意采访的(访谈会一直抛出 DOMException)。

澳门新葡亰手机版 10

在 <iframe> 中,提供了二个 sandbox 属性用于调节框架中的页面包车型大巴权位,由此固然是同域,也得以调控 <iframe> 的安全性。

 

本文由澳门新葡亰手机版发布于web前端,转载请注明出处:代码实现四种双人对弈游戏

上一篇:整理总结的一些前端面试题,是真的美澳门新葡 下一篇:没有了
猜你喜欢
热门排行
精彩图文