精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

使用JavaScript和Canvas寫一個游戲框架

開發(fā) 前端
下面我們要介紹的JavaScript代碼使用面向?qū)ο蟮姆绞絹砭帉憽τ跊]有編寫過多少JavaScript代碼的人來說,恐怕第一眼看到它們會覺得有點奇怪。

4、寫一個游戲框架(一)

http://www.brighthub.com/internet/web-development/articles/40512.aspx

在知道了如何使用畫布元素之后,接下來我教大家寫一個框架,有了這個框架,我們就可以把它作為基礎(chǔ)來創(chuàng)建游戲。在這第一部分,我們會介紹前兩個文件/類。

編寫代碼之前,我們先來看一看隨后幾篇文章將致力于創(chuàng)建的示例Demo。表面上看起來,這個Demo跟第二篇文章里的那個沒啥區(qū)別,但如果你看看后臺(查看網(wǎng)頁源代碼)就會發(fā)現(xiàn),為了更方便地創(chuàng)建這個最終效果,一個凝聚不少心血的基礎(chǔ)框架已經(jīng)寫好了。

 

 

下面我們要介紹的JavaScript代碼使用面向?qū)ο蟮姆绞絹砭帉憽τ跊]有編寫過多少JavaScript代碼的人來說,恐怕第一眼看到它們會覺得有點奇怪。如果你真的不太熟悉JavaScript的面向?qū)ο缶幊蹋ㄗh通過Mozilla Developer Network的這個教程https://developer.mozilla.org/en/Introduction_to_Object-Oriented_JavaScript來補(bǔ)補(bǔ)課。這篇教程里解釋了我們稍后會用到的一些編程技術(shù)。

從設(shè)計思想上來看,這個框架可以分成兩部分:與底層的2D引擎交互的類(用于操作畫布、控制渲染循環(huán)、處理輸入等的代碼)和用來創(chuàng)建對象以便構(gòu)成游戲的類。前者可以歸為引擎類,后者可以歸為應(yīng)用類。由于應(yīng)用類要構(gòu)建于引擎類之上,所以我們需要先來創(chuàng)建引擎類。

Main.js

如果你研究了前面例子中的代碼,就會發(fā)現(xiàn)Main.js文件中包含了不少代碼。

  1.  
  2. /** 每秒多少幀  
  3.     @type Number  
  4. */  
  5. var FPS = 30;  
  6. /** 兩幀間間隔的秒數(shù)  
  7.     @type Number  
  8. */  
  9. var SECONDS_BETWEEN_FRAMES = 1 / FPS;  
  10. /** GameObjectManager 實例的全局引用  
  11.     @type GameObjectManager  
  12. */  
  13. var g_GameObjectManager = null;  
  14. /** 應(yīng)用中用到的圖像  
  15.     @type Image  
  16. */  
  17. var g_image = new Image();  
  18. g_image.src = "jsplatformer3-smiley.jpg";  
  19.  
  20. // 將應(yīng)用的入口設(shè)置為init函數(shù)  
  21. window.onload = init;  
  22.  
  23. /**  
  24.     應(yīng)用的入口  
  25. */  
  26. function init()  
  27. {  
  28.     new GameObjectManager().startupGameObjectManager();  
  29. }  

首先是定義全局變量的代碼。然后,跟以前一樣,當(dāng)頁面加載完畢后立即運行init函數(shù)。在init函數(shù)里,創(chuàng)建GameObjectManager類的實例。

這里在GameObjectManager類的實例上調(diào)用了startupGameObjectManager函數(shù)。這篇文章以及后面的幾篇文章還將多次提到幾個命名上具有startupClassName形式的函數(shù)。這些函數(shù)實際上充當(dāng)了各自類的構(gòu)造函數(shù),這樣做有兩個原因。

首先,JavaScript不支持函數(shù)重載(至少不容易實現(xiàn))。如果你想讓一個類有多個構(gòu)造函數(shù),那么這就成了問題。而通過把構(gòu)造工作分配給另一組函數(shù)(如startupClassName1、startupClassName2),就可以比較容易地定義構(gòu)造類的不同方式了。

第二個原因(很大程度上也是個人的問題)是我經(jīng)常會在構(gòu)造函數(shù)中引用尚未定義的變量。這可能是我使用C++、Java和C#這些語言落下的毛病,在這些語言里,類變量在源代碼中的位置對其在構(gòu)造函數(shù)中的可見性沒有影響。拿下面這個C#類為例:

  1. class Test  
  2. {  
  3.     public void Test() {this.a = 5;}  
  4.     public int a;  
  5. }  

這些代碼是合乎語法的,可以正常工作。下面再看看JavaScript中一個相同的例子:

  1. function Test()  
  2. {  
  3.     this.a = 5;  
  4.     var a;  
  5. }  

這段代碼的問題在于,局部變量a在我們把數(shù)值5賦給它的時候還不存在。只有運行到var a;這一行,變量a才存在。盡管這個例子有點故意編排的意味,但的確能夠說明我所遇到的問題。通過把類的創(chuàng)建放到一個類似startupClassName這樣的函數(shù)中完成,并且在構(gòu)造函數(shù)中定義(但不初始化)局部變量,然后當(dāng)我在這些構(gòu)建函數(shù)中引用相應(yīng)的局部變量時,就能夠確保它們一定是存在的。

#p#

GameObjectManager.js

  1.  
  2. /**  
  3.     管理游戲中所有對象的管理器  
  4.     @class  
  5. */  
  6. function GameObjectManager()  
  7. {  
  8.     /** 保存游戲中對象的數(shù)組  
  9.         @type Arary  
  10.     */  
  11.     this.gameObjects = new Array();  
  12.     /** 上一次幀被渲染的時間  
  13.         @type Date  
  14.     */  
  15.     this.lastFrame = new Date().getTime();  
  16.     /** x軸的全局滾動值  
  17.         @type Number  
  18.     */  
  19.     this.xScroll = 0;  
  20.     /** y軸的全局滾動值  
  21.         @type Number  
  22.     */  
  23.     this.yScroll = 0;  
  24.     /** 對ApplicationManager實例的引用  
  25.         @type ApplicationManager  
  26.     */  
  27.     this.applicationManager = null;  
  28.     /** 對畫布元素的引用  
  29.         @type HTMLCanvasElement  
  30.     */  
  31.     this.canvas = null;  
  32.     /** 對畫布元素2D上下文的引用  
  33.         @type CanvasRenderingContext2D  
  34.     */  
  35.     this.context2D = null;  
  36.     /** 對內(nèi)存中用作后臺緩沖區(qū)的畫布的引用  
  37.         @type HTMLCanvasElement  
  38.     */  
  39.     this.backBuffer = null;  
  40.     /** 對后臺緩沖畫布的2D上下文的引用  
  41.         @type CanvasRenderingContext2D  
  42.     */  
  43.     this.backBufferContext2D = null;  
  44.  
  45.     /**  
  46.         初始化這個對象  
  47.         @return A reference to the initialised object  
  48.     */  
  49.     this.startupGameObjectManager = function()  
  50.     {  
  51.         // 設(shè)置引用this對象的全局指針  
  52.         g_GameObjectManager = this;  
  53.  
  54.         // 取得畫布元素及其2D上下文的引用  
  55.         this.canvas = document.getElementById('canvas');  
  56.         thisthis.context2D = this.canvas.getContext('2d');  
  57.         this.backBuffer = document.createElement('canvas');  
  58.         thisthis.backBuffer.width = this.canvas.width;  
  59.         thisthis.backBuffer.height = this.canvas.height;  
  60.         thisthis.backBufferContext2D = this.backBuffer.getContext('2d');  
  61.  
  62.         // 創(chuàng)建一個新的ApplicationManager  
  63.         this.applicationManager = new ApplicationManager().startupApplicationManager();  
  64.  
  65.         // 使用setInterval來調(diào)用draw函數(shù)  
  66.         setInterval(function(){g_GameObjectManager.draw();}, SECONDS_BETWEEN_FRAMES);  
  67.  
  68.         return this;  
  69.     }  
  70.  
  71.     /**  
  72.         渲染循環(huán)  
  73.     */  
  74.     this.draw = function ()  
  75.     {  
  76.         // 計算從上一幀到現(xiàn)在的時間  
  77.         var thisFrame = new Date().getTime();  
  78.         var dt = (thisFrame - this.lastFrame)/1000;  
  79.         this.lastFrame = thisFrame;  
  80.  
  81.         // 清理繪制上下文  
  82.         this.backBufferContext2D.clearRect(0, 0, this.backBuffer.width, this.backBuffer.height);  
  83.         this.context2D.clearRect(0, 0, this.canvas.width, this.canvas.height);  
  84.  
  85.         // 首先更新所有游戲?qū)ο? 
  86.         for (x in this.gameObjects)  
  87.         {  
  88.             if (this.gameObjects[x].update)  
  89.             {  
  90.                 this.gameObjects[x].update(dt, this.backBufferContext2D, this.xScroll, this.yScroll);  
  91.             }  
  92.         }  
  93.  
  94.         // 然后繪制所有游戲?qū)ο? 
  95.         for (x in this.gameObjects)  
  96.         {  
  97.             if (this.gameObjects[x].draw)  
  98.             {  
  99.                 this.gameObjects[x].draw(dt, this.backBufferContext2D, this.xScroll, this.yScroll);  
  100.             }  
  101.         }  
  102.  
  103.         // 將后臺緩沖復(fù)制到當(dāng)前顯示的畫布  
  104.         this.context2D.drawImage(this.backBuffer, 0, 0);  
  105.     };  
  106.  
  107.     /**  
  108.         向gameObjects集合中添加一個GameObject  
  109.         @param gameObject The object to add  
  110.     */  
  111.     this.addGameObject = function(gameObject)  
  112.     {  
  113.         this.gameObjects.push(gameObject);  
  114.         this.gameObjects.sort(function(a,b){return a.zOrder - b.zOrder;})  
  115.     };  
  116.  
  117.     /**  
  118.         從gameObjects集合中刪除一個GameObject  
  119.         @param gameObject The object to remove  
  120.     */  
  121.     this.removeGameObject = function(gameObject)  
  122.     {  
  123.         this.gameObjects.removeObject(gameObject);  
  124.     }  
  125. }  

首先看一看GameObjectManager類。GameObjectManager是一個引擎類,用于管理畫布的繪制操作,還負(fù)責(zé)分派GameObject類(下一篇文章里介紹)的事件。

GameObjectManager類的startupGameObjectManager函數(shù)的代碼如下:

  1.  
  2. /**  
  3.     初始化這個對象  
  4.     @return A reference to the initialised object  
  5. */  
  6. this.startupGameObjectManager = function()  
  7. {  
  8.     // 設(shè)置引用this對象的全局指針  
  9.     g_GameObjectManager = this;  
  10.  
  11.     // 取得畫布元素及其2D上下文的引用  
  12.     this.canvas = document.getElementById('canvas');  
  13.     thisthis.context2D = this.canvas.getContext('2d');  
  14.     this.backBuffer = document.createElement('canvas');  
  15.     thisthis.backBuffer.width = this.canvas.width;  
  16.     thisthis.backBuffer.height = this.canvas.height;  
  17.     thisthis.backBufferContext2D = this.backBuffer.getContext('2d');  
  18.  
  19.     // 創(chuàng)建一個新的ApplicationManager  
  20.     this.applicationManager = new ApplicationManager().startupApplicationManager();  
  21.  
  22.     // 使用setInterval來調(diào)用draw函數(shù)  
  23.     setInterval(function(){g_GameObjectManager.draw();}, SECONDS_BETWEEN_FRAMES);  
  24.  
  25.     return this;  
  26. }  

前面已經(jīng)說過,我們會把每個類的初始化工作放在startupClassName函數(shù)中來做。因此,GameObjectManager類將由startupGameObjectManager函數(shù)進(jìn)行初始化。

而引用這個GameObjectManager實例的全局變量g_GameObjectManager經(jīng)過重新賦值,指向了這個新實例。

  1. // 設(shè)置引用this對象的全局指針  
  2. g_GameObjectManager = this;  

對畫布元素及其繪圖上下文的引用也同樣保存起來:

  1. // 取得畫布元素及其2D上下文的引用  
  2. this.canvas = document.getElementById('canvas');  
  3. thisthis.context2D = this.canvas.getContext('2d');  

在前面的例子中,所有繪圖操作都是直接在畫布元素上完成的。這種風(fēng)格的渲染一般稱為單緩沖渲染。在此,我們要使用一種叫做雙緩沖渲染的技術(shù):任意游戲?qū)ο蟮乃欣L制操作,都將在一個內(nèi)存中的附加畫布元素(后臺緩沖)上完成,完成后再通過一次操作把它復(fù)制到網(wǎng)頁上的畫布元素(前臺緩沖)。

雙緩沖技術(shù)(http://www.brighthub.com/internet/web-development/articles/11012.aspx)通常用于減少畫面抖動。我自己在測試的時候從沒發(fā)現(xiàn)直接向畫布元素上繪制有抖動現(xiàn)象,但我在網(wǎng)上的確聽別人念叨過,使用單緩沖渲染會導(dǎo)致某些瀏覽器在渲染時發(fā)生抖動。

不管怎么說,雙緩沖還是能夠避免最終用戶看到每個游戲?qū)ο笤诶L制過程中最后一幀的組合過程。在通過JavaScript執(zhí)行某些復(fù)雜繪制操作時(例如透明度、反鋸齒及可編程紋理),這種情況是完全可能發(fā)生的。

使用附加緩沖技術(shù)占用的內(nèi)存非常少,多執(zhí)行一次圖像復(fù)制操作(把后臺緩沖繪制到前臺緩沖)導(dǎo)致的性能損失也可以忽略不計,可以說實現(xiàn)雙緩沖系統(tǒng)沒有什么缺點。

如果將在HTML頁面中定義的畫布元素作為前臺緩沖,那就需要再創(chuàng)建一個畫布來充當(dāng)后臺緩沖。為此,我們使用了document.createElement函數(shù)在內(nèi)存里創(chuàng)建了一個畫布元素,把它用作后臺緩沖。

  1. this.backBuffer = document.createElement('canvas');  
  2. thisthis.backBuffer.width = this.canvas.width;  
  3. thisthis.backBuffer.height = this.canvas.height;  
  4. thisthis.backBufferContext2D = this.backBuffer.getContext('2d');  

接下來,我們創(chuàng)建了ApplicationManager類的一個新實例,并調(diào)用startupApplicationManager來初始化它。這個ApplicationManager類將在下一篇文章中介紹。

  1. // 創(chuàng)建一個新的ApplicationManager  
  2. this.applicationManager = new ApplicationManager().startupApplicationManager();  

最后,使用setInterval函數(shù)重復(fù)調(diào)用draw函數(shù),這個函數(shù)是渲染循環(huán)的核心所在。

  1. // 使用setInterval來調(diào)用draw函數(shù)  
  2. setInterval(function(){g_GameObjectManager.draw();}, SECONDS_BETWEEN_FRAMES);  

#p#

下面來看一看draw函數(shù)。

  1. /**  
  2.     渲染循環(huán)  
  3. */  
  4. this.draw = function ()  
  5. {  
  6.     // 計算從上一幀到現(xiàn)在的時間  
  7.     var thisFrame = new Date().getTime();  
  8.     var dt = (thisFrame - this.lastFrame)/1000;  
  9.     this.lastFrame = thisFrame;  
  10.  
  11.     // 清理繪制上下文  
  12.     this.backBufferContext2D.clearRect(0, 0, this.backBuffer.width, this.backBuffer.height);  
  13.     this.context2D.clearRect(0, 0, this.canvas.width, this.canvas.height);  
  14.  
  15.     // 首先更新所有游戲?qū)ο? 
  16.     for (x in this.gameObjects)  
  17.     {  
  18.         if (this.gameObjects[x].update)  
  19.         {  
  20.             this.gameObjects[x].update(dt, this.backBufferContext2D, this.xScroll, this.yScroll);  
  21.         }  
  22.     }  
  23.  
  24.     // 然后繪制所有游戲?qū)ο? 
  25.     for (x in this.gameObjects)  
  26.     {  
  27.         if (this.gameObjects[x].draw)  
  28.         {  
  29.             this.gameObjects[x].draw(dt, this.backBufferContext2D, this.xScroll, this.yScroll);  
  30.         }  
  31.     }  
  32.  
  33.     // 將后臺緩沖復(fù)制到當(dāng)前顯示的畫布  
  34.     this.context2D.drawImage(this.backBuffer, 0, 0);  
  35. };  

這個draw函數(shù)就是所有渲染循環(huán)的核心。在前面的例子中,渲染循環(huán)的函數(shù)會直接修改要繪制到屏幕上的對象(笑臉)。如果只需繪制一個對象,這樣做沒有問題。但是,一個游戲要由幾十個單獨的對象組成,所以這個draw函數(shù)并沒有直接在渲染循環(huán)中直接處理要繪制的對象,而是維護(hù)了一個保存著這些對象的數(shù)組,讓這些對象自己來更新和繪制自己。

首先,計算自上一幀渲染所經(jīng)過的時間。即便我們在代碼里寫了每秒鐘調(diào)用30次draw函數(shù),但誰也無法保證事實如此。通過計算自上一幀渲染所經(jīng)過的時間,可以做到盡可能讓游戲的執(zhí)行與幀速率無關(guān)。

  1. // 計算從上一幀到現(xiàn)在的時間  
  2. var thisFrame = new Date().getTime();  
  3. var dt = (thisFrame - this.lastFrame)/1000;  
  4. this.lastFrame = thisFrame;  

接著清理繪制上下文。

  1. // 清理繪制上下文  
  2. this.backBufferContext2D.clearRect(0, 0, this.backBuffer.width, this.backBuffer.height);  
  3. this.context2D.clearRect(0, 0, this.canvas.width, this.canvas.height);  

然后,就是調(diào)用游戲?qū)ο?這些對象是由GameObject類定義的,下一篇文章將介紹該類)自己的更新(update)和繪制(draw)方法。注意,這兩個方法是可選的(這也是我們在調(diào)用它們之前先檢查它們是否存在的原因),但差不多每一個對象都需要更新和繪制自已。

  1. // 首先更新所有游戲?qū)ο? 
  2. for (x in this.gameObjects)  
  3. {  
  4.     if (this.gameObjects[x].update)  
  5.     {  
  6.         this.gameObjects[x].update(dt, this.backBufferContext2D, this.xScroll, this.yScroll);  
  7.     }  
  8. }  
  9.  
  10. // 然后繪制所有游戲?qū)ο? 
  11. for (x in this.gameObjects)  
  12. {  
  13.     if (this.gameObjects[x].draw)  
  14.     {  
  15.         this.gameObjects[x].draw(dt, this.backBufferContext2D, this.xScroll, this.yScroll);  
  16.     }  
  17. }  

最后,把后臺緩沖復(fù)制到前臺緩沖,最終用戶就可以看到下一幀了。

  1. // 將后臺緩沖復(fù)制到當(dāng)前顯示的畫布  
  2. this.context2D.drawImage(this.backBuffer, 0, 0);  

理解了draw函數(shù),下面再分別講一講addGameObject和removeGameObject函數(shù)。

  1. /**  
  2.     向gameObjects集合中添加一個GameObject  
  3.     @param gameObject The object to add  
  4. */  
  5. this.addGameObject = function(gameObject)  
  6. {  
  7.     this.gameObjects.push(gameObject);  
  8.     this.gameObjects.sort(function(a,b){return a.zOrder - b.zOrder;})  
  9. };  
  10.  
  11. /**  
  12.     從gameObjects集合中刪除一個GameObject  
  13.     @param gameObject The object to remove  
  14. */  
  15. this.removeGameObject = function(gameObject)  
  16. {  
  17.     this.gameObjects.removeObject(gameObject);  
  18. }  

利用addGameObject和removeGameObject(在Utils.js文件里通過擴(kuò)展Array.prototype添加)函數(shù),可以在GameObjectManager所維護(hù)的GameObject集合(即gameObjects變量)中添加和刪除游戲?qū)ο蟆?/p>

GameObjectManager類是我們這個游戲框架中最復(fù)雜的一個類。在下一篇文章中,我們會講解游戲框架的另外幾個類:GameObject、VisualGameObject、Bounce和ApplicationManager。

好了,現(xiàn)在放松一下,看一看Demo吧

原文:http://www.brighthub.com/content/matthewcaspersonshubfoliohasmoved.aspx

譯文:http://www.cn-cuckoo.com/2011/08/14/game-development-with-javascript-and-the-canvas-element-3-2604.html

【編輯推薦】

  1. 使用JavaScript和Canvas開發(fā)游戲之認(rèn)識Canvas
  2. HTML 5 Canvas(畫布)教程之圖像處理
  3. HTML 5新特性Canvas入門秘籍
  4. 15個不可思議的HTML 5 Canvas應(yīng)用欣賞
  5. 使用JavaScript和Canvas開發(fā)游戲之使用Canvas
責(zé)任編輯:陳貽新 來源: 李松峰博客
相關(guān)推薦

2011-08-12 08:56:31

JavaScript

2011-08-11 09:16:50

JavaScript

2015-06-29 11:30:07

JavaScript小烏龜推箱子

2022-08-10 18:14:49

國際象棋游戲位字段C語言

2019-05-14 12:30:07

PythonPygame游戲框架

2011-11-03 09:13:27

JavaScript

2016-11-29 13:31:52

JavaScriptsetTimeout定時執(zhí)行

2011-10-21 09:10:12

JavaScript

2021-03-30 05:58:01

JavascriptCss3轉(zhuǎn)盤小游戲

2014-02-14 09:37:01

JavascriptDOM

2013-01-14 09:44:58

JavaScriptJSJS框架

2021-02-05 16:03:48

JavaScript游戲?qū)W習(xí)前端

2020-11-30 06:20:13

javascript

2017-06-08 15:53:38

PythonWeb框架

2021-09-08 08:36:50

ncursesLinux猜謎游戲

2015-06-02 04:13:23

Python乒乓球類游戲

2021-04-13 06:35:13

Elixir語言編程語言軟件開發(fā)

2023-03-01 10:19:23

2024-01-15 00:35:23

JavaScript框架HTML

2022-09-01 11:48:45

JavaScript框架
點贊
收藏

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

黄免费在线观看| 国产日韩亚洲欧美在线| 国产又粗又猛又爽又黄视频| 欧美自拍偷拍| 欧美一级免费观看| 国产欧美日韩小视频| 免费在线一级视频| 久久99国产精品麻豆| 国内自拍欧美激情| 精品国产大片大片大片| 国产一区福利| 欧美日韩国产免费| www在线观看免费| 欧美日韩视频在线播放| av电影在线观看一区| 国产精品入口尤物| 日韩欧美国产亚洲| 亚洲乱码电影| 亚洲色图av在线| 国产又黄又嫩又滑又白| 国产精品麻豆成人av电影艾秋| 一区二区三区精密机械公司| 日韩精品成人一区二区在线观看| 精品国产免费无码久久久| 久久精品观看| 中文字幕+乱码+中文字幕一区| 97超级碰碰| 影音先锋黄色网址| 久久青草久久| 久久久久久国产免费 | 国产乱国产乱老熟| 欧美在线网站| 神马久久桃色视频| 亚洲久久久久久久| 免费萌白酱国产一区二区三区| 在线综合视频播放| 亚洲77777| 精品国产第一福利网站| 五月天久久比比资源色| 国产在线xxxx| 欧美野外wwwxxx| 一区二区中文字幕在线| 天堂精品一区二区三区| 青青草娱乐在线| 91最新地址在线播放| 国产chinese精品一区二区| 国产精品毛片久久久久久久av| 日韩激情av在线| 热99在线视频| 欧美日韩综合一区二区三区| 亚洲一区欧美二区| 国产91精品视频在线观看| av无码精品一区二区三区| 91久久精品www人人做人人爽| 性欧美精品男男| 网友自拍区视频精品| 亚洲国产精品久久精品怡红院| 麻豆免费在线观看视频| 日韩有吗在线观看| 日韩欧美国产一区二区在线播放| 欧美一级特黄aaa| 成人动漫视频在线观看| 91精品视频网| 又色又爽又黄18网站| 中文无码日韩欧| 日韩美女一区二区三区四区| 丰满人妻一区二区三区大胸| 中文字幕日韩高清在线| 亚洲国产成人久久综合| 久久久午夜精品福利内容| 日韩成人av在线资源| 精品一区二区三区四区在线| aaaaa一级片| av永久不卡| 久久天天躁狠狠躁夜夜av| 私库av在线播放| 亚洲国产日本| 青青a在线精品免费观看| 婷婷激情五月综合| 精品一区二区三区视频| 99re国产视频| 天堂成人在线| 久久综合久久综合久久综合| 久久99精品久久久久久三级| 国产福利电影在线| 亚洲免费在线播放| 日韩av三级在线| 日韩制服一区| 日韩欧美不卡在线观看视频| 国产ts丝袜人妖系列视频| 欧美亚洲在线日韩| 欧美多人乱p欧美4p久久| 国产欧美一区二区三区在线看蜜臂| 日韩精品一区第一页| 亚洲wwwav| 欧美午夜黄色| 亚洲欧美日韩久久| aa免费在线观看| 国产精品一区二区三区av| 亚洲成人a级网| 东京热无码av男人的天堂| 亚洲五月婷婷| 国产美女精品视频免费观看| 黄色a在线观看| 国产精品理论在线观看| 国内精品在线观看视频| 国产精品99久久久久久董美香| 日韩免费在线观看| 中文字幕第24页| 伊人影院久久| 91精品视频播放| 国产福利在线| 偷拍亚洲欧洲综合| www.日本久久| 国产一区2区| 国内精品视频久久| 精品国产无码一区二区三区| 国产丝袜欧美中文另类| 色欲色香天天天综合网www| 永久免费观看精品视频| 亚洲色图综合网| 日韩成年人视频| 国产美女一区二区| 亚洲午夜精品久久久久久浪潮| 天堂av在线| 精品国产免费视频| 欧美精品久久久久久久久46p| 肉丝袜脚交视频一区二区| 国产另类第一区| 一色桃子av在线| 欧美巨大另类极品videosbest| 国产中文字幕一区二区| 亚洲第一在线| 岛国一区二区三区高清视频| 二区三区在线观看| 555www色欧美视频| 极品美妇后花庭翘臀娇吟小说| 天堂蜜桃91精品| 久久综合福利| 亚洲女同志freevdieo| 亚洲电影天堂av| 亚洲一区二区91| 国产xxx精品视频大全| 国风产精品一区二区| 国产亚洲高清一区| 久久精品国产v日韩v亚洲| 伊人网av在线| 中文字幕av不卡| xxx国产在线观看| 久久国产影院| 91精品国产综合久久久久久久久| 18免费在线视频| 欧美日韩一级黄| 少妇高潮在线观看| 国产剧情一区二区| 无码熟妇人妻av在线电影| 88久久精品| 久久久久国产视频| 性猛交xxxx| 欧美性猛交xxxx富婆| 波多野结衣 在线| 老司机免费视频久久| 亚洲草草视频| 国产乱码精品一区二区三区亚洲人 | 尤物tv在线精品| 清纯唯美亚洲激情| 成人三级黄色免费网站| 欧美人牲a欧美精品| 夫妻性生活毛片| 国产成人精品三级| 欧美视频在线免费播放| 国产一区不卡| 国产在线精品自拍| 精品日韩av| 亚洲欧美国产va在线影院| 人妻中文字幕一区二区三区| 日韩久久一区二区| 日本xxxx免费| 久久久999| 一个色的综合| 国产厕拍一区| 国产精品久久久久久久美男| 国产区在线观看| 亚洲成av人影院在线观看| 黄色免费av网站| 亚洲天堂精品在线观看| 中国极品少妇xxxx| 日韩国产欧美一区二区三区| 色哟哟免费网站| 亚瑟一区二区三区四区| 成人黄色av播放免费| hd国产人妖ts另类视频| 在线观看精品自拍私拍| 亚洲a视频在线观看| 一本一道久久a久久精品综合蜜臀| 在线观看日本黄色| 成人福利在线看| 天天色综合社区| 最新日韩在线| 一区二区三区四区在线视频| 国产调教精品| 成人av资源在线播放| 91超碰在线| 精品国产拍在线观看| 视频国产在线观看| 日韩美女一区二区三区四区| 亚洲怡红院av| 大荫蒂欧美视频另类xxxx| 日韩一级片av| 国产精品三级在线观看| 中文乱码人妻一区二区三区视频| 精品亚洲成a人在线观看| 亚洲中文字幕无码中文字| 欧美成人日韩| 亚洲国产精品视频一区| 色天下一区二区三区| 成人精品水蜜桃| 日韩成人在线一区| 国产aⅴ夜夜欢一区二区三区| 日本h片在线观看| 久久精品国产91精品亚洲| 国产三区四区在线观看| 日韩av最新在线观看| 亚洲第一页视频| 欧美精品1区2区3区| 国语对白做受69按摩| 欧美日韩国产综合视频在线观看中文 | www.av中文字幕| 欧美成人首页| 9色视频在线观看| 天天射成人网| 亚洲欧美久久234| 欧美精品一二| 日本一区二区三区免费看| 思热99re视热频这里只精品| 国产日韩精品推荐| 国产精品美女在线观看直播| 亚洲综合大片69999| 成人黄色理论片| 亚洲精品欧美日韩专区| 亚洲精品一区二区在线播放∴| 国产精品人成电影| 成人黄色在线| 国产中文欧美精品| 四虎国产精品永久在线国在线| 国产欧美精品日韩| 一区二区三区日本视频| 亚洲综合精品一区二区| 日韩区一区二| 国产精品麻豆免费版| 都市激情久久| 精品国产一二| 亚洲毛片免费看| 欧美亚洲另类久久综合| 国产一区二区三区四区五区传媒 | 国产国产精品| 五月天综合婷婷| 欧美日韩国产一区精品一区| 国内少妇毛片视频| 亚洲黄色影院| 国产裸体舞一区二区三区| 日韩电影网1区2区| 91福利免费观看| 国产成人小视频| 国产精品第七页| 欧美激情在线免费观看| 91av手机在线| 一区二区三区高清| 国产成人在线观看网站| 日韩欧美在线一区| 中文字幕一区二区在线视频| 欧美一级二级三级蜜桃| 人妻无码一区二区三区久久99| 亚洲精品电影久久久| 国产福利第一视频在线播放| 久久国产一区二区三区| 一色桃子av在线| 日韩av手机在线观看| 91久久青草| 国产三区精品| av中文字幕一区二区| 青青草免费在线视频观看| 99视频一区| 无尽裸体动漫2d在线观看| 懂色av一区二区夜夜嗨| 国产成人无码精品久久二区三| 自拍偷拍国产亚洲| 日韩 欧美 精品| 在线播放亚洲一区| 天堂中文在线官网| 最新69国产成人精品视频免费| 日本电影在线观看网站| 国外成人性视频| 中文成人在线| 久久久一本精品99久久精品66| 日韩午夜电影网| 777777av| 国产一区激情在线| 久久av无码精品人妻系列试探| 亚洲视频一二三区| 少妇高潮av久久久久久| 日韩美女一区二区三区四区| 9191在线| 538国产精品一区二区在线| 免费观看亚洲天堂| 亚洲国产高清国产精品| 亚洲一区黄色| 女教师高潮黄又色视频| 中文字幕第一区第二区| 草久久免费视频| 欧美va在线播放| av电影在线观看| 欧美中文在线观看国产| 久久影院一区二区三区| 亚洲欧美日韩不卡一区二区三区| 国产亚洲永久域名| 亚洲成人精品在线播放| 亚洲欧洲国产日韩| 久久久精品毛片| 日韩精品免费电影| 福利在线导航136| 亚洲一区制服诱惑| 日韩久久精品| www.欧美日本| 久久久欧美精品sm网站| 1级黄色大片儿| 精品国产乱码91久久久久久网站| 精品麻豆一区二区三区| 国产精品三级美女白浆呻吟| 欧美激情在线免费| 激情五月宗合网| jizz一区二区| 国产午夜小视频| 精品99久久久久久| 欧美黑人猛交的在线视频| 亚洲综合中文字幕在线| 91精品电影| 又黄又爽又色的视频| 椎名由奈av一区二区三区| 一级二级三级视频| 日韩专区中文字幕| 日韩美女在线| 在线综合视频网站| 国产专区欧美精品| www.毛片com| 日韩欧美高清一区| av资源一区| 精品中文字幕一区| 午夜一区在线| 色欲AV无码精品一区二区久久 | 网友自拍区视频精品| 亚洲欧洲日产国码无码久久99| 91在线观看污| www.久久精品视频| 一级做a爰片久久毛片美女图片| gogo亚洲高清大胆美女人体| 日本一区二区在线| 免费高清视频精品| 国精产品一区一区二区三区mba| 777欧美精品| 羞羞网站在线免费观看| 国产精品一区二区a| 玖玖国产精品视频| 亚洲a∨无码无在线观看| 在线播放亚洲一区| 黑人精品视频| 麻豆av一区二区| 奇米色777欧美一区二区| 91插插插插插插| 精品毛片乱码1区2区3区| 美女91在线看| 色999五月色| 国产suv一区二区三区88区| 日韩精品一区二区三| 一区二区福利视频| 免费观看亚洲视频大全| 日本精品免费在线观看| 中文字幕一区免费在线观看| 亚洲精品福利网站| 国产成+人+综合+亚洲欧洲| 99久久久久| 黄色录像a级片| 欧美日韩一区久久| 免费影视亚洲| 亚洲第一导航| 国产成人高清在线| 午夜视频网站在线观看| 九九九久久国产免费| 免费久久久久久久久| 永久免费黄色片| 欧美午夜片在线免费观看| 高h视频在线观看| 欧美日韩一区二区三区在线视频| 激情综合色综合久久| 日韩在线视频免费播放| 大量国产精品视频| 国产在线观看91一区二区三区| 日本高清免费观看| 色妹子一区二区| 男男gaygays亚洲|