整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          jQuery實現純HTML/CSS的拼圖游戲

          這是關于初學者的文章,他們希望通過一些簡單的方法開始在網絡中開發游戲開發,而不使用任何重型工具。本文提供了一個簡單的步驟,開始使用html / css和javascript的2d游戲開發。在這里,我將介紹如何創建一個圖像拼圖游戲,您可以在其中拖放圖像部分進行交換和重新排列零件以形成完整的圖像。

          你可以在線玩這個游戲:http://www.ikinsoft.com/3ddemo/puzzle/puzzle.html

          游戲規則

          游戲的規則很簡單。你只需要拖放破碎的圖像來交換它。您需要以形成正確圖像的方式交換它們。將拖放圖像部件所需的步驟數。所以,您可能希望考慮并嘗試以盡可能最小的步驟進行。右側提供正確的圖像供您參考。

          游戲畫面如下所示:

          游戲畫面截圖

          游戲代碼說明

          我們將游戲的代碼分成3部分:Html,Css和Javascript。Html部分包含形成游戲布局的簡單標簽。CSS提供了一些響應式設計,Javascript部分包含游戲的主要邏輯。游戲的幾個重要步驟如下:

          打破圖像

          對于圖像看起來像分為nxn不同的部分,每側的部件n數量在哪里,nxn li元素已被使用在一個ul。每個的顯示屬性li已設置為內嵌塊,以使其顯示為網格。每個背景圖像li被設置為僅顯示圖像的1 /(n×n)部分,并且相應地設置背景圖像的位置。data-value屬性已被分配給每個li以標識該片段的索引。

          代碼如下:

          打碎圖片代碼

          在這里,您可以看到使用簡單background-image和background-position風格實現了破壞的效果。在已經設置了博爾森圖像之后,按照正確的順序,隨機化方法用于隨機化片段。在游戲中,用戶必須重新排列片段以形成完整的圖像。

          gridSize表示圖像需要在每一側(水平和垂直)分割多少部分。硬編碼值400是盒子的大小。請注意,您可能想要擺脫這個硬編碼的值。我將在下一次更新中用一個變量來更新。基于gridSize,我將拼圖的級別分為3部分:容易,中等和難易。容易3x3格,中4x4和硬5x5。您可以通過更改相應的單選按鈕的值,以不同的方式實現相同的方式。

          隨機斷開零件

          在設置圖像損壞的部分后,如前面代碼塊的最后一行所示,隨機化方法用于隨機分割碎片。為此,創建一個小型通用隨機化函數來隨機化任何jquery元素集合。

          隨機化方法的實現如下:

          隨機斷開零件代碼

          在這里,我們只是簡單地循環給定選擇器的每個子元素,并根據隨機數改變其位置。隨機數應在0和收集中的元素數之間。

          拖放圖片碎片

          為了使每個碎片拖動,使用了jquery draggable插件。請確保您的頁面中包含jquery-ui.js以實現可拖放/可拖放功能。

          拖放圖片碎片代碼

          正如您在上述代碼片段中可以看到的,每次下降之后,isSorted 都將被調用來檢查這些片段是否已被排序。正在根據包含li元素的data-value屬性檢查每個片段的排序。如果片段被排序,則表示圖片已完成。

          設置樣式

          已經使用了一個非常小的css來使其變得簡單易懂。所使用的css允許頁面響應,您可以在平板電腦或手機中玩游戲。沒有使用css的第三方庫,以便您可以輕松了解本機css樣式。

          計數步驟

          計數步驟或任何用戶操作是任何游戲中最常見的部分。這也是通過一個簡單的步驟實現的。在每次下降之后,它檢查圖像是否形成。如果是,游戲結束,如果沒有,則將stepCount 變量遞增1.然后,stepCount 使用jquery 更新UI。

          計時器

          計時器也是大多數游戲的重要組成部分之一。基于讀者提供的反饋,已經實現了一個基本的計時器來檢查完成拼圖所需的秒數。計時器正在游戲開始時啟動,tick 每秒鐘調用 方法來更新計時器。Tick方法一旦從start方法調用,然后每秒鐘調用自身(使用JavaScript SetTimeout)并使用JQuery更新UI中使用的時間。當圖片完成時,游戲結束,最后計時,并在使用JQuery的輸出中顯示。

          下面是定時器方法的實現:

          計時器代碼

          請注意,getTime()方法給出自01/01/1970以來通過的毫秒數。如果您建議更好的方法來計算兩個DateTime 在javascript 之間的時間,我將不勝感激。我不想依靠1000毫秒的差距setTimeout()來增加1秒。

          級別

          根據用戶的反饋,游戲中添加了3個難度級別:1.輕松2.中等3.硬。在我們的例子中,選擇容易設置3x3矩陣中的難題,4x4矩陣中的中等,硬設置為5x5矩陣。

          瀏覽器兼容性

          為了簡單起見,我避免使用Html 5或CSS 3,以便它可以在大多數瀏覽器中使用。由于使用了JQuery版本,此游戲可能不適用于較早的瀏覽器<IE8。如果您希望在舊版本的舊版本中使用此游戲,您可以將腳本引用替換為較舊的JQuery版本(1.9或更早版本)。最新的JQuery版本不支持舊版瀏覽器。

          上文的示例網址應該在大多數最新的瀏覽器中運行。已經在IE 11和Google Chrome中測試過。

          、canvas簡介

          1. canvas是HTML5提供的一種新標簽,雙標簽;
          2. HTML5 canvas標簽元素用于圖形的繪制,通過腳本 (通常是JavaScript)來完成;
          3. canvas標簽只是圖形容器,必須使用腳本來繪制圖形;

          Canvas是一個矩形區域的畫布,可以用JavaScript在上面繪畫;


          二、案例目標

          我們今天的目標是使用HTML5畫布技術制作一款拼圖小游戲,要求將圖像劃分為3*3的9塊方塊并打亂排序,用戶可以移動方塊拼成完整圖片。

          效果如下所示:


          三、程序流程

          3.1 HTML靜態頁面布局

          <div id="container">
                      <!--頁面標題-->
                      <h3>HTML5畫布綜合項目之拼圖游戲</h3>
                      <!--水平線-->
                      <hr />
                      <!--游戲內容-->
                      <!--游戲時間-->        
                      <div id="timeBox">
                          共計時間:<span id="time">00:00:00</span>
                      </div>
                      <!--游戲畫布-->
                      <canvas id="myCanvas" width="300" height="300" style="border:1px solid">
                          對不起,您的瀏覽器不支持HTML5畫布API。
                      </canvas>
                      <!--游戲按鈕-->
                      <div>
                          <button onclick="restartGame()">
                              重新開始
                          </button>
                      </div>  
          </div>

          效果如下所示:

          我們可以看到頁面的大致結構是已經顯現出來了,就是骨架已經搭建好了,現在我們要使用css強化樣式;


          3.2 CSS打造頁面樣式

          整體背景設置

          body {
              background-color: silver;/*設置頁面背景顏色為銀色*/
          }

          游戲界面樣式設置

          #container {
              background-color: white;
              width: 600px;   
              margin: auto;
              padding: 20px;
              text-align: center; 
              box-shadow: 10px 10px 15px black;
          }

          游戲時間面板樣式設置

          #timeBox {
              margin: 10px 0;
              font-size: 18px;
          }

          游戲按鈕樣式設置

          button {
              width: 200px;
              height: 50px;
              margin: 10px 0;
              border: 0;
              outline: none;
              font-size: 25px;
              font-weight: bold;
              color: white;  
              background-color: lightcoral;
          }

          鼠標懸浮時的按鈕樣式設置

          button:hover {
              background-color: coral;
          }

          設置好界面整體樣式之后我們得到完整的界面,如下所示:

          可以看到整體的靜態界面已經搭建出來了


          3.3 js構建交互效果

          3.3.1 對象的獲取以及圖片的設置

          目標對象的獲取

          var c = document.getElementById('myCanvas'); //獲取畫布對象
          var ctx = c.getContext('2d'); //獲取2D的context對象

          聲明拼圖的圖片素材來源

          var img = new Image();
          img.src = "image/pintu.jpg";
                          
          img.onload = function() { //當圖片加載完畢時
              generateNum(); //打亂拼圖的位置
              drawCanvas(); //在畫布上繪制拼圖
          }

          3.3.2 初始化拼圖

          • 需要將素材圖片分割成3行3列的9個小方塊,并打亂順序放置在畫布上;
          • 為了在游戲過程中便于查找當前的區域該顯示圖片中的哪一個方塊,首先為原圖片上的9個小方塊區域進行編號;


          定義初始方塊位置

          var num = [[00, 01, 02], [10, 11, 12], [20, 21, 22]];


          打亂拼圖的位置

          function generateNum() { //循環50次進行拼圖打亂    
                   for (var i = 0; i < 50; i++) {
                //隨機抽取其中一個數據
                      var i1 = Math.round(Math.random() * 2);
                      var j1 = Math.round(Math.random() * 2);
                //再隨機抽取其中一個數據
                      var i2 = Math.round(Math.random() * 2);
                      var j2 = Math.round(Math.random() * 2);
                //對調它們的位置
                      var temp = num[i1][j1];
                      num[i1][j1] = num[i2][j2];
                      num[i2][j2] = temp;
             }
          }


          繪制拼圖

          自定義名稱的drawCanvas()方法用于在畫布上繪制亂序后的圖片;

          function drawCanvas() {
              //清空畫布
              ctx.clearRect(0, 0, 300, 300);
              //使用雙重for循環繪制3x3的拼圖
              for (var i = 0; i < 3; i++) {
                  for (var j = 0; j < 3; j++) {
                      if (num[i][j] != 22) {
                          //獲取數值的十位數,即第幾行
                          var row = parseInt(num[i][j] / 10);
                          //獲取數組的個位數,即第幾列
                          var col = num[i][j] % 10;
                          //在畫布的相關位置上繪圖
                          ctx.drawImage(img, col * w, row * w, w, w, j * w, i * w, w, w); // w:300 / 3 = 100(小圖寬度)
                      }
                  }
              }
          }

          如下所示:

          3.3.3 事件綁定

          監聽鼠標監聽事件

          c.onmousedown = function(e) {
              var bound = c.getBoundingClientRect(); //獲取畫布邊界
              
              var x = e.pageX - bound.left; //獲取鼠標在畫布上的坐標位置(x,y)
              var y = e.pageY - bound.top;
          
          
              var row = parseInt(y / w); //將x和y換算成幾行幾列
              var col = parseInt(x / w);
          
          
              
              if (num[row][col] != 22) { //如果當前點擊的不是空白區域
                  detectBox(row, col); //移動點擊的方塊
                  drawCanvas(); //重新繪制畫布
                  var isWin = checkWin(); //檢查游戲是否成功
                  
                  if (isWin) { //如果游戲成功
                      clearInterval(timer); //清除計時器
                      ctx.drawImage(img, 0, 0); //繪制完整圖片
                      ctx.font = "bold 68px serif"; //設置字體為加粗、68號字,serif
                      ctx.fillStyle = "red"; //設置填充色為紅色
                      ctx.fillText("游戲成功!", 20, 150); //顯示提示語句
                  }
              }
          }

          點擊方塊移動

          function detectBox(i, j) {
              //如果點擊的方塊不在最上面一行
              if (i > 0) {
                  //檢測空白區域是否在當前方塊的正上方
                  if (num[i-1][j] == 22) {
                      //交換空白區域與當前方塊的位置
                      num[i-1][j] = num[i][j];
                      num[i][j] = 22;
                      return;
                  }
              }
              //如果點擊的方塊不在最下面一行
              if (i < 2) {
                  //檢測空白區域是否在當前方塊的正下方
                  if (num[i+1][j] == 22) {
                      //交換空白區域與當前方塊的位置
                      num[i+1][j] = num[i][j];
                      num[i][j] = 22;
                      return;
                  }
              }
              //如果點擊的方塊不在最左邊一列
              if (j > 0) {
                  //檢測空白區域是否在當前方塊的左邊
                  if (num[i][j - 1] == 22) {
                      //交換空白區域與當前方塊的位置
                      num[i][j - 1] = num[i][j];
                      num[i][j] = 22;
                      return;
                  }
              }
              //如果點擊的方塊不在最右邊一列
              if (j < 2) {
                  //檢測空白區域是否在當前方塊的右邊
                  if (num[i][j + 1] == 22) {
                      //交換空白區域與當前方塊的位置
                      num[i][j + 1] = num[i][j];
                      num[i][j] = 22;
                      return;
                  }
              }
          }


          3.3.4 游戲計時

          • 自定義函數getCurrentTime()用于進行游戲計時;
          • function getCurrentTime() {
            s = parseInt(s);
            //將時分秒轉換為整數以便進行自增或賦值
            m = parseInt(m);
            h = parseInt(h);
            s++;
            //每秒變量s先自增1

            if (s == 60) {
            s = 0;
            //如果秒已經達到60,則歸0
            m++;
            //分鐘自增1
            }
            if (m == 60) {
            m = 0;
            //如果分鐘也達到60,則歸0
            h++;
            //小時自增1
            }


            //修改時分秒的顯示效果,使其保持兩位數
            if (s < 10)
            s = "0" + s;
            if (m < 10)
            m = "0" + m;
            if (h < 10)
            h = "0" + h;
            time.innerHTML = h + ":" + m + ":" + s;
            //將當前計時的時間顯示在頁面上
            }
          • 在JavaScript中使用setInterval()方法每隔1秒鐘調用getCurrentTime()方法一次,以實現更新效果;var timer = setInterval("getCurrentTime()", 1000);


          3.3.5 游戲成功與重新開始

          游戲成功判定與顯示效果的實現

          • 自定義函數checkWin()用于進行游戲成功判斷;
          function restartGame() {
              clearInterval(timer);  //清除計時器
              s = 0; //時間清零
              m = 0;
              h = 0;
              getCurrentTime();  //重新顯示時間
              timer = setInterval("getCurrentTime()", 1000);
           
              generateNum(); //重新打亂拼圖順序
              drawCanvas(); //繪制拼圖
              
          }
          • 如果成功則使用clearInterval()方法清除計時器。然后在畫布上繪制完整圖片,并使用fillText()方法繪制出“游戲成功”的文字圖樣;if (isWin) { //如果游戲成功
            clearInterval(timer);
            //清除計時器
            ctx.drawImage(img, 0, 0);
            //繪制完整圖片
            ctx.font = "bold 68px serif";
            //設置字體為加粗、68號字,serif
            ctx.fillStyle = "red";
            //設置填充色為紅色
            ctx.fillText("游戲成功!", 20, 150);
            //顯示提示語句
            }

          3.4 最終效果演示

          靜態效果如上所示,至于游戲成功這里伙計們可以自行操作;


          四、總結

          本次案例我們使用HTML5的新特性canvas畫布標簽打造了簡單的9宮格拼圖游戲,總體來說沒有特別的復雜,主要是圖片的分割方塊移動事件的綁定,以及重新游戲的初始化操作,明確了游戲邏輯之后其實代碼的編寫其實不難。感興趣的小伙伴可以去嘗試一下。

          去年曾寫過一個用H5Javascriptcss3實現的拼拼樂小游戲,技術棧采用自己封裝的類Jquery框架 Xuery ,其中涉及到了很多經典的 javascript 算法和css3特性 ,對大家的編程能力會有很大的提高,文末我也會放上源碼獲取方式,大家可以學習體驗一下。

          前言

          因為該應用屬于 H5 游戲,為了讓項目更輕量,我沒有采用第三方 ui 庫,如果大家想采用基于 vue 的第三方移動端ui庫,我給大家推薦幾個我之前用過的比較靠譜的:

          • Mint 餓了么推出的移動端ui庫
          • NutUI 一套京東風格的移動端組件庫
          • muse-ui 基于MaterialUI風格的移動端UI組件
          • cube-ui 滴滴團隊開發的移動端UI組件庫
          • vant 有贊團隊的電商風格的移動端組件庫
          • atom-design atom風格的移動端ui組件庫
          • mand-mobile 滴滴團隊研發的基于金融場景的移動端ui組件庫

          以上推薦的都是社區比較完善,bug比較少的組件庫,大家可以感受一下。

          回到我們的小游戲開發,考驗更多的是大家對 javascriptcss3 的掌握程度,在學習完這篇文章之后相信大家對 javascriptcss3 的編程能力都會有極大的提升,后面還會介紹如何使用 canvas 實現生成戰績海報圖的功能。

          正文

          我們先來看看游戲的預覽界面:

          本文的算法實現方式在之前的拼拼樂文章中已經說明,這里主要介紹核心算法, 至于vue-cli的使用方法,筆者之前也寫過對應的文章,大家可以研究學習一下。vue-cli搭建項目方式如下:

          // 安裝
          yarn global add @vue/cli
          
          // 創建項目
          vue create pinpinle
          
          // 進入項目并啟動
          cd pinpinle && yarn start
          

          關于vue-cli3配置實戰,可以移步 一張圖教你快速玩轉vue-cli3

          H5游戲核心功能介紹

          目前筆者主要整理了如下核心功能,接下來筆者會一一帶大家實現: 實現純javascript上傳預覽圖片 實現拼圖分割功能 實現洗牌算法 實現生成戰績海報功能

          1. 實現純javascript上傳預覽圖片

          文件上傳預覽主要采用FileReader API實現,原理就是將file對象傳給FileReader的readAsDataURL然后轉化為data:URL格式的字符串(base64編碼)以表示所讀取文件的內容。 具體代碼如下:

          // 2.文件上傳解析
          let file = $('#file');
          file.on('change', function(e){
              var file = this.files[0];
              var fileReader = new FileReader();
              // 讀取完成觸發的事件
              fileReader.onload = function(e) {
                  $('.file-wrap')[0].style.backgroundImage = 'url(' + fileReader.result + ')';
                  imgSrc = fileReader.result;
              }
          
              file && fileReader.readAsDataURL(file);
          })
          

          2. 實現拼圖分割功能

          一般我們處理這種拼圖游戲都會有如下方案: 用canvas分割圖片 采用n張不同的切好的切片圖片(方法簡單,但是會造成多次請求) * 動態背景分割

          經過權衡,筆者想出了第三種方法,也是自認為比較優雅的方法,即動態背景分割,我們只需要使用1張圖片,然后利于css的方式切割圖片,有點經典的雪碧圖的感覺,如下:

          本質就是我們設置九個div,每個div都使用同一張圖片,并且圖片大小等于游戲畫布大小,但是我們通過backgroundPosition(背景定位)的方式來實現切割圖片。這樣做的另一個好處是方便我們實現洗牌邏輯

          3. 實現洗牌算法

          洗牌邏輯依托于隨機算法,這里我們結合坐標系,實現一個隨機生成二維坐標系的邏輯,然后通過改變每個切片的translate位置,配合過渡動畫,即可實現洗牌功能和洗牌動畫。

          3.1 數組亂序算法

          數組亂序比較簡單,代碼如下:

          // 數組亂序
          function upsetArr(arr) {
              arr.sort(function(a,b){
                  return Math.random() > 0.5 ? -1 : 1
              })
          }
          

          3.2 洗牌邏輯

          洗牌邏輯基于數組亂序,具體邏輯如下:

          // 洗牌方法
          function shuffle(els, arr) {
              upsetArr(arr);
              for(var i=0, len=els.length; i< len; i++) {
                  var el = els[i];
                  el.setAttribute('index', i);  // 將打亂后的數組索引緩存到元素中
                  el.style.transform = 'translate(' + arr[i].x + 'vw,' + arr[i].y + 'vh'+ ')';
              }
          }
          

          3.3 生成n緯矩陣坐標

          n維矩陣主要用來做洗牌和計算成功率的,具體實現如下:

          // 生成n維矩陣坐標
          function generateMatrix(n, dx, dy) {
              var arr = [], index = 0;
              for(var i = 0; i< n; i++) {
                  for(var j=0; j< n; j++) {
                      arr.push({x: j*dx, y: i*dy, index: index});
                      index++;
                  }
              }
              return arr
          }
          

          3.4 置換算法

          置換算法主要用來切換拼圖的,比如用戶想移動拼圖,可以通過置換來實現:

          // 數組置換
          function swap(arr, indexA, indexB) {
              let cache = arr[indexA];
              arr[indexA] = arr[indexB];
              arr[indexB] = cache;
          }
          

          4. 實現生成戰績海報功能

          生成戰績海報筆者采用canvas來實現,對于canvas的api不熟悉的可以查看MDN,講的比較詳細。這里筆者簡單實現一個供大家參考:

          function generateImg() {
              var canvas = document.createElement("canvas");
          
              if(canvas.getContext) {
                  var winW = window.innerWidth,
                      winH = window.innerHeight,
                  ctx = canvas.getContext('2d');
                  canvas.width = winW;
                  canvas.height = winH;
          
                  // 繪制背景
                  // ctx.fillStyle = '#06c';
                  var linear = ctx.createLinearGradient(0, 0, 0, winH);
                  linear.addColorStop(0, '#a1c4fd');
                  linear.addColorStop(1, '#c2e9fb');
                  ctx.fillStyle = linear;
                  ctx.fillRect(0, 0, winW, winH);
                  ctx.fill();
          
                  // 繪制頂部圖像
                  var imgH = 0;
                  img = new Image();
                  img.src = imgSrc;
                  img.onload = function(){
                      // 繪制的圖片寬為.7winW, 根據等比換算繪制的圖片高度為 .7winW*imgH/imgW
                      imgH = .6*winW*this.height/this.width;
                      ctx.drawImage(img, .2*winW, .1*winH, .6*winW, imgH);
          
                      drawText();
                      drawTip();
                      drawCode();
                  }
          
                  // 繪制文字
                  function drawText() {
                      ctx.save();
                      ctx.fillStyle = '#fff';
                      ctx.font = 20 + 'px Helvetica';
                      ctx.textBaseline = 'hanging';
                      ctx.textAlign = 'center';
                      ctx.fillText('我只用了' + (180 -dealtime) + 's,' + '快來挑戰!', winW/2, .15*winH + imgH);
                      ctx.restore();
                  }
          
                  // 繪制提示文字
                  function drawTip() {
                      ctx.save();
                      ctx.fillStyle = '#000';
                      ctx.font = 14 + 'px Helvetica';
                      ctx.textBaseline = 'hanging';
                      ctx.textAlign = 'center';
                      ctx.fillText('關注下方二維碼開始游戲', winW/2, .25*winH + imgH);
                      ctx.restore();
                  }
          
          
                  // 繪制二維碼
                  function drawCode() {
                      var imgCode = new Image();
                      imgCode.src = '/piecePlay/images/logo.png';
                      imgCode.onload = function(){
                          ctx.drawImage(imgCode, .35*winW, .3*winH + imgH, .3*winW, .3*winW);
          
                          // 生成預覽圖
                          var img = new Image();
                          img.src= convertCanvasToImage(canvas, 1).src;
                          img.className = 'previewImg';
                          img.onload = function(){
                              $('.preview-page')[0].appendChild(this);
                              startDx = startDx - 100;
                              transformX(wrap, startDx + 'vw');
                          }
                      }
                  }  
              } else {
                  alert('瀏覽器不支持canvas!')
              }
          }
          

          H5拼圖小游戲我已在github開源, 感興趣的可以在我github上學習參考。以上的邏輯部分的代碼可以直接整合到vue項目中即可,由于實現比較簡單,這里我就不詳細介紹了。

          更多前端實戰項目推薦

          • H5-dooring H5頁面制作工具
          • mitu 在線圖片編輯器

          最后

          如果想學習更多H5游戲, webpack,node,gulp,css3,javascript,nodeJS,canvas數據可視化等前端知識和實戰,歡迎在《趣談前端》一起學習討論,共同探索前端的邊界。


          主站蜘蛛池模板: 一区二区三区观看免费中文视频在线播放 | 一区二区三区电影在线观看| 亚洲字幕AV一区二区三区四区| 国产日韩视频一区| 一区二区三区视频在线| 无码日韩人妻AV一区二区三区| 国产精品揄拍一区二区| 国产一区三区三区| 亚洲视频一区二区| 精品综合一区二区三区| 国产未成女一区二区三区 | 国产精品主播一区二区| 成人毛片无码一区二区| 无码人妻精品一区二区三区蜜桃 | 亚洲日韩一区精品射精| 精品永久久福利一区二区| 国产激情无码一区二区| 成人区人妻精品一区二区不卡视频 | 无码少妇A片一区二区三区| 99精品一区二区三区| 任你躁国语自产一区在| 日韩内射美女人妻一区二区三区| 99精品国产高清一区二区三区| 亚洲AV永久无码精品一区二区国产 | 亚洲国产系列一区二区三区 | 精品国产亚洲一区二区三区在线观看| 日本不卡一区二区视频a| 成人无码AV一区二区| 亚洲色婷婷一区二区三区| 一区二区三区无码视频免费福利| 国产精品乱码一区二区三区 | 另类一区二区三区| 国产精品视频一区二区噜噜| 美女啪啪一区二区三区| 日韩精品一区二区亚洲AV观看| 亚洲区精品久久一区二区三区| 国产精品夜色一区二区三区| 中文字幕一区日韩精品| 国产一区二区三区美女| V一区无码内射国产| 亚洲日本一区二区三区在线|