<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    我的家園

    我的家園

    本系列文章由zhmxy555編寫,轉(zhuǎn)載請注明出處。 文章鏈接  http://blog.csdn.net/zhmxy555/article/details/7447864

    作者:毛星云    郵箱: happylifemxy@qq.com    歡迎郵件交流編程心得



    這節(jié)筆記的主要內(nèi)容是介紹一個完整的回合制游戲demo,而這個demo里面主要突出了游戲里AI的各種思考與行為的方式.這樣的通過計算機角色本身的判斷思考,然后產(chǎn)生對應(yīng)行為的AI稱作行為型游戲AI。

    如果對AI基礎(chǔ)不太了解的朋友,請移步:


    【Visual C++】游戲開發(fā)筆記十五 游戲人工智能(一) 運動型游戲AI


    首先,我們來了解這種行為型AI的設(shè)計方法。

    游戲程序中計算機角色的思考與行為,實際上是對各種不同事件進行分析思考,然后根據(jù)不同的情況作出相應(yīng)的反應(yīng)。但如何對發(fā)生的條件進行判斷,并作出相應(yīng)的反應(yīng)呢?

    對,我們可以利用“if-else”條件句以及“switch-case”語句這類的判斷式來完成。

    通常情況下,設(shè)計此類AI,會涉及到連串的條件判斷句,簡單數(shù)學(xué)運算,及一些數(shù)據(jù)結(jié)構(gòu)的知識。



    下面我們就來具體講解這個demo涉及到的一些知識點:




    一、AI怪物攻擊與思考方式設(shè)計



    例如今天我們要展示的這個回合制游戲demo里的AI,就有如下幾種行為

    (1)利爪攻擊

    (2)閃電鏈攻擊

    (3)致命一擊

    (4)使用梅肯斯姆回復(fù)生命值

    (5)逃跑


    那么我們可以根據(jù)以上設(shè)計的怪物行為,設(shè)計以下一段算法,用來模擬怪物對戰(zhàn)時的思考與行為的方式:

    if(monster.nHp > 20)	 //生命值大于20
    {
    if(rand()%5!= 1)           
     //進行利爪攻擊概率4/5
    else
           //進行閃電鏈攻擊概率1/5
    }
    else	 //生命值小于20
    {
    switch(rand()%5)
    {
    case 0:	 //利爪攻擊
    break;
    case 1:	 //釋放閃電鏈
    break;
    case 2:	 //致命一擊
    break;
    case 3:	 //使用梅肯斯姆回復(fù)	 ;
    break;
    case 4:	 //逃跑
    if(1== rand()%3 )     //逃跑成功幾率1/3
    //逃跑成功
    else
    //逃跑失敗
    break;
    }
    }


    這段代碼中,利用if-else判斷式判斷怪物生命值,然后怪物有4/5的幾率釋放普通的利爪攻擊,有1/5的幾率釋放閃電鏈魔法攻擊,當(dāng)怪物重傷生命值小于20點時,也有一定的幾率逃跑。

    以上的利用“if-else”、“switch”語句,使計算機角色進行事件情況判斷,然后寫出相應(yīng)的動作實現(xiàn)代碼,這就是行為型游戲AI

    設(shè)計的核心精神。





    二,玩家角色攻擊方式設(shè)計


    然后我們再來設(shè)計一下玩家的攻擊技能。

    今天放出的這個demo里我給人物設(shè)定了兩個技能,一個主動的普通攻擊技能“無敵斬”,傷害計算公式為damage = rand()%10 + player.lv*player.w(player.lv為角色等級,player.w為攻擊系數(shù))。

    而被動技能為可以有一定幾率打出4倍暴擊傷害的“恩賜解脫”,這個技能是Dota里面幻影刺客的大招(呵呵,淺墨玩dota時可是超級幻刺控~~)。

    其實暴擊的實現(xiàn)方式很簡單,就是用if條件句進行概率的判斷(淺墨在這里利用4==rand( )%5來設(shè)定暴擊概率為20%),如果判斷成功就將“倍率x普通攻擊”作為damage的值。

    (哈哈,淺墨專門找到了Dota里面這兩個技能的圖標(biāo)以及用到了這個demo里面,具體效果圖在下面)


    下面貼出代碼人物技能的代碼:

    if (4==rand()%5)                   // 20%幾率觸發(fā)幻影刺客的大招,恩賜解脫,4倍暴擊傷害
    {
    damage = 4*(rand()%10 + player.lv*player.w);
    monster.nHp -= (int)damage;
    sprintf(str,"恩賜解脫觸發(fā),這下牛逼了,4倍暴擊...對怪物照成了%d點傷害",damage);
    } 
    else
    {
    damage = rand()%10 + player.lv*player.w;
    monster.nHp -= (int)damage;
    sprintf(str,"玩家使用了無敵斬,傷害一般般...對怪物照成了%d點傷害",damage);
    }
    




    三、完整的回合制游戲源代碼


    基礎(chǔ)部分就講解完了,下面就貼出注釋詳細的,完整的回合制游戲demo的代碼吧:

    #include "stdafx.h"
    #include <stdio.h>
    //定義一個結(jié)構(gòu)體
    struct chr
    {
    int	 nHp;
    int	 fHp;
    int	 lv;
    int	 w;
    int	 kind;
    };
    //全局變量聲明
    HINSTANCE hInst;
    HBITMAP	bg,sheep,girl,skill,skillult,slash,magic,recover,game;
    HDC	 hdc,mdc,bufdc;
    HWND	hWnd;
    DWORD	tPre,tNow;
    int	 pNum,f,txtNum;
    bool	attack,over;
    chr	 player,monster;
    char	text[5][100];
    //全局函數(shù)聲明
    ATOM	 MyRegisterClass(HINSTANCE hInstance);
    BOOL	 InitInstance(HINSTANCE, int);
    LRESULT CALLBACK	WndProc(HWND, UINT, WPARAM, LPARAM);
    void	 MyPaint(HDC hdc);
    void	 MsgInsert(char*);
    void	 CheckDie(int hp,bool player);
    //****WinMain函數(shù),程序入口點函數(shù)**************************************
    int APIENTRY WinMain(HINSTANCE hInstance,
                         HINSTANCE hPrevInstance,
                         LPSTR     lpCmdLine,
                         int       nCmdShow)
    {
    MSG msg;
    MyRegisterClass(hInstance);
    //初始化  
    if (!InitInstance (hInstance, nCmdShow)) 
    {
    return FALSE;
    }
    //消息循環(huán)
    GetMessage(&msg,NULL,NULL,NULL);            //初始化msg    
        while( msg.message!=WM_QUIT )
        {
            if( PeekMessage( &msg, NULL, 0,0 ,PM_REMOVE) )
            {
                TranslateMessage( &msg );
                DispatchMessage( &msg );
            }
    else
    {
    tNow = GetTickCount();
    if(tNow-tPre >= 40)
    MyPaint(hdc);
    }
        }
    return msg.wParam;
    }
    //***設(shè)計一個窗口類,類似填空題,使用窗口結(jié)構(gòu)體*************************
    ATOM MyRegisterClass(HINSTANCE hInstance)
    {
    WNDCLASSEX wcex;
    wcex.cbSize = sizeof(WNDCLASSEX); 
    wcex.style	 = CS_HREDRAW | CS_VREDRAW | CS_DBLCLKS;
    wcex.lpfnWndProc	= (WNDPROC)WndProc;
    wcex.cbClsExtra	 = 0;
    wcex.cbWndExtra	 = 0;
    wcex.hInstance	 = hInstance;
    wcex.hIcon	 = NULL;
    wcex.hCursor	 = NULL;
    wcex.hCursor	 = LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground	= (HBRUSH)(COLOR_WINDOW+1);
    wcex.lpszMenuName	= NULL;
    wcex.lpszClassName	= "canvas";
    wcex.hIconSm	 = NULL;
    return RegisterClassEx(&wcex);
    }
    //****初始化函數(shù)************************************
    //加載位圖并設(shè)定各種初始值 
    BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
    {
    HBITMAP bmp;
    hInst = hInstance;
    hWnd = CreateWindow("canvas", "淺墨的繪圖窗口" , WS_OVERLAPPEDWINDOW,
    CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);
    if (!hWnd)
    {
    return FALSE;
    }
    MoveWindow(hWnd,10,10,640,510,true);
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    hdc = GetDC(hWnd);
    mdc = CreateCompatibleDC(hdc);
    bufdc = CreateCompatibleDC(hdc);
    bmp = CreateCompatibleBitmap(hdc,640,510);
    SelectObject(mdc,bmp);
    bg = (HBITMAP)LoadImage(NULL,"bg.bmp",IMAGE_BITMAP,640,510,LR_LOADFROMFILE);
    sheep = (HBITMAP)LoadImage(NULL,"sheep.bmp",IMAGE_BITMAP,133,220,LR_LOADFROMFILE);
    girl = (HBITMAP)LoadImage(NULL,"girl.bmp",IMAGE_BITMAP,480,148,LR_LOADFROMFILE);
    skill = (HBITMAP)LoadImage(NULL,"skill.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);
    skillult = (HBITMAP)LoadImage(NULL,"skillult.bmp",IMAGE_BITMAP,50,50,LR_LOADFROMFILE);
    slash = (HBITMAP)LoadImage(NULL,"slash.bmp",IMAGE_BITMAP,196,162,LR_LOADFROMFILE);
    magic = (HBITMAP)LoadImage(NULL,"magic.bmp",IMAGE_BITMAP,200,100,LR_LOADFROMFILE);
    recover = (HBITMAP)LoadImage(NULL,"recover.bmp",IMAGE_BITMAP,300,150,LR_LOADFROMFILE);
    game = (HBITMAP)LoadImage(NULL,"over.bmp",IMAGE_BITMAP,289,74,LR_LOADFROMFILE);
    player.nHp = player.fHp = 50;	//設(shè)定玩家角色聲明值及上限
    player.lv = 2;	 //設(shè)定玩家角色等級
    player.w  = 4;	 //設(shè)定攻擊傷害加權(quán)值
    monster.nHp = monster.fHp = 120;	//設(shè)定怪物角色生命值及上限
    monster.lv = 1;	 //設(shè)定怪物角色等級
    monster.w = 1;	 //設(shè)定攻擊傷害加權(quán)值
    txtNum = 0;	 //顯示消息數(shù)目
    SetBkMode(mdc, TRANSPARENT);    //設(shè)置TextOut背景透明
    MyPaint(hdc);
    return TRUE;
    }
    //****自定義繪圖函數(shù)*********************************
    // 1.畫面貼圖與對戰(zhàn)消息顯示
    // 2.怪物行為判斷及各項數(shù)據(jù)處理與計算
    void MyPaint(HDC hdc)
    {
    char str[100];
    int i,damage;
    //貼上背景圖
    SelectObject(bufdc,bg);
    BitBlt(mdc,0,0,640,510,bufdc,0,0,SRCCOPY);
    //顯示對戰(zhàn)消息
    for(i=0;i<txtNum;i++)
    TextOut(mdc,0,360+i*18,text[i],strlen(text[i]));
    //貼上怪物圖
    if(monster.nHp>0)
    {
    SelectObject(bufdc,sheep);
    BitBlt(mdc,70,180,133,110,bufdc,0,110,SRCAND);
    BitBlt(mdc,70,180,133,110,bufdc,0,0,SRCPAINT);
    sprintf(str,"%d / %d",monster.nHp,monster.fHp);
    TextOut(mdc,100,320,str,strlen(str));
    }
    //貼上玩家圖
    if(player.nHp>0)
    {
    SelectObject(bufdc,girl);
    BitBlt(mdc,500,200,60,74,bufdc,pNum*60,74,SRCAND);
    BitBlt(mdc,500,200,60,74,bufdc,pNum*60,0,SRCPAINT);
    sprintf(str,"%d / %d",player.nHp,player.fHp);
    TextOut(mdc,510,320,str,strlen(str));
    }
    if(over)	 //貼上游戲結(jié)束圖畫
    {
    SelectObject(bufdc,game);
    BitBlt(mdc,200,200,289,37,bufdc,0,37,SRCAND);
    BitBlt(mdc,200,200,289,37,bufdc,0,0,SRCPAINT);
    }
    else if(!attack)	 //貼上攻擊命令圖畫
    {
    SelectObject(bufdc,skill);
    BitBlt(mdc,500,350,50,50,bufdc,0,0,SRCCOPY);
    SelectObject(bufdc,skillult);
    BitBlt(mdc,430,350,50,50,bufdc,0,0,SRCCOPY);
    //BitBlt(mdc,500,350,74,30,bufdc,0,30,SRCAND);
    //BitBlt(mdc,500,350,74,30,bufdc,0,0,SRCPAINT);
    }
    else
    {
    f++;
    //第5~10個畫面時顯示玩家攻擊圖標(biāo)
    if(f>=5 && f<=10)
    {
    SelectObject(bufdc,slash);
    BitBlt(mdc,100,160,98,162,bufdc,98,0,SRCAND);
    BitBlt(mdc,100,160,98,162,bufdc,0,0,SRCPAINT);
    //第10個畫面時計算怪物受傷害程度并加入顯示消息
    if(f == 10)
    {
    if (4==rand()%5)                   // 20%幾率觸發(fā)幻影刺客的大招,恩賜解脫,4倍暴擊傷害
    {
    damage = 4*(rand()%10 + player.lv*player.w);
    monster.nHp -= (int)damage;
    sprintf(str,"恩賜解脫觸發(fā),這下牛逼了,4倍暴擊...對怪物照成了%d點傷害",damage);
    } 
    else
    {
    damage = rand()%10 + player.lv*player.w;
    monster.nHp -= (int)damage;
    sprintf(str,"玩家使用了無敵斬,傷害一般般...對怪物照成了%d點傷害",damage);
    }
    MsgInsert(str);
    CheckDie(monster.nHp,false);
    }
    }
    srand(tPre);
    //第15個畫面時判斷怪物進行哪項動作
    if(f == 15)
    {
    if(monster.nHp > 20)	 //生命值大于20
    {
    if(rand()%5 != 1)          //進行利爪攻擊概率4/5
    monster.kind = 0;
    else                       //進行閃電鏈攻擊概率1/5
    monster.kind = 1;    
    }
    else	 //生命值小于20
    {
    switch(rand()%5)
    {
    case 0:	 //利爪攻擊
    monster.kind = 0;
    break;
    case 1:	 //釋放閃電鏈
    monster.kind = 1;
    break;
    case 2:	 //致命一擊
    monster.kind = 2;
    break;
    case 3:	 //使用梅肯斯姆回復(fù)
    monster.kind = 3;
    break;
    case 4:	 //逃跑
    monster.kind = 4;
    break;
    }
    }
    }
    //第26~30個畫面時顯示玩家攻擊圖標(biāo)
    if(f>=26  && f<=30)
    {
    switch(monster.kind)
    {
    case 0:	 //利爪攻擊
    SelectObject(bufdc,slash);
    BitBlt(mdc,480,150,98,162,bufdc,98,0,SRCAND);
    BitBlt(mdc,480,150,98,162,bufdc,0,0,SRCPAINT);
    //第30個畫面時計算玩家受傷害程度并加入顯示消息
    if(f == 30)
    {
    damage = rand()%10 + monster.lv*monster.w;
    player.nHp -= (int)damage;
    sprintf(str,"怪物利爪攻擊...對玩家照成 %d 點傷害",damage);
    MsgInsert(str);
    CheckDie(player.nHp,true);
    }
    break;
    case 1:	 //釋放閃電鏈
    SelectObject(bufdc,magic);
    BitBlt(mdc,480,190,100,100,bufdc,100,0,SRCAND);
    BitBlt(mdc,480,190,100,100,bufdc,0,0,SRCPAINT);
    //第30個畫面時計算玩家受傷害程度并加入顯示消息
    if(f == 30)
    {
    damage = rand()%10 + 3*monster.w;
    player.nHp -= (int)damage;
    sprintf(str,"怪物釋放閃電鏈...對玩家照成 %d 點傷害",damage);
    MsgInsert(str);
    CheckDie(player.nHp,true);
    }
    break;
    case 2:	 //致命一擊
    SelectObject(bufdc,slash);
    BitBlt(mdc,480,150,98,162,bufdc,98,0,SRCAND);
    BitBlt(mdc,480,150,98,162,bufdc,0,0,SRCPAINT);
    //第30個畫面時計算玩家受傷害程度并加入顯示消息
    if(f == 30)
    {
    damage = rand()%10 + monster.lv*monster.w*5;
    player.nHp -= (int)damage;
    sprintf(str,"怪物致命一擊...對玩家照成 %d 點傷害.",damage);
    MsgInsert(str);
    CheckDie(player.nHp,true);
    }
    break;
    case 3:	 //使用梅肯斯姆補血
    SelectObject(bufdc,recover);
    BitBlt(mdc,60,160,150,150,bufdc,150,0,SRCAND);
    BitBlt(mdc,60,160,150,150,bufdc,0,0,SRCPAINT);
    //第30個畫面時怪物回復(fù)生命值并加入顯示消息
    if(f == 30)
    {
    monster.nHp += 30;
    sprintf(str,"怪物使用梅肯斯姆...恢復(fù)了30點生命值",damage);
    MsgInsert(str);
    }
    break;
    case 4:
    //在第30個畫面時判斷怪物是否逃跑成功
    if(f == 30)
    {
    if(1== rand()%3 )	//逃跑幾率1/3
    {
    over = true;
    monster.nHp = 0;
    sprintf(str,"怪物逃跑中...逃跑成功");
    MsgInsert(str);
    }
    else
    {
    sprintf(str,"怪物逃跑中...逃跑失敗");
    MsgInsert(str);
    }
    }
    break;
    }
    }
    if(f == 30)	 //回合結(jié)束
    {
    attack = false;
    f = 0;
    }
    }
    BitBlt(hdc,0,0,640,510,mdc,0,0,SRCCOPY);
    tPre = GetTickCount();
    pNum++;
    if(pNum == 8)
    pNum = 0;
    }
    //****新增的對戰(zhàn)消息函數(shù)********************************
    void MsgInsert(char* str)
    {
    if(txtNum < 5)
    {
    sprintf(text[txtNum],str);
    txtNum++;
    }
    else
    {
    for(int i=0;i<txtNum;i++)
    sprintf(text[i],text[i+1]);
    sprintf(text[4],str);
    }
    }
    //****生命值判斷函數(shù)*************************
    void CheckDie(int hp,bool player)
    {
    char str[100];
    if(hp <= 0)
    {
    over = true;
    if(player)
    {
    sprintf(str,"勝敗乃兵家常事,大俠請重新來過......");
    MsgInsert(str);
    }
    else
    {
    sprintf(str,"少年,你贏了,有兩下子啊~~~~~!!!!");
    MsgInsert(str);
    }
    }
    }
    //****消息處理函數(shù)***********************************
    // 
    LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
    int x,y;
    switch (message)
    {
    case WM_KEYDOWN:	 //鍵盤消息
    if(wParam==VK_ESCAPE)	 //按下Esc鍵
    PostQuitMessage(0);
    break;
    case WM_LBUTTONDOWN:	 //鼠標(biāo)左鍵消息
    if(!attack)
    {
    x = LOWORD(lParam);	 //X坐標(biāo)
    y = HIWORD(lParam);	 //Y坐標(biāo)
    if(x >= 500 && x <= 550 && y >= 350 && y <= 400)
    attack = true;
    }
    break;
    case WM_DESTROY:	 //窗口結(jié)束消息
    DeleteDC(mdc);
    DeleteDC(bufdc);
    DeleteObject(bg);
    DeleteObject(sheep);
    DeleteObject(girl);
    DeleteObject(skill);
    DeleteObject(skillult);
    DeleteObject(slash);
    DeleteObject(magic);
    DeleteObject(recover);
    DeleteObject(game);
    ReleaseDC(hWnd,hdc);
    PostQuitMessage(0);
    break;
    default:	 //默認消息
    return DefWindowProc(hWnd, message, wParam, lParam);
       }
       return 0;
    }


    每一回合開始的時候,我們點擊畫面上“無敵斬”的技能圖標(biāo),就可以進行攻擊,對怪物造成傷害,人品好的話,還可以觸發(fā)強力被動技能“恩賜解脫”,對怪物造成4倍暴擊傷害,這里我們設(shè)定的暴擊概率為20%



    淺墨在截圖的時候,人品挺好的,恩賜解脫的暴擊概率為20%,但是淺墨的4次攻擊里,有3次都打出了“恩賜解脫”的暴擊效果,直接果斷地把這只小綿羊帶走了,呵呵。


    下面就是游戲運行的截圖:


    游戲開始



    第一刀就出暴擊了,48點傷害



    運氣不錯,又一刀暴擊,68點傷害



    最后一刀又出了暴擊,小綿羊被“秒殺”,游戲結(jié)束




    我們還可以調(diào)節(jié)怪物等級,怪物攻擊加權(quán)值,怪物血量上限以及玩家角色等級,玩家角色攻擊加權(quán)值,玩家角色血量上限來讓游戲更具挑戰(zhàn)性。


    當(dāng)然,我們也可以增加更多的代碼,來使怪物的思考與行動方式更具真實性和多樣性,來使玩家的技能更加豐富。



    這個回合制游戲demo可以說是目前市場上回合制游戲的本體,《仙劍奇?zhèn)b傳》(三代以前的,三代及以后的仙劍都是進度條模式了),《夢幻西游》《問道》等經(jīng)典的回合制游戲,無非就是在這種風(fēng)格的demo基礎(chǔ)上,寫更多的代碼,豐富內(nèi)容而已,或為游戲引擎的核心代碼。


    最后淺墨再提一點,以結(jié)束這篇筆記,其實就是為了給大家提供一些實現(xiàn)思路:


    可以在這個demo的基礎(chǔ)上,增加劇情,世界觀,游戲地圖,等級系統(tǒng),經(jīng)驗值系統(tǒng),寵物系統(tǒng),道具系統(tǒng),符文系統(tǒng),五行相克系

    統(tǒng),天氣系統(tǒng)等,讓這個回合制游戲更加有趣更加吸引人。

    而這些系統(tǒng),我在以后的筆記里面會盡量全部涵蓋進行講解的,希望大家繼續(xù)關(guān)注我的博客。




    本節(jié)筆記到這里就結(jié)束了。


    本節(jié)筆記的源代碼請點擊這里下載:  【Visual C++】Note_Code_16



    感謝一直支持【Visual C++】游戲開發(fā)筆記系列專欄的朋友們,也請大家繼續(xù)關(guān)注我的專欄,我一有時間就會把自己的學(xué)習(xí)心得,覺得比較好的知識點寫出來和大家一起分享。

    精通游戲開發(fā)的路還很長很長,非常希望能和大家一起交流,共同學(xué)習(xí),共同進步。

    大家看過后覺得值得一看的話,可以頂一下這篇文章,你們的支持是我繼續(xù)寫下去的動力~

    如果文章中有什么疏漏的地方,也請大家指正。也希望大家可以多留言來和我探討編程相關(guān)的問題。

    最后,謝謝你們一直的支持~~~


    ——————————淺墨于2012年4月10日

    作者:zhmxy555 發(fā)表于2012-4-11 3:10:45 原文鏈接
    閱讀:7242 評論:96 查看評論

    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 999在线视频精品免费播放观看| 一个人免费高清在线观看| 亚洲人成网站在线播放影院在线 | 中文字幕免费播放| 亚洲综合激情九月婷婷 | 亚洲av午夜成人片精品电影| 成全视成人免费观看在线看| 亚洲白色白色在线播放| 国产大片免费观看中文字幕| 国内精品免费在线观看| 亚洲精品第一国产综合亚AV| 亚洲色欲久久久综合网东京热| 国产一卡二卡四卡免费| 三级片免费观看久久| 亚洲无成人网77777| 亚洲福利视频一区二区| 每天更新的免费av片在线观看 | 97在线观免费视频观看| 中文字幕在线免费看| 中文字幕无码亚洲欧洲日韩| 亚洲AV无码乱码在线观看富二代 | www视频免费看| 国产VA免费精品高清在线| youjizz亚洲| 亚洲VA中文字幕无码毛片| 国产无遮挡吃胸膜奶免费看视频| 久久免费国产精品一区二区| 无码色偷偷亚洲国内自拍| 亚洲一区中文字幕在线观看| 亚洲人成中文字幕在线观看 | 久久久无码精品亚洲日韩按摩| 国产免费无遮挡精品视频| 一级女人18毛片免费| 久久久久国色av免费看| 一级毛片在线免费视频| 亚洲AV女人18毛片水真多| ass亚洲**毛茸茸pics| 亚洲人成电影在线天堂| 亚洲AV永久精品爱情岛论坛| 亚洲精品亚洲人成在线观看下载 | 中文字幕在线免费看线人|