青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

天行健 君子當(dāng)自強(qiáng)而不息

【ZT】DirectInput里的鍵盤(pán)鼠標(biāo)的應(yīng)用

設(shè)計(jì)一個(gè)PC游戲,鍵盤(pán)鼠標(biāo)的輸入是絕不能少。Windows也提供了諸如 WM_LBUTTONDOWN、WM_RBUTTONUP等鼠標(biāo)消息以及WM_KEYDOWN、WM_KEYUP等鍵盤(pán)輸入消息。但是 DirectInput中仍然提供了對(duì)鼠標(biāo)鍵盤(pán)的支持,其原因就是DirectInput提供一個(gè)更直接更快捷的對(duì)輸入設(shè)備的訪問(wèn)方法。就象我們?cè)贒OS 下直接接管鍵盤(pán)中斷,而不是去用什么討厭的INT16來(lái)處理鍵盤(pán)輸入一樣(用INT16來(lái)處理鍵盤(pán)輸入其弊端在《金庸群俠傳》中顯得尤為明顯,人物在走路 之前總要頓那么一下,就是這一下讓我覺(jué)得非常之不爽!其原因我想我也不用羅嗦了)。

  當(dāng)然Windows的鍵盤(pán)消息比之INT16當(dāng)然有了長(zhǎng)足的進(jìn)步(因?yàn)樗峁┝艘? 個(gè)WM_KEYUP消息),但是在某些方面仍顯不足。因?yàn)閃indows的消息機(jī)制是一個(gè)緩沖(buffer)機(jī)制,未被處理的鍵盤(pán)鼠標(biāo)消息都放在緩沖區(qū) 里等待下一次處理,這樣對(duì)于一些應(yīng)用軟件是非常重要的,但是對(duì)游戲來(lái)說(shuō)(特別是一些動(dòng)作游戲,包括體育游戲)就顯得有蛇足之嫌了。舉個(gè)例子,在足球游戲 里,你去搶截對(duì)手的球——搶球和射門、鏟斷和長(zhǎng)傳(大腳)總是設(shè)成同一個(gè)鍵,這好像是個(gè)公認(rèn)的標(biāo)準(zhǔn)了——但這時(shí)剛好對(duì)手的球脫腳了,球直接就到了你的腳 下,這時(shí)你本來(lái)想帶球繞過(guò)他的,可是你的搶球鍵已經(jīng)按過(guò)了,由于這個(gè)該死的緩沖機(jī)制,先要處理一下這個(gè)搶球鍵(也就是射門鍵),于是你的動(dòng)作就變成了一次 盲目的后場(chǎng)遠(yuǎn)射(等同于大腳解圍)了。控制不了自己的動(dòng)作,做球員做到這個(gè)份兒上真是夠失敗的了。這里就是緩沖機(jī)制不適用的地方了。

  而DirectInput提供了緩沖和立即兩種訪問(wèn)輸入設(shè)備的方式,對(duì)于立即方 式,正好就是解決上面弊病的方法。DirectInput里關(guān)于鍵盤(pán)的初始化部分,已經(jīng)在很早以前的一篇文章里給出來(lái)了。雖是針對(duì)于DirectX7的, 但關(guān)于DirectInput部分在DX8和DX7里差別不大,把LPDIRECTINPUT7換成LPDIRECTINPUT8、 LPDIRECTINPUTDEVICE7換成LPDIRECTINPUTDEVICE8就OK了,此外還有一點(diǎn)點(diǎn)需要改動(dòng)的就是DirectInput 對(duì)象的創(chuàng)建,DX8里用的是下面這個(gè)函數(shù):

DirectInput8Create(hInst, DIRECTINPUT_VERSION, IID_IDirectInput8,(LPVOID *)&lpDI, NULL);

  里面具體的參數(shù)大家看也看得出來(lái),我就不多說(shuō)了。

  下面說(shuō)一下鼠標(biāo),鼠標(biāo)的緩沖機(jī)制還是滿重要的,鼠標(biāo)的移動(dòng)就建立在滾動(dòng)計(jì)數(shù)累積的 基礎(chǔ)上的。鼠標(biāo)是每隔8ms采樣一次(反正USB鼠標(biāo)是這樣,我估計(jì)一般鼠標(biāo)也是一樣),要是只獲取當(dāng)前狀態(tài)的話,那這個(gè)鼠標(biāo)移動(dòng)起來(lái)就太慢了(應(yīng)該不會(huì) 有人在應(yīng)用程序里每隔8ms就調(diào)用一次鼠標(biāo)的狀態(tài)獲取函數(shù)吧)。之所以采用DirectInput,不是因?yàn)榫彌_這個(gè)原因,而是因?yàn)橐粋€(gè)我個(gè)人的喜好因 素。一般的游戲在卷屏?xí)r是判斷鼠標(biāo)的位置是否在屏幕邊緣,如果是就向這一方向卷屏。我個(gè)人不是很喜歡這種做法,可能因?yàn)槲沂直容^笨,玩游戲是經(jīng)常莫名其妙 地畫(huà)面就移走了,這讓我覺(jué)得很成問(wèn)題,為什么光標(biāo)指到屏幕邊上就要卷屏?所以我希望鼠標(biāo)的移動(dòng)才是卷屏的依據(jù),這在Windows的消息機(jī)制里就做不到 了。因?yàn)樵赪indows的消息機(jī)制里,當(dāng)鼠標(biāo)一到屏幕邊上時(shí)再向外移動(dòng),應(yīng)用程序是收不到WM_MOUSEMOVE消息的。但在DirectInput 里就可以由我自己來(lái)實(shí)現(xiàn),DirectInput接收到的只是鼠標(biāo)的滾動(dòng)計(jì)數(shù),它可沒(méi)有什么光標(biāo)位置的限制。

  下面就給出DirectInput鼠標(biāo)對(duì)象的初始化代碼,只能這么一步步的來(lái),沒(méi)什么好說(shuō)的。


//=================================
LPDIRECTINPUT8  pDI;
LPDIRECTINPUTDEVICE8  lpMouse;

// 存放鼠標(biāo)光標(biāo)的Surface
LPDIRECT3DSURFACE8  lpDSCursor;
HANDLE  hMouseEvent;

//是有符號(hào)型,所以可以判斷光標(biāo)是否移出屏幕來(lái)決定是否卷屏
short  MouseX = FULLSCREEN_WIDTH/2,MouseY =FULLSCREEN_HEIGHT/2;

bool InitInput()
{
    HRESULT   hres;
    hres 
= DirectInput8Create(hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (LPVOID *)&lpDI, NULL);
    
if(FAILED(hres))
        
return FALSE;

    hres 
= lpDI->CreateDevice(GUID_SysMouse, &lpMouse,NULL);
    
if(FAILED(hres))
        
return FALSE;

    hres 
= lpMouse->SetDataFormat(&c_dfDIMouse);
    
if(FAILED(hres))
        
return FALSE;

    hres 
= lpMouse->SetCooperativeLevel(hMainWnd,DISCL_EXCLUSIVE | DISCL_FOREGROUND);
    
if(FAILED(hres))
        
return FALSE;

    hMouseEvent 
= CreateEvent(NULL, FALSE, FALSE, NULL);
    
if(!hMouseEvent)
        
return FALSE;

    hres 
= lpMouse->SetEventNotification(hMouseEvent);
    
if(FAILED(hres))
        
return FALSE;

    DIPROPDWORD dipdw;
    dipdw.diph.dwSize 
= sizeof(DIPROPDWORD);
    dipdw.diph.dwHeaderSize 
= sizeof(DIPROPHEADER);
    dipdw.diph.dwObj 
= 0;
    dipdw.diph.dwHow 
= DIPH_DEVICE;
    dipdw.dwData 
= MOUSE_SAMPLEBUFFER;  // 預(yù)定義為16
    hres = lpMouse->SetProperty(DIPROP_BUFFERSIZE,&dipdw.diph);
    
if(FAILED(hres))
        
return FALSE;

    lpMouse
->Acquire();

    
return TRUE;
}


現(xiàn)在是我們完全接管了鼠標(biāo),那么無(wú)可非議的,鼠標(biāo)光標(biāo)的顯示任務(wù)也落到了我們頭上,不過(guò)在D3D8入門里我提到了,光標(biāo)的顯示可以由D3D8支持。下面我們就來(lái)創(chuàng)建一個(gè)光標(biāo):

D3DLOCKED_RECT  dlr;
//光標(biāo)的Surface只能是A8R8G8B8格式的,占了一個(gè)alpha字節(jié)又不支持半透明,真是shit 

hres 
= lpDevice->CreateImageSurface(3232, D3DFMT_A8R8G8B8,&lpDSCursor);
if(FAILED(hres))
    
return FALSE;

hres 
= lpDSCursor->LockRect(&dlr, NULL, 0);
if(FAILED(hres))
    
return FALSE;

// 往Surface里寫(xiě)數(shù)據(jù)呀,不用我說(shuō)了吧
………………
hres 
= lpDSCursor->UnlockRect();
hres 
= lpDevice->SetCursorProperties(00, lpDSCursor);
if(FAILED(hres))
    
return FALSE;

lpDevice
->ShowCursor(TRUE);

接下來(lái)就是鼠標(biāo)數(shù)據(jù)的存取了,這里我只處理了鼠標(biāo)的移動(dòng)。

void MouseEvent()
{
    DIDEVICEOBJECTDATA od;
    HRESULT  hres;
    DWORD   count;
    
short   x = 0, y = 0;
    
while(1)
    {
        count 
= 1;
        hres 
=lpMouse->GetDeviceData(sizeof(DIDEVICEOBJECTDATA), &od,&count, 0);
        
if(hres == DIERR_INPUTLOST)
        {
            lpMouse
->Acquire();
            
return;
        }

        
if(FAILED(hres) || !count)
            
break;

        
switch(od.dwOfs)
        {
        
case DIMOFS_X:
            x 
+= (short)od.dwData;
            
break;
        
case DIMOFS_Y:
            y 
+= (short)od.dwData;
            
break;
        
//物理設(shè)備上左鍵或右鍵按下/釋放,如有左右鍵交換可是要自己判斷的
        case DIMOFS_BUTTON0:
        
case DIMOFS_BUTTON1:
            
if(od.dwData & 0x80)
            
// 鍵按下
            …………
        
else
            
// 鍵釋放
            …………    
        }
    }

    
if(x || y)
    {
        MouseX 
+= x;
        MouseY 
+= y;
        
// 決定光標(biāo)的位置以及是否卷屏等等
        …………
        lpDevice
->SetCursorPosition(MouseX, MouseY,D3DCURSOR_IMMEDIATE_UPDATE);
    }
}

  好了,現(xiàn)在算是完了。但是我個(gè)人覺(jué)得有一點(diǎn)小小的缺憾,大家如果試一下就會(huì)發(fā)現(xiàn),鼠標(biāo)移動(dòng)的總比Windows下慢一些,這是為什么?我在Windows的鼠標(biāo)設(shè)置里看到一個(gè)加速選項(xiàng),覺(jué)得可能是由于這個(gè)原因。那就模擬一下了。(以下只列出上面函數(shù)的改動(dòng)部分)

short  xaccel,yaccel;
xaccel 
= yaccel = 1;

while(1)
{
    …………
    
switch(od.dwOfs)
    {
    
case DIMOFS_X:
        x 
+= (short)od.dwData*xaccel;
        xaccel
++;
        
break;
    
case DIMOFS_Y:
        y 
+= (short)od.dwData*yaccel;
        yaccel
++;
        
break;
        …………
    }
    ………
}

      經(jīng)過(guò)這樣改動(dòng)后,鼠標(biāo)再移動(dòng)起來(lái)果然順暢了很多。

  此外,DIDEVICEOBJECTDATA結(jié)構(gòu)中還有一個(gè)時(shí)間標(biāo)記,用這個(gè)可以 判斷鼠標(biāo)的雙擊,現(xiàn)在我們的鼠標(biāo)模擬已經(jīng)初具雛形。自己接管鼠標(biāo)后,就可以定義方便自己的消息比如什么拖動(dòng)啦(在Windows下判斷拖動(dòng)就是煩,自己定 義一個(gè))、三擊啦什么的,好處是不言而喻的,當(dāng)然也帶來(lái)了壞處——就是編寫(xiě)的代碼就多了,不過(guò)這就是游戲程序員的職責(zé)呀。

posted on 2007-05-06 17:17 lovedday 閱讀(649) 評(píng)論(0)  編輯 收藏 引用 所屬分類: ■ DirectX 9 Program

公告

導(dǎo)航

統(tǒng)計(jì)

常用鏈接

隨筆分類(178)

3D游戲編程相關(guān)鏈接

搜索

最新評(píng)論

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美大片第1页| 永久免费毛片在线播放不卡| 在线亚洲美日韩| 午夜精品视频在线观看| 国产一区二区日韩| 久热精品视频在线免费观看 | 亚洲一区二区三区四区在线观看 | 国产精品99久久久久久久久 | 免费观看一区| 99视频热这里只有精品免费| 国产精品va在线播放| 午夜免费电影一区在线观看| 欧美激情成人在线视频| 亚洲欧美日韩成人| 一区二区三区在线观看欧美| 欧美激情精品久久久久| 亚洲欧美在线一区| 亚洲国产国产亚洲一二三| 亚洲一区二区久久| 在线观看视频一区二区| 欧美日韩成人在线播放| 久久精品一级爱片| 日韩西西人体444www| 久久亚洲私人国产精品va| 夜色激情一区二区| 一区在线播放视频| 国产精品国产三级国产专区53| 欧美中文字幕视频在线观看| 亚洲精品午夜精品| 欧美va天堂| 欧美一区二区日韩一区二区| 日韩网站在线| 亚洲成人在线视频网站| 国产麻豆日韩| 欧美涩涩网站| 欧美激情自拍| 久久这里有精品15一区二区三区| 亚洲网址在线| 亚洲精品免费在线播放| 久久综合网hezyo| 午夜欧美不卡精品aaaaa| 日韩一级在线观看| 亚洲黄色大片| 精品1区2区3区4区| 国产亚洲欧美日韩美女| 国产精品青草久久久久福利99| 免费久久精品视频| 久久久久久久91| 欧美一区二区视频在线| 亚洲无线一线二线三线区别av| 亚洲欧洲一区二区三区| 欧美高清视频在线播放| 国产精品成人va在线观看| 蜜月aⅴ免费一区二区三区| 久久av一区二区三区漫画| 亚洲综合久久久久| 亚洲一级黄色| 亚洲一区二区在| 一区二区日韩| 一区二区精品| 亚洲天堂免费观看| 亚洲性图久久| 亚洲一级特黄| 亚洲欧美日韩国产| 亚洲欧美日韩精品在线| 亚洲欧美日韩在线一区| 亚洲女优在线| 欧美一区二粉嫩精品国产一线天| 亚洲中无吗在线| 欧美一级午夜免费电影| 欧美在线你懂的| 久久精品一区四区| 猛男gaygay欧美视频| 欧美xx视频| 欧美日韩国产一区| 国产精品乱码久久久久久| 国产精品毛片a∨一区二区三区| 国产精品乱码| 国产丝袜美腿一区二区三区| 国产亚洲毛片在线| 在线看片成人| 一区二区欧美精品| 亚洲综合色噜噜狠狠| 欧美一区91| 麻豆精品视频在线| 亚洲电影专区| 夜夜爽av福利精品导航| 亚洲欧美成人一区二区三区| 欧美在线播放| 欧美777四色影视在线| 欧美精品一区二区三区一线天视频| 欧美精品一区二区三区高清aⅴ| 欧美日韩三区| 国产午夜精品美女视频明星a级| 伊甸园精品99久久久久久| 亚洲人午夜精品免费| 亚洲永久精品大片| 久久一区视频| 亚洲精品欧洲| 欧美在线国产| 欧美区在线观看| 国产无一区二区| 亚洲精品婷婷| 欧美中文字幕精品| 亚洲成人资源| 亚洲专区一二三| 欧美波霸影院| 国产性猛交xxxx免费看久久| 亚洲精品久久久久中文字幕欢迎你 | 欧美欧美在线| 国产亚洲免费的视频看| 91久久精品日日躁夜夜躁欧美 | 欧美有码在线观看视频| 欧美精品国产精品| 国产午夜精品在线| 99热精品在线观看| 久久精品国产精品 | 在线视频亚洲欧美| 久久午夜电影网| 99这里只有精品| 久久夜色精品国产欧美乱极品| 欧美四级在线| 亚洲国产精品第一区二区三区| 亚洲欧美国产77777| 欧美国产在线电影| 欧美一区二区在线免费观看 | 欧美亚洲视频一区二区| 亚洲欧洲日本在线| 久久免费精品视频| 国产精品尤物| 亚洲一区二区精品在线| 亚洲国产黄色| 久久天天狠狠| 国产在线不卡视频| 香蕉亚洲视频| 一区二区av在线| 欧美精品一区二区三区蜜臀| 亚洲成人在线视频播放| 欧美在线观看视频在线 | 欧美一区二区三区另类| 欧美特黄a级高清免费大片a级| 亚洲人午夜精品免费| 久久综合网络一区二区| 午夜在线精品偷拍| 国产精品久久网| 亚洲综合国产| 一本久道久久久| 欧美日韩一区不卡| 一区二区三区精品久久久| 亚洲国产日韩欧美在线图片| 久久久久一区| 伊人久久亚洲美女图片| 久久精品一区二区| 欧美在线一级视频| 激情综合电影网| 乱人伦精品视频在线观看| 久久精品国产亚洲一区二区三区| 国产农村妇女精品一区二区| 亚洲欧美激情四射在线日| 一二三区精品福利视频| 欧美偷拍一区二区| 亚洲综合成人在线| 亚洲一区二区动漫| 国产欧美精品在线| 久久九九热免费视频| 久久国产主播| 亚洲国产一区二区三区在线播| 欧美高清视频| 欧美区亚洲区| 午夜久久电影网| 久久精品视频播放| 亚洲人成久久| 一本色道久久综合亚洲精品不| 国产精品久久久久免费a∨大胸| 午夜日韩av| 久久久夜精品| 一级日韩一区在线观看| 一级日韩一区在线观看| 国产美女高潮久久白浆| 久久综合久色欧美综合狠狠| 久久人人爽人人爽| 日韩亚洲欧美中文三级| 亚洲一区二区三区视频播放| 国产一区二区久久精品| 欧美电影免费观看大全| 欧美日韩精品在线| 久久精品国产欧美激情| 久久午夜激情| 一区二区三区四区国产| 欧美一级免费视频| 亚洲激情社区| 亚洲一区二区日本| 亚洲国产精品一区二区第一页 | 欧美xxxx在线观看| 亚洲直播在线一区| 久久露脸国产精品| 亚洲宅男天堂在线观看无病毒| 欧美一区二区三区四区在线观看地址 | 亚洲欧美日韩在线高清直播| 久久成年人视频|