成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

百行HTML 5代碼實(shí)現(xiàn)四種雙人對(duì)弈游戲

開(kāi)發(fā) 前端
要做一個(gè)完整的雙人對(duì)弈游戲,至少要做如下事情,第一步:繪制棋盤。不同的棋類游戲棋盤不同,這一點(diǎn)需要進(jìn)行動(dòng)態(tài)處理;第二步:繪制棋子......

簡(jiǎn)介:本文是一個(gè)非常具有挑戰(zhàn)性的編程,因?yàn)?100 行代碼,約莫 10000 個(gè)字符左右,將實(shí)現(xiàn)圍棋、五子棋、四子棋和翻轉(zhuǎn)棋四種雙人對(duì)弈游戲。請(qǐng)注意,這四個(gè)對(duì)弈游戲不是初級(jí)編程者的習(xí)作,而是有著棋盤、立體棋子、事件、走棋規(guī)則判斷、輸贏判斷的完整對(duì)弈游戲,并且可以離線存儲(chǔ)到 iPad、Android 平板中,試想一下,把這種游戲下載到平板中,就可以在火車,旅游景區(qū),等沒(méi)有信號(hào)的地方進(jìn)行對(duì)弈,是不是擴(kuò)展了平板電腦的功能,是不是一種很愜意的事情。而且,關(guān)鍵是,這個(gè)程序沒(méi)有圖片,不需要去應(yīng)用商店付費(fèi)下載,僅僅是用 HTML5 技術(shù)寫(xiě)的 100 行代碼而已,絕對(duì)是目前最迷您精悍的雙人對(duì)弈游戲源碼。(編者注:由于網(wǎng)頁(yè)代碼的寬度有限制,所以作者的源代碼經(jīng)過(guò)了一些換行處理,特此說(shuō)明。)

目標(biāo)

要做一個(gè)完整的雙人對(duì)弈游戲,至少要做如下事情,第一步:繪制棋盤。不同的棋類游戲棋盤不同,這一點(diǎn)需要進(jìn)行動(dòng)態(tài)處理;第二步:繪制棋子。需要說(shuō)明的是,圍棋,五子棋等這些棋子都是圓的啊,請(qǐng)不要為了圖片苦惱,在 HTML5 時(shí)代,我們用代碼就可以實(shí)現(xiàn)立體圓形棋子;第三步:判斷落子事件。當(dāng)然是要定位手指的點(diǎn)擊位置,這四種棋中,有的是落在框里面的,有的卻是落在縱橫交錯(cuò)的棋盤十字線上,需要?jiǎng)討B(tài)處理;第四步:判斷落子規(guī)則。下棋都有規(guī)則,不要因?yàn)榇a少,就將規(guī)則打折扣,否則程序不成熟,會(huì)變成小朋友的玩具了;第五步:判斷輸贏。最后,我們要判斷輸贏。也就是要數(shù)子,這個(gè)事情必須由程序來(lái)完成,因?yàn)橄缕蹇偟眯枰粋€(gè)裁判嘛;第六步:就是平板電腦時(shí)代,我們得實(shí)現(xiàn)離線應(yīng)用。這個(gè)太重要了,否則,要是在臺(tái)式電腦上,接根網(wǎng)線玩的游戲,已經(jīng)遍地都是了,您寫(xiě)得再牛,有什么用?就是要移動(dòng),在沒(méi)有信號(hào)的地方,才有市場(chǎng),現(xiàn)在平板,智能手機(jī)這么多,在沒(méi)有網(wǎng)絡(luò)信號(hào)的地方,掏出移動(dòng)設(shè)備來(lái)下棋,才是一件很牛的事情。

繪制棋盤

前面說(shuō)了圍棋、五子棋、四子棋和翻轉(zhuǎn)棋的棋盤并不相同,圍棋是縱橫 18 個(gè)格,其他三種棋則是 8 個(gè)格。所以繪制棋盤是需要有參數(shù)。這是個(gè)小問(wèn)題,大問(wèn)題是,選擇什么方法來(lái)繪制棋盤?

HTML5 框架下,有至少 3 種方法:第一種,用 Canvas 畫(huà)線;第二種,用 DIV,CSS3 里面增加了行列屬性;第三種,用 table 標(biāo)簽。

用哪一種速度最快,代碼少呢?答案是:第三種。多少有點(diǎn)失望啊,HTML5 不是萬(wàn)能的。詳細(xì)代碼如下:

  1. this.board=function(name,width,height,rowBak,colBak){ /* 畫(huà)棋盤 */  
  2. namenameBak=name;  
  3. if("turnover"==name){row=8;col=8;}else if("gogame"==name){row=18;col=18;}  
  4. var aW=Math.floor(width/(col+2)),aH=Math.floor(height/(row+2));  
  5. minL=(aW>aH?aH:aW)-4;// 這個(gè)減法很重要,否則填空時(shí)會(huì)把表格撐大  
  6. var array=new Array("<div style=\"margin:"+minL+"px;\"> "+  
  7. "<table border=1 cellspacing=0 width=\""+(aW*col)+"\"  
  8. height=\""+(aH*row)+"\">");  
  9. for(var i=0;i<row;i++){  
  10. array.push("<tr>");  
  11. for(var j=0;j<col;j++){array.push("<td align=center>"+  
  12. evt(i,j,minL,minL,aW*j+minL/2+8,aH*i+minL/2)+"</td>");}  
  13. if(nameBak!="four"&&nameBak!="turnover")/* 將事件添加到表格中 */  
  14. array.push(evt(i,col,minL,minL,aW*col+minL/2+8,aH*i+minL/2));  
  15. array.push("</tr>");  
  16. }  
  17. if(nameBak!="four"&&nameBak!="turnover"){  
  18. for(var j=0;j<=col;j++){  
  19. array.push(evt(row,j,minL,minL,aW*j+minL/2+8,aH*row+minL/2));  
  20. }  
  21. }  
  22. document.write(array.join("")+"</table></div>");  
  23. setClick(row,col,minL,minL);/* 初始化事件 */  
  24. start();/* 初始化棋子 */  

上面代碼中,最重要的是標(biāo)黑體的第 6 行代碼,這里面有兩個(gè)訣竅,第一個(gè)就是 table 的定義,第二個(gè)就是使用了 Array 數(shù)組。為什么要使用數(shù)組,而不是定義一個(gè)字符串呢?答案是優(yōu)化,就是 Array 數(shù)組的 push 方法的速度要遠(yuǎn)遠(yuǎn)快于 String 字符串的加 + 運(yùn)算。共計(jì) 16 行代碼,一個(gè)棋盤就畫(huà)好了,當(dāng)然這其中不僅僅是畫(huà)線,還有棋子處理,事件定義等方法的調(diào)用,后面將陸續(xù)談到。

繪制棋子

繪制完棋盤,我們來(lái)繪制棋子。我們挑選的這四種棋,雖然棋盤不同,但是棋子都是相同的,都是黑白棋子。這在以前,做在線對(duì)弈,除了 Flash 能實(shí)現(xiàn)美觀效果外,其他的必須先請(qǐng)美工做幾副小圖片,HTML5 時(shí)代,美工的人力和溝通成本就節(jié)省了。

我們至少有兩種方法繪制棋子,第一種是:canvas 類,第二種就是 css 的圓角屬性。用哪種速度又快代碼又少呢?答案是第二種,圓角。代碼如下:

  1. function man(width,height,id,colorBak){ /* 畫(huà)棋子 */  
  2. var color=colorBak==null?(order++%2==0?"000":"CCC"):colorBak;  
  3. var r="border-radius:"+width/2+"px;";  
  4. var obj=id==null?event.srcElement:_$(id);  
  5. obj.innerHTML="<div id=\"man_"+color+"_"+order+"\" style=\"display:block;-webkit-"  
  6. +r+"-moz-"+r+""+r+"-moz-box-shadow:inset 0 -10px 40px rgba(0,0,0,1);"+  
  7. "box-shadow:inset 0 -10px 40px rgba(0,0,0,1);"+  
  8. "background:-webkit-gradient(radial, 50 40, 30, center center, 80, from(#"+color+"),  
  9. to(rgba(255,255,255,1)));"+  
  10. "width:"+width+"px;height:"+height+"px;\"></div>";  

上面代碼中,我們看到,我們將每一個(gè)棋子定義了一個(gè) DIV,使用了 CSS3 的 shadow,gradient 屬性,并且可以根據(jù)棋盤的大小自動(dòng)計(jì)算棋子的大小,另外,如果用戶不喜歡黑白顏色,甚至可以定義成紅黃顏色,女生和小朋友估計(jì)會(huì)喜歡。這 5 行代碼是畫(huà)一個(gè)棋子的方法,做一個(gè)簡(jiǎn)單的循環(huán),就可以畫(huà)出多個(gè)棋子,方法如下。

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

#p#

處理事件

繪制完棋盤和棋子,我們來(lái)分析一下用戶的動(dòng)作。用戶的動(dòng)作無(wú)非就是兩種,一種是點(diǎn)擊棋盤 table,另外一種就是點(diǎn)擊棋子 DIV。難點(diǎn)在點(diǎn)擊 table 這里,我們要獲知用戶點(diǎn)擊 table 的位置。

傳統(tǒng)思路可能是這樣,使用 event 方法,獲得 x,y 的坐標(biāo),然后與 table 的左上角做減法,然后再跟單元格 cell 做除法。聽(tīng)起來(lái)都麻煩。

如果您仔細(xì)閱讀了前面的代碼,就應(yīng)該發(fā)現(xiàn),其實(shí)在畫(huà)棋盤是,我們向 array 數(shù)組中 push 了一個(gè) evt 方法,很明顯,這個(gè) evt 方法要返回一個(gè)字符串變量的,那么他的內(nèi)容是什么呢?答案揭曉:

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

原理是一個(gè) DIV。對(duì)了,這個(gè)添加事件的方法非常特殊,實(shí)際上是在每個(gè)棋盤的交叉的地方畫(huà)了一個(gè) DIV,然后給 DIV 添加事件。

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

需要說(shuō)明的是,DIV 一定要先定義,即 document.write 輸出出來(lái),然后才能執(zhí)行 onclick 的定義,否則會(huì)返回 DIV 未定義的錯(cuò)誤。寥寥 10 行代碼,把事件問(wèn)題搞定了。

落子規(guī)則

前面說(shuō)了,用戶點(diǎn)擊事件有兩種,點(diǎn)擊棋盤 table 事件我們采用額外增加 DIV 的方法巧妙解決了,第二種點(diǎn)擊棋子的方法又該如何呢?

先要說(shuō)明的是,點(diǎn)擊棋子其實(shí)是一種錯(cuò)誤的事件,點(diǎn)擊棋盤可以落子,點(diǎn)擊棋子是什么意思?黑白棋點(diǎn)擊棋子是無(wú)意義的,我們必須要進(jìn)行判斷,不能在有子的地方落子,這是規(guī)則之一。所以必須要定義一個(gè)方法,判斷是不是點(diǎn)擊的地方是不是有棋子。代碼如下:

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

想不到吧,其實(shí)只要一行代碼就可以就可以做是否有子的判斷,怎么判斷的,訣竅就在于判斷 DIV 的顏色,棋子要么黑,返回 0,要么白,返回 1,但是空白地方是沒(méi)有顏色的,返回 null。這里要特別注意返回值,后面判斷輸贏的時(shí)候還要用,所以不能簡(jiǎn)單通過(guò) true 或者 false 的的返回值來(lái)判斷是否有子,而是要判斷出有什么顏色的子。

對(duì)于五子棋和圍棋,這一條規(guī)則夠用了,但是對(duì)于翻轉(zhuǎn)棋和四子棋,還有第二條規(guī)則:不能在四周空白的地方落子,就是說(shuō)必須是相連的。也就是說(shuō),不僅僅要判斷點(diǎn)擊的地方是不是有棋子,還要判斷其四周是不是有棋子,這個(gè),不是可以有,而是,必須有。需要做一個(gè)小循環(huán)啊,代碼如下:

  1. function rule(){/* 走棋規(guī)則 */  
  2. var id=event.srcElement.id;  
  3. if(id.indexOf("man_")==0){alert("不能在有子的地方落子");return false;}else{  
  4. var p=id.indexOf("_"),p1=id.lastIndexOf("_");  
  5. var row=id.substr(p+1,p1-p-1)*1,col=id.substr(p1+1)*1;  
  6. if("gobang"==nameBak)return gobang(row,col);  
  7. else if("four"==nameBak){  
  8. if(isMan(row,col+1)==null&&isMan(row,col-1)==null&&  
  9. isMan(row+1,col)==null&&  
  10. isMan(row-1,col)==null){  
  11. alert("四子棋不能在四周空白的地方落子!");  
  12. return false;  
  13. }  
  14. return gobang(row,col,3);  
  15. }else if("turnover"==nameBak){  
  16. if(isMan(row,col+1)==null&&isMan(row,col-1)==null&&  
  17. isMan(row+1,col)==null&&isMan(row-1,col)==null&&  
  18. isMan(row-1,col-1)==null&&  
  19. isMan(row+1,col+1)==null){  
  20. alert("翻轉(zhuǎn)棋不能在四周空白的地方落子!");  
  21. return false;  
  22. }  
  23. turnover();  
  24. }else if("gogame"==nameBak){  
  25. }  
  26. }  
  27. return true;  

循環(huán)中,反復(fù)調(diào)用 isMan 方法判斷是否有棋子,所以如果 isMan 寫(xiě)得不夠簡(jiǎn)練,快速,不知道要耗費(fèi)多少時(shí)間啊。數(shù)一數(shù),總共 19 行代碼就處理了落子規(guī)則。

到這里,我們繪制了棋盤,棋子,獲得了點(diǎn)擊時(shí)間,判斷了落子規(guī)則,才用了 40 行左右的代碼,其實(shí)程序基本上可用了,但是我們不能滿足啊,還得讓他更加智能一些,我們還需要一個(gè)裁判斷輸贏。

判斷輸贏

要判斷輸贏,我們必須要知道下棋的規(guī)則:

五子棋是各個(gè)方向的五子相連算贏,四子棋是各個(gè)方向四個(gè)子相連算贏,翻轉(zhuǎn)棋數(shù)棋子的個(gè)數(shù),圍棋則要麻煩些,不僅僅數(shù)棋子個(gè)數(shù),還要數(shù)圍住的區(qū)域。

邏輯上好像很復(fù)雜啊,似乎也是計(jì)算最多的地方,有點(diǎn)人工智能的意思。沒(méi)錯(cuò),如果前面的基礎(chǔ)打得不好,這里的確要耗費(fèi)很多代碼,但是因?yàn)槲覀兦懊娑x了 DIV 用顏色判斷是否存在棋子的 iaMan 方法,這里再使用一個(gè)小技巧,就可以輕松搞定這個(gè)輸贏判斷。先看看五子棋和四子棋的輸贏判斷代碼,然后對(duì)照代碼來(lái)分析。

  1. function gobang(row,col,num){  
  2. numnum=num==null?4:num;  
  3. var rs=[[],[],[],[]],b=[],w=[];/* 這里采用四維數(shù)組來(lái)存儲(chǔ)棋子位置 */  
  4. for(var i=0,j=0;i<num*2+1;i++,j++){  
  5. rs[0].push(isMan(row-num+i,col));  
  6. rs[1].push(isMan(row,col-num+j));  
  7. rs[2].push(isMan(row-num+i,col-num+j));  
  8. rs[3].push(isMan(row-num+i,col-num+j));  
  9. if(i<num){b.push(0);w.push(1);}  
  10. }  
  11. if(rs.join("#").indexOf(b.join(","))!=-1){alert("黑棋勝");return false;  
  12. }else if(rs.join("#").indexOf(w.join(","))!=-1){alert("白棋勝");return false;}  
  13. return true;  

共計(jì) 9 行代碼就搞定,看懂沒(méi)?首先定義了一個(gè) Javascript 多維數(shù)組 rs=[[],[],[],[]],這種定義多維數(shù)組的方法,挑出來(lái)重點(diǎn)說(shuō)明一下,因?yàn)樗阉饕嫔隙际撬巡坏降模抑v課時(shí)差不多遇到的學(xué)生也都不清楚,他們大多采用 new Array,然后加循環(huán)的蝸牛方法。

第二步:從落子的地方開(kāi)始循環(huán),注意,不是循環(huán)整個(gè)棋盤,為的就是節(jié)省時(shí)間啊。循環(huán)設(shè)計(jì)縱橫交叉四個(gè)方向,有棋子的地方,就向這個(gè)四維數(shù)組 push 棋子的顏色。

第三步:把數(shù)組 join 起來(lái)就 ok 啦,如果有 4 個(gè)或 5 個(gè) 1 相連,自然就是白棋勝,否則就是黑棋勝。

寫(xiě)道這里,就有點(diǎn)意思啦,注意我們處理的數(shù)據(jù)的方法,我稱之為“塊數(shù)據(jù)”的處理方法,就是充分利用 array 數(shù)組,保存一塊一塊的數(shù)據(jù),無(wú)論寫(xiě)入,讀取,還是統(tǒng)計(jì)分析,都是針對(duì)這一塊數(shù)據(jù)進(jìn)行,這樣既可以提高內(nèi)聚度,便于提煉出可以重用的方法,就可以大大的加快執(zhí)行速度。

處理相連都不在話下,數(shù)子就更簡(jiǎn)單了,使用塊數(shù)據(jù)處理方法,3 行搞定。

  1. function turnover(){  
  2. if(order<64)return;  
  3. var num=0;var total=row*col;for(var i=0;i<row;i++){  
  4. for(var j=0;j<col;j++){num+=isMan(i+"_"+j);}  
  5. }  
  6. if(num<total/2)alert("黑棋勝"+(total-num*2)+"子");  
  7. else if(num>row*col/2)alert("白棋勝"+(num*2-total)+"子");  
  8. else alert("平局");  

棋子初始化

環(huán)環(huán)相扣地寫(xiě)到這里,還有最后一個(gè)關(guān)于棋子的問(wèn)題需要處理。那就是,下五子棋是從空白棋盤開(kāi)始,其他三種棋卻一開(kāi)始都是有子的。其實(shí)給一個(gè)空白棋盤也行,但是其他三種棋因?yàn)橐话愕那皫撞阶叻ǘ际枪潭ǖ模覀優(yōu)榱颂岣咧悄芑潭龋坏貌辉诶速M(fèi)四行代碼,畢竟,我們的目標(biāo)是一個(gè)市場(chǎng)化的產(chǎn)品,而不是一個(gè)初學(xué)者不考慮用戶體驗(yàn)的程序。

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

其實(shí)就是調(diào)用了一下 moreMan 方法,注意也是塊數(shù)據(jù)引用,傳輸了一個(gè)數(shù)組,用下劃線分割橫向和縱向坐標(biāo)。

#p#

做成離線應(yīng)用

本文開(kāi)頭就說(shuō)過(guò),臺(tái)式電腦的雙人或多人對(duì)弈程序早已多如牛毛爛大街了,只有移動(dòng)應(yīng)用才能有市場(chǎng),我們的目標(biāo)就是奔著這個(gè)來(lái)的,所以最后必須做成離線應(yīng)用。

如何實(shí)現(xiàn) HTML5 的離線應(yīng)用,搜索引擎很快能找到結(jié)果,其實(shí)只要三個(gè)關(guān)鍵步驟。

第一步;在 Web 服務(wù)器的配置文件中聲明一下。Tomcat 和 Apache 的聲明方式不相同,需要注意;

第二步:定義 manifest 文件,文件格式需要注意;

第三步:在 HTML 的文件中調(diào)用一下 manifest 文件。

根據(jù)這三個(gè)步驟,讀者可以自行搜索細(xì)節(jié),這里就不贅述了,我只講搜索引擎搜不到的。

另外需要說(shuō)明的是,iPad 和 Android 平板上瀏覽器實(shí)現(xiàn)全屏的方法也不一樣,針對(duì) iPad 用戶,我們還必須定義一行能夠?qū)崿F(xiàn)全屏的代碼。

9. 效果圖、在線演示、開(kāi)放源代碼

本文的在線演示網(wǎng)址是:http://www.chofo.com/chess.htm,效果圖如下圖所示:

圖1. 效果圖

[[82208]]

圖中加了一個(gè)選擇棋類型和設(shè)置背景功能,如要獲得全部源代碼,只要使用瀏覽器的查看源代碼功能即可,限于篇幅,這里就不貼了。

總結(jié)

作為一個(gè)程序員,最高的境界不是寫(xiě)得代碼越多越好,而是用最少的代碼實(shí)現(xiàn)最多的計(jì)算,解決最多的問(wèn)題。回想當(dāng)年,蓋茨在編寫(xiě) Basic 時(shí),為了節(jié)省幾個(gè)字符需要絞盡腦汁通宵達(dá)旦,以至于遺留了千年蟲(chóng)世紀(jì)難題,反觀今日,在云計(jì)算時(shí)代,隨著硬盤和內(nèi)存的容量越來(lái)越大,CPU 的運(yùn)算越來(lái)越快,很多大型項(xiàng)目的程序員似乎失去了精簡(jiǎn)代碼的習(xí)慣。但是移動(dòng)計(jì)算的硬件,目前還沒(méi)有那么高的配置,本文通過(guò) HTML5 對(duì)弈游戲,使用“塊數(shù)據(jù)”計(jì)算方法,實(shí)現(xiàn)了用最少代碼實(shí)現(xiàn)最多計(jì)算的目標(biāo),特別適用移動(dòng)計(jì)算,與大家共勉。

原文鏈接:http://www.mhtml5.com/2012/07/5177.html

責(zé)任編輯:張偉 來(lái)源: HTML5研究小組
相關(guān)推薦

2011-08-19 09:15:01

HTML 5

2015-03-19 15:13:20

PHP基本排序算法代碼實(shí)現(xiàn)

2021-12-22 09:34:01

Golagn配置方式

2011-03-16 09:05:53

NATiptables

2012-07-05 10:18:03

HTML5

2010-08-05 09:33:08

Flex頁(yè)面跳轉(zhuǎn)

2025-01-16 00:00:00

MapStruct映射

2009-09-08 17:20:01

C#排序算法

2015-04-02 16:54:52

災(zāi)難恢復(fù)VDI災(zāi)難恢復(fù)

2015-04-13 11:39:26

VDI災(zāi)難恢復(fù)

2013-11-15 13:35:17

html5代碼創(chuàng)意

2012-05-15 13:57:41

HTML5

2021-10-24 08:37:18

網(wǎng)絡(luò)監(jiān)控網(wǎng)絡(luò)架構(gòu)網(wǎng)絡(luò)

2022-01-12 11:02:01

云計(jì)算安全技術(shù)

2023-07-11 10:24:00

分布式限流算法

2010-07-16 13:50:53

Perl哈希表

2019-10-24 07:42:28

Java引用GC

2017-07-06 15:40:19

DevOps核心能力

2022-08-01 07:56:23

React Hook開(kāi)發(fā)組件

2012-09-11 09:55:26

編程HTML5編程能力
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 在线观看国产wwwa级羞羞视频 | 亚洲一区二区电影在线观看 | 天天夜天天操 | 一区二区视频在线观看 | 麻豆精品国产91久久久久久 | 精品不卡 | 欧美性a视频 | 精品一二三区视频 | 国产高清视频在线播放 | 国产成人综合久久 | 天堂中文字幕av | 亚洲欧美成人影院 | 九九热在线观看视频 | 亚洲精品在线播放 | 亚洲精品在线播放 | 精品亚洲一区二区 | 久久久精品视频一区二区三区 | 成人国产在线视频 | 欧美激情一区二区三级高清视频 | 中文字幕一区二区三 | 激情久久网 | 亚洲人人| 欧美成人精品在线 | 亚洲午夜视频在线观看 | 久久亚洲一区 | 一级黄色片一级黄色片 | 四虎免费视频 | www国产成人免费观看视频,深夜成人网 | 国产东北一级毛片 | 日本成人综合 | 国产精品福利久久久 | 久久国内精品 | 日韩欧美在线视频 | 夜夜艹天天干 | 永久www成人看片 | 欧美jizzhd精品欧美巨大免费 | 丝袜美腿一区 | 国产电影一区二区三区爱妃记 | 伊人精品一区二区三区 | 亚洲福利 | 欧美在线 |