色哟哟视频在线观看-色哟哟视频在线-色哟哟欧美15最新在线-色哟哟免费在线观看-国产l精品国产亚洲区在线观看-国产l精品国产亚洲区久久

0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

如何構建Arduino供電的迷你復古游戲機

454398 ? 來源:網絡整理 ? 作者:網絡整理 ? 2019-11-29 09:01 ? 次閱讀

曾經想知道編寫自己的復古游戲需要多少工作? Pong為Arduino編寫代碼有多容易?和我一起,向我展示如何構建Arduino供電的迷你復古游戲機,以及如何從頭開始編寫Pong。最終結果如下:

構建計劃

這是一個相當簡單的電路。 電位器(電位器)將控制游戲,而Arduino將會驅動OLED顯示屏。這將在面包板上生產,但是您可能希望將其制成永久性電路并將其安裝在箱子中。之前我們已經寫過有關重新創建Pong的文章,但是今天我將向您展示如何從頭開始編寫代碼,并分解每個部分。

您需要的內容

這是您需要的:

1 x Arduino(任何型號)

1 x 10k電位器

1 x 0.96英寸I2C OLED顯示屏

1 x面包板

各種公頭》公連接線

任何Arduino都應該工作,請查看我們的購買指南如果您不確定要購買哪種型號。

這些OLED顯示器非???。通常可以購買白色,藍色,黃色或這三種的混合物。它們確實是全彩色的,但是它們又增加了該項目的復雜性和成本。

電路

這是一個非常簡單的電路。如果您對Arduino沒有太多的經驗,請先查看這些初學者項目。

在這里是:

在鍋的前面,將左引腳連接到 + 5V ,將右引腳連接到接地。將中間引腳連接到模擬引腳0 (A0)。

使用I2C協議連接OLED顯示器。將 VCC 和 GND 連接到Arduino + 5V 和接地。將 SCL 連接到模擬五( A5 )。將 SDA 連接到模擬4 ( A4 )。它連接到模擬引腳的原因很簡單。這些引腳包含I2C協議所需的電路。確保它們正確連接,并且沒有交叉。確切的引腳會因型號而異,但是Nano和Uno會使用A4和A5。如果您未使用Arduino或Nano,請查看模型的Wire庫文檔。

電位器測試

上傳此測試代碼(請確保從中選擇正確的電路板和端口工具》 面板和工具》 端口菜單):

void setup() {

// put your setup code here, to run once:

Serial.begin(9600); // setup serial

}

void loop() {

// put your main code here, to run repeatedly:

Serial.println(analogRead(A0)); // print the value from the pot

delay(500);

}

現在打開串行監視器(右上》 串行監視器)并轉動鍋。您應該看到在串行監視器上顯示的值。完全逆時針應為零,完全逆時針應為 1023 :

您稍后會對此進行調整,但現在就可以了。如果什么也沒有發生,或者您不做任何事情就改變了值,請斷開并仔細檢查電路。

OLED測試

OLED顯示的配置稍微復雜一些。您需要安裝兩個庫才能首先驅動顯示。從Github下載Adafruit_SSD1306和Adafruit-GFX庫。將文件復制到您的庫文件夾中。這取決于您的操作系統

Mac OS:/用戶/用戶名/Documents/Arduino/libraries

Linux:/home/Username/Sketchbook

Windows:/Users/Arduino/libraries

現在上傳測試草圖。轉到文件》 示例》 Adafruit SSD1306 》 ssd1306_128x64_i2c 。這應該給您一個包含大量圖形的大草圖:

如果上傳后沒有任何反應,請斷開連接并再次檢查您的連接。如果示例不在菜單中,則可能需要重新啟動Arduino IDE。

代碼

現在是時候編寫代碼了。我將解釋每個步驟,所以如果您只想使其運行,請跳到最后。這是相當數量的代碼,因此,如果您不確定,請查看以下10個免費資源以學習編碼。

首先包括必要的庫:

#include

#include

#include

#include

SPI 和 WIRE 是用于處理I2C通信的兩個Arduino庫。 Adafruit_GFX 和 Adafruit_SSD1306 是您先前安裝的庫。

下一步,配置顯示:

Adafruit_SSD1306 display(4);

然后設置運行游戲所需的所有變量:

int resolution[2] = {128, 64}, ball[2] = {20, (resolution[1] / 2)};

const int PIXEL_SIZE = 8, WALL_WIDTH = 4, PADDLE_WIDTH = 4, BALL_SIZE = 4, SPEED = 3;

int playerScore = 0, aiScore = 0, playerPos = 0, aiPos = 0;

char ballDirectionHori = ‘R’, ballDirectionVerti = ‘S’;

boolean inProgress = true;

這些變量存儲運行游戲所需的所有數據。其中一些存儲球的位置,屏幕的大小,球員的位置等。請注意其中的一些是 const 的意思,它們是恒定的,并且永遠不會改變。

屏幕分辨率和焊球位置存儲在數組中。數組是相似事物的集合,對于球,存儲坐標( X 和 Y )。訪問數組中的元素很容易(不要在文件中包含此代碼):

resolution[1];

由于數組從零開始,因此將返回分辨率數組中的第二個元素( 64 )。更新元素甚至更容易(同樣,不包含此代碼):

ball[1] = 15;

在 void setup()內,配置顯示:/p》 void setup() {

display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

display.display();

}

第一行告訴Adafruit庫,您的顯示器正在使用什么尺寸和通訊協議(在這種情況下,為 128 x 64 和 I2C )。第二行( display.display())告訴屏幕顯示緩沖區中存儲的內容(無內容)。

創建兩個名為 drawBall 和 eraseBall :

void drawBall(int x, int y) {

display.drawCircle(x, y, BALL_SIZE, WHITE);

}

void eraseBall(int x, int y) {

display.drawCircle(x, y, BALL_SIZE, BLACK);

}

這些采用 x 和 y 坐標并使用顯示庫中的 drawCircle 方法將其繪制在屏幕上。這使用了前面定義的常量 BALL_SIZE 。嘗試更改此設置,看看會發生什么。此drawCircle方法接受像素顏色-黑色或白色。因為這是單色顯示(一種顏色),所以白色表示像素處于打開狀態,黑色表示像素處于關閉狀態。

現在創建一種稱為 moveAi 的方法:

void moveAi() {

eraseAiPaddle(aiPos);

if (ball[1] 》 aiPos) {

++aiPos;

}

else if (ball[1] 《 aiPos) {

--aiPos;

}

drawAiPaddle(aiPos);

}

此方法處理移動人工智能或 AI 播放器。這是一個非常簡單的計算機對手-如果球在槳上方,請向上移動。它在槳下面,向下移動。很簡單,但是效果很好。增量和減量符號( ++ aiPos 和 –aiPos )用于從aiPosition中添加或減去一個。您可以添加或減去更大的數字以使AI更快地移動,因此更難以克服。這樣做的方法如下:

aiPos += 2;

并且:

aiPos -= 2;

加號等于和負號符號是aiPos當前值加/減兩個的簡寫。這是另一種方法:

aiPos = aiPos + 2;

aiPos = aiPos - 1;

注意此方法如何首先擦除槳,并且然后再次繪制。必須這樣做。如果繪制了新的槳葉位置,則屏幕上將有兩個重疊的槳葉。

drawNet 方法使用兩個循環繪制球網:

void drawNet() {

for (int i = 0; i 《 (resolution[1] / WALL_WIDTH); ++i) {

drawPixel(((resolution[0] / 2) - 1), i * (WALL_WIDTH) + (WALL_WIDTH * i), WALL_WIDTH);

}

}

這將使用 WALL_WIDTH 變量來設置其大小。

創建名為 drawPixels 和的方法擦除像素。就像球形方法一樣,兩者之間的唯一區別是像素的顏色:

void drawPixel(int posX, int posY, int dimensions) {

for (int x = 0; x 《 dimensions; ++x) {

for (int y = 0; y 《 dimensions; ++y) {

display.drawPixel((posX + x), (posY + y), WHITE);

}

}

}

void erasePixel(int posX, int posY, int dimensions) {

for (int x = 0; x 《 dimensions; ++x) {

for (int y = 0; y 《 dimensions; ++y) {

display.drawPixel((posX + x), (posY + y), BLACK);

}

}

}

再次,這兩種方法都使用兩個 》循環繪制一組像素。循環不必使用庫 drawPixel 方法繪制每個像素,而是根據給定的尺寸繪制一組像素。

drawScore 方法使用庫的文本功能將播放器和AI得分寫入屏幕。這些存儲在 playerScore 和 aiScore 中:

void drawScore() {

display.setTextSize(2);

display.setTextColor(WHITE);

display.setCursor(45, 0);

display.println(playerScore);

display.setCursor(75, 0);

display.println(aiScore);

}

此方法還具有 eraseScore 對應,將像素設置為黑色或關閉。

最后四種方法非常相似。他們繪制并擦除了玩家和AI球拍:

void erasePlayerPaddle(int row) {

erasePixel(0, row - (PADDLE_WIDTH * 2), PADDLE_WIDTH);

erasePixel(0, row - PADDLE_WIDTH, PADDLE_WIDTH);

erasePixel(0, row, PADDLE_WIDTH);

erasePixel(0, row + PADDLE_WIDTH, PADDLE_WIDTH);

erasePixel(0, row + (PADDLE_WIDTH + 2), PADDLE_WIDTH);

}

注意他們如何調用之前創建的 erasePixel 方法。這些方法會繪制并擦除適當的槳。

主循環中還有更多邏輯。這是完整的代碼:

#include

#include

#include

#include

Adafruit_SSD1306 display(4);

int resolution[2] = {128, 64}, ball[2] = {20, (resolution[1] / 2)};

const int PIXEL_SIZE = 8, WALL_WIDTH = 4, PADDLE_WIDTH = 4, BALL_SIZE = 4, SPEED = 3;

int playerScore = 0, aiScore = 0, playerPos = 0, aiPos = 0;

char ballDirectionHori = ‘R’, ballDirectionVerti = ‘S’;

boolean inProgress = true;

void setup() {

display.begin(SSD1306_SWITCHCAPVCC, 0x3C);

display.display();

}

void loop() {

if (aiScore 》 9 || playerScore 》 9) {

// check game state

inProgress = false;

}

if (inProgress) {

eraseScore();

eraseBall(ball[0], ball[1]);

if (ballDirectionVerti == ‘U’) {

// move ball up diagonally

ball[1] = ball[1] - SPEED;

}

if (ballDirectionVerti == ‘D’) {

// move ball down diagonally

ball[1] = ball[1] + SPEED;

}

if (ball[1] 《= 0) { // bounce the ball off the top ballDirectionVerti = ‘D’; } if (ball[1] 》= resolution[1]) {

// bounce the ball off the bottom

ballDirectionVerti = ‘U’;

}

if (ballDirectionHori == ‘R’) {

ball[0] = ball[0] + SPEED; // move ball

if (ball[0] 》= (resolution[0] - 6)) {

// ball is at the AI edge of the screen

if ((aiPos + 12) 》= ball[1] && (aiPos - 12) 《= ball[1]) { // ball hits AI paddle if (ball[1] 》 (aiPos + 4)) {

// deflect ball down

ballDirectionVerti = ‘D’;

}

else if (ball[1] 《 (aiPos - 4)) {

// deflect ball up

ballDirectionVerti = ‘U’;

}

else {

// deflect ball straight

ballDirectionVerti = ‘S’;

}

// change ball direction

ballDirectionHori = ‘L’;

}

else {

// GOAL!

ball[0] = 6; // move ball to other side of screen

ballDirectionVerti = ‘S’; // reset ball to straight travel

ball[1] = resolution[1] / 2; // move ball to middle of screen

++playerScore; // increase player score

}

}

}

if (ballDirectionHori == ‘L’) {

ball[0] = ball[0] - SPEED; // move ball

if (ball[0] 《= 6) { // ball is at the player edge of the screen if ((playerPos + 12) 》= ball[1] && (playerPos - 12) 《= ball[1]) { // ball hits player paddle if (ball[1] 》 (playerPos + 4)) {

// deflect ball down

ballDirectionVerti = ‘D’;

}

else if (ball[1] 《 (playerPos - 4)) { // deflect ball up ballDirectionVerti = ‘U’; } else { // deflect ball straight ballDirectionVerti = ‘S’; } // change ball direction ballDirectionHori = ‘R’; } else { ball[0] = resolution[0] - 6; // move ball to other side of screen ballDirectionVerti = ‘S’; // reset ball to straight travel ball[1] = resolution[1] / 2; // move ball to middle of screen ++aiScore; // increase AI score } } } drawBall(ball[0], ball[1]); erasePlayerPaddle(playerPos); playerPos = analogRead(A2); // read player potentiometer playerPos = map(playerPos, 0, 1023, 8, 54); // convert value from 0 - 1023 to 8 - 54 drawPlayerPaddle(playerPos); moveAi(); drawNet(); drawScore(); } else { // somebody has won display.clearDisplay(); display.setTextSize(4); display.setTextColor(WHITE); display.setCursor(0, 0); // figure out who if (aiScore 》 playerScore) {

display.println(“YOU LOSE!”);

}

else if (playerScore 》 aiScore) {

display.println(“YOU WIN!”);

}

}

display.display();

}

void moveAi() {

// move the AI paddle

eraseAiPaddle(aiPos);

if (ball[1] 》 aiPos) {

++aiPos;

}

else if (ball[1] 《 aiPos) {

--aiPos;

}

drawAiPaddle(aiPos);

}

void drawScore() {

// draw AI and player scores

display.setTextSize(2);

display.setTextColor(WHITE);

display.setCursor(45, 0);

display.println(playerScore);

display.setCursor(75, 0);

display.println(aiScore);

}

void eraseScore() {

// erase AI and player scores

display.setTextSize(2);

display.setTextColor(BLACK);

display.setCursor(45, 0);

display.println(playerScore);

display.setCursor(75, 0);

display.println(aiScore);

}

void drawNet() {

for (int i = 0; i 《 (resolution[1] / WALL_WIDTH); ++i) {

drawPixel(((resolution[0] / 2) - 1), i * (WALL_WIDTH) + (WALL_WIDTH * i), WALL_WIDTH);

}

}

void drawPixel(int posX, int posY, int dimensions) {

// draw group of pixels

for (int x = 0; x 《 dimensions; ++x) {

for (int y = 0; y 《 dimensions; ++y) {

display.drawPixel((posX + x), (posY + y), WHITE);

}

}

}

void erasePixel(int posX, int posY, int dimensions) {

// erase group of pixels

for (int x = 0; x 《 dimensions; ++x) {

for (int y = 0; y 《 dimensions; ++y) {

display.drawPixel((posX + x), (posY + y), BLACK);

}

}

}

void erasePlayerPaddle(int row) {

erasePixel(0, row - (PADDLE_WIDTH * 2), PADDLE_WIDTH);

erasePixel(0, row - PADDLE_WIDTH, PADDLE_WIDTH);

erasePixel(0, row, PADDLE_WIDTH);

erasePixel(0, row + PADDLE_WIDTH, PADDLE_WIDTH);

erasePixel(0, row + (PADDLE_WIDTH + 2), PADDLE_WIDTH);

}

void drawPlayerPaddle(int row) {

drawPixel(0, row - (PADDLE_WIDTH * 2), PADDLE_WIDTH);

drawPixel(0, row - PADDLE_WIDTH, PADDLE_WIDTH);

drawPixel(0, row, PADDLE_WIDTH);

drawPixel(0, row + PADDLE_WIDTH, PADDLE_WIDTH);

drawPixel(0, row + (PADDLE_WIDTH + 2), PADDLE_WIDTH);

}

void drawAiPaddle(int row) {

int column = resolution[0] - PADDLE_WIDTH;

drawPixel(column, row - (PADDLE_WIDTH * 2), PADDLE_WIDTH);

drawPixel(column, row - PADDLE_WIDTH, PADDLE_WIDTH);

drawPixel(column, row, PADDLE_WIDTH);

drawPixel(column, row + PADDLE_WIDTH, PADDLE_WIDTH);

drawPixel(column, row + (PADDLE_WIDTH * 2), PADDLE_WIDTH);

}

void eraseAiPaddle(int row) {

int column = resolution[0] - PADDLE_WIDTH;

erasePixel(column, row - (PADDLE_WIDTH * 2), PADDLE_WIDTH);

erasePixel(column, row - PADDLE_WIDTH, PADDLE_WIDTH);

erasePixel(column, row, PADDLE_WIDTH);

erasePixel(column, row + PADDLE_WIDTH, PADDLE_WIDTH);

erasePixel(column, row + (PADDLE_WIDTH * 2), PADDLE_WIDTH);

}

void drawBall(int x, int y) {

display.drawCircle(x, y, BALL_SIZE, WHITE);

}

void eraseBall(int x, int y) {

display.drawCircle(x, y, BALL_SIZE, BLACK);

}

這是您最終得到的結果:

對代碼很有信心,您可以進行許多修改:

添加難度級別菜單(更改AI和球速)。

向其中添加一些隨機移動

為兩個玩家添加另一個底池。

添加一個暫停按鈕。

現在看看這些復古游戲Pi Zero項目。

責任編輯:wv

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 游戲機
    +關注

    關注

    9

    文章

    299

    瀏覽量

    33478
  • Arduino
    +關注

    關注

    188

    文章

    6471

    瀏覽量

    187244
收藏 人收藏

    評論

    相關推薦

    樹莓派與Arduino的區別是什么

    Pi): 樹莓派最初是作為教育工具設計的,旨在幫助學生學習計算機編程和電子工程。隨著時間的推移,它已經發展成為一個多功能的微型計算機,可以用于各種項目,包括但不限于: 家庭媒體中心 游戲機 網絡服務器 IoT(物聯網)設備 教育和學習平臺 Arduino
    的頭像 發表于 11-11 11:14 ?866次閱讀

    索尼PS5 Pro游戲機震撼發布

    游戲界的萬眾矚目下,索尼于近日舉行的PS5技術展示會上,由首席架構師Mark Cerny親自揭曉了萬眾期待的PS5 Pro游戲機。這款全新力作以699美元的定價,定于11月7日盛大發售,無疑為游戲愛好者們帶來了前所未有的震撼與
    的頭像 發表于 09-11 16:59 ?713次閱讀

    基于 FPGA 的飛機大戰游戲系統設計

    喜歡老式電子游戲的買家。一些愛好者一直在收集復古游戲產品,一些普通玩家也開始收集舊式磁帶和CD,還有小時候玩過的游戲機。 雖然復古
    發表于 07-24 20:03

    微軟開發者成功在任天堂 NES 游戲機上運行.NET

    游戲機被譽為“紅白”,搭載 1.78 MHz 的 8 位 CPU,內存僅有 2KB,游戲卡帶最大容量可達 512 Kilobytes。然而,這樣的設備如今運行安卓/iOS app 明顯吃力,因為現今的主流應用均大于 55-2
    的頭像 發表于 05-30 14:36 ?463次閱讀

    索尼或將于近期公布PS5 Pro游戲機及《宇宙機器人》新作發布日期

    5月份,Jeff Grubb曾透露索尼計劃近期發布PS5 Pro游戲主機,而近期揭示的眾多信息中亦可見到這個發布會的痕跡,甚至傳言《宇宙機器人》將作為新的作品亮相,進一步暗示索尼可能在此次發布會上推出PS5 Pro游戲機。
    的頭像 發表于 05-28 15:56 ?607次閱讀

    開源DIY!用 ESP32 制造迷你復古小電視

    MAKER :陳亮 這款迷你復古電視非常的小巧可愛,它會不會成為你的桌擺新寵呢!它無法接收模擬電視廣播信號,但是它可以通過微型 SD 卡播放錄像帶。你可以多準備幾套 SD 卡來播放你喜歡的節目
    發表于 05-27 11:01

    YXC可編程振蕩器,頻點22.578MHz,工作電壓3.3V,應用于游戲機

    游戲機是一種專門用于游戲運行的電子設備,它通過外界載體(如光盤、卡帶等)來運行游戲。與電腦和手機等多功能設備不同,游戲機專注于游戲體驗,具有
    的頭像 發表于 05-23 17:43 ?304次閱讀
    YXC可編程振蕩器,頻點22.578MHz,工作電壓3.3V,應用于<b class='flag-5'>游戲機</b>

    任天堂Switch初代游戲機模擬運行Windows 11 ARM效果展示

    5 月 14 日,某開發者PatRyk在X平臺發布帖子,展示了將任天堂Switch初代游戲機在Linux環境中通過QEMU模擬Windows 11 ARM系統的效果。
    的頭像 發表于 05-14 10:16 ?887次閱讀

    精選推薦!看大佬用樹莓派4做個迷你版PS5

    為了搭配這個迷你游戲主機,作者還制作了一個小型顯示器,使用了5英寸的樹莓派顯示屏。這只是一個有趣的小項目,但你也可以將它連接到任何你喜歡的顯示器或顯示屏。 ? 現在,你可以在上面玩各種復古游戲
    發表于 05-13 10:24

    Funkey游戲機新作,基于全志T113的全新版本

    不同于配置高端、性能強勁的Windows、安卓掌,有一部分的愛好者往往對擁有復古外形的開源掌更加感興趣。作為開源掌的熱門產品,小巧便攜的FunKeys掌
    發表于 05-11 11:04

    開源項目!做一臺基于 ESP32 DIY 復古游戲機

    等級。通過 BS138 MOSFET 晶體管完成控制顯示屏上嵌入的 LED 的電流。 完成 現在就可以運行這臺復古游戲機了,開啟你的復古游戲回憶之旅吧! 文章來源:https://w
    發表于 04-19 10:20

    全新HyperX Alloy Rise先鋒系列游戲機械鍵盤,有線連接,采用攝氏度

    據悉,惠普旗下品牌HyperX近期推出Alloy Rise先鋒系列游戲機械鍵盤,包括全尺寸RGB版及75%配列的先鋒75,價格從1299元起。
    的頭像 發表于 04-16 14:21 ?571次閱讀

    OrangePi?Neo:好玩不貴,最具性價比的游戲來了!

    3月24日,香橙派在深圳發布了備受期待的OrangePiNeo游戲。據稱,這款游戲售價4099元起,將為用戶帶來強大的性能和豐富的游戲
    的頭像 發表于 04-11 17:28 ?636次閱讀
    OrangePi?Neo:好玩不貴,最具性價比的<b class='flag-5'>游戲</b>掌<b class='flag-5'>機</b>來了!

    做一臺基于 ESP32 DIY 復古游戲機——MicroByte

    Arduino 庫以便進行游戲以外的開發工作。 作者的GitHub倉庫: https://github.com/jfm92/microByte 固件、PCB 設計、外殼 3D 文件等可以在文末下載。 BOM 清單: https://git
    的頭像 發表于 04-11 15:14 ?799次閱讀
    做一臺基于 ESP32 DIY <b class='flag-5'>復古</b><b class='flag-5'>游戲機</b>——MicroByte

    任天堂計劃2025年3月發布Switch 2游戲機

    根據推測,這款新游戲機或擁有類似原有型號Switch的手持特性,且配備尺寸較大的屏幕。盡管大部分業內人士預期新機即刻上市,但任天堂決定先進行銷售規劃及為開發者預留足夠的時間來制作受歡迎的游戲,從而達到簡化銷售過程之目的。
    的頭像 發表于 02-27 16:45 ?3082次閱讀
    主站蜘蛛池模板: 亚洲 无码 在线 专区| 国产免费播放一区二区三区 | 久久综合网久久综合| 古风H啪肉NP文| 97国产视频| 亚洲精品线在线观看| 秋霞电影网午夜鲁丝片| 久久亚洲国产中文字幕| 国产午夜精品久久理论片小说| qvod在线| 98久久人妻无码精品系列蜜桃| 亚洲精品国产品国语在线试看| 欧美性appstin孕妇| 久久伊人天堂视频网| 黄页网站18以下勿看免费| 国产精品第九页| 成 人 色综合| 99免费在线观看| 9277高清在线观看视频| 在线 国产 欧美 专区| 亚洲不卡视频在线| 桃花免费高清在线观看| 人和拘一级毛片| 欧美18videosex初次| 恋夜秀场支持安卓版全部视频国产 | 尿孔 调教 扩张| 巨黄的肉辣文np| 久久91精品国产91久久户| 国内精品久久久久影院男同志| 国产99小视频| 第四色男人天堂| 俄罗斯雏妓的BBB孩交| www国产av偷拍在线播放| 99视频福利| CHINSEFUCKGAY无套| 99热久久这里只有精品视频| 51精品国产AV无码久久久密桃| 中文字幕亚洲第一| 1区2区3区4区产品不卡码网站| 中文字幕欧美一区| 最近中文字幕2019免费版日本|