日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【Direct3D游戏开发】——DirectInput 让世界动起来

發(fā)布時間:2023/12/10 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【Direct3D游戏开发】——DirectInput 让世界动起来 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

?其實我們是可以通過Windows消息和API取得鍵盤或者鼠標或者其他設備的輸入信息,但這有個等待windows消息傳送的延時,筆者試過直接在消息回調函數(shù)中相應鍵盤的上下左右消息去使場景中的模型進行旋轉,感覺有明顯的延時。這對于游戲玩家來說簡直是噩夢,就好像我在玩lol,舍友都在用迅雷下AV一樣的信息。而DirectX是直接與硬件進行交流,不需要去等待windows傳送消息。DirectInput可以直接獲得硬件的消息,立即響應。

??要用DirectInput獲得一個硬件設備的信息和初始化Direct3D一樣要經(jīng)過幾個步驟:

????????1.創(chuàng)建DirectInput對象

????????2.創(chuàng)建設備對象

????????3.設定設備數(shù)據(jù)格式

????????4.設定程序協(xié)調層級

????????5.獲得設備

????????6.取得設備狀態(tài)

??前面4步是初始化設備。

??1.創(chuàng)建DirectInput對象

????????

//DirectInput8對象
?? ?LPDIRECTINPUT8 pInputSystem;
//-1、創(chuàng)建DirectInput8對象
?? ?hr = DirectInput8Create( hInst, DIRECTINPUT_VERSION, IID_IDirectInput8,?
?? ??? ??? ??? ??? ??? ??? ?(VOID**)&pInputSystem, NULL );
?? ?if( FAILED( hr ) )
?? ?{
?? ??? ?MessageBox( NULL, L"DirectInput8Create()-FAILED!", NULL, MB_OK );
?? ??? ?return false;
?? ?}
?????首先聲明一個DirectInput對象指針,然后調用DirectInput8Create()方法創(chuàng)建DirectInput對象,最后判斷是否創(chuàng)建成功。具體參數(shù)含義可以查閱MSDN.
??2.創(chuàng)建設備對象?

?????

//鍵盤設備
?? ?LPDIRECTINPUTDEVICE8 pKeyboardDevice;
//-2、創(chuàng)建鍵盤DirectInput8Device
?? ?hr = pInputSystem->CreateDevice( GUID_SysKeyboard, &pKeyboardDevice, NULL );
?? ?if( FAILED(hr) )
?? ?{
?? ??? ?MessageBox( NULL, L"pInputSystem->CreateDevice()-FAILED!", NULL, MB_OK );
?? ??? ?return false;
?? ?}
???首先聲明一個設備指針,然后調用DirectInput對象的成員函數(shù)CreateDevice()創(chuàng)建設備,這個創(chuàng)建的是鍵盤設備,具體由CreateDevice()的第一個參數(shù)決定,對于鼠標應為:GUID_SysMouse.


??3.設定設備數(shù)據(jù)格式


?? ?//-3、設置鍵盤的數(shù)據(jù)格式
?? ?hr = pKeyboardDevice->SetDataFormat( &c_dfDIKeyboard );
?? ?if( FAILED( hr ) )
?? ?{
?? ??? ?MessageBox( NULL, L"pKeyboardDevice->SetDataFormat()-FAILED!", NULL, MB_OK );
?? ??? ?return false;
?? ?}

??由DirectInputDevice設備的SetDataFormat()成員函數(shù)完成,參數(shù)只有一個是一個關于數(shù)據(jù)格式的常量,對于鼠標有兩種數(shù)據(jù)格式:c_dfDIMouse 、c_dfDIMouse2 用哪一個取決于先前聲明的鼠標設備類型,但要保持前后一致。


??4.設定程序協(xié)同層級


//-4、設置設備合作等級
?? ?hr = pKeyboardDevice->SetCooperativeLevel( _hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE );
?? ?if( FAILED(hr) )
?? ?{
?? ??? ?MessageBox( NULL, L"pKeyboardDevice->SetCooperativeLevel()-FAILED!", NULL, MB_OK );
?? ??? ?return false;
?? ?}

???所謂的協(xié)同層級就是手你的程序如何和其他程序共同使用此設備。相關參數(shù):
???DISL_BACKGROUND 程序當前非活躍,取得設備信息

???DISL_EXCLUSIVE 獨占模式,其他程序無法使用程序所建立與使用的輸入裝置,設置前應先檢查當前設備的協(xié)同等級

???DISL_FORCGROUND 程序只有在活躍時,才取得設備信息

???DISL_NONEXCLUSIVE非獨占模型,與其他程序共享設備

???DISL_NOWINKEY 無法使用Windows鍵,防止使用者按下中斷鍵導致程序結束

??5.獲取設備

??

//-5、獲取設備
?? ??? ?hr = pKeyboardDevice->Acquire();
?? ??? ?if( FAILED(hr) )
?? ??? ?{
?? ??? ??? ?MessageBox( NULL, L"pMouseDevice->Acquire()-FAILED!", NULL, MB_OK );
?? ??? ??? ?return false;
?? ??? ?}
???十分簡單,調用設備的成員函數(shù)Acquire(), 檢查是否獲取成功。


??6.取得設備狀態(tài)

if( FAILED(pKeyboardDevice->GetDeviceState( sizeof(keysBuffer), (LPVOID)keysBuffer )) )
?? ??? ?{
?? ??? ??? ?if( FAILED( pKeyboardDevice->Acquire() ) )
?? ??? ??? ??? ?return false;
?? ??? ??? ?if( FAILED( pKeyboardDevice->GetDeviceState( sizeof(keysBuffer), (LPVOID)keysBuffer )) )
?? ??? ??? ?{
?? ??? ??? ??? ?MessageBox( NULL, L" pKeyboardDevice->GetDeviceState()-FAILED!", NULL, MB_OK );
?? ??? ??? ??? ?return false;
?? ??? ??? ?}
?? ??? ?}

?也非常簡單,調用設備的GetDeviceState()成員函數(shù),一般在獲取狀態(tài)失敗一次后再請求一次設備,然后獲取設備狀態(tài)。


??經(jīng)過以上步驟就已經(jīng)取得設備的當前狀態(tài),剩下的問題就是如何響應

??一、對于鍵盤消息

???????????

char keyboardState[256];
//方向鍵上按下
if( keyboardState[DIK_UP] & 0x80)
? ? ? ?//響應操作
//方向鍵右按下
if( keyboardState[DIK_RIGHT] & 0x80)
? ? ? ?//響應操作
//方向鍵下按下
if( keyboardState[DIK_DOWN] & 0x80)
? ? ? ?//響應操作
//方向鍵左按下
if( keyboardState[DIK_LEFT] & 0x80)
? ? ? ?//響應操作
??首先定義了一個256大小的數(shù)組作為輸入緩沖區(qū),代表鍵盤上256個鍵的狀態(tài),對于每一個鍵的狀態(tài)是一個8bit的內存,高位代表鍵的狀態(tài)。所以與(0x80)作And運算,如果不為0則代表此鍵被按下,反之未被按下。DIK_UP之類的是Direct的枚舉類型。具體可查閱MSDN.


??二、對于鼠標

??對于鼠標在調用GetDeviceState()時需要在此函數(shù)的第二個參數(shù)傳入一個類型為DIMOUSESTATE或DIMOUSESTATE2的結構體,以下是該結構體的定義


typedef struct DIMOUSESTATE {
? ? LONG lX;
? ? LONG lY;
? ? LONG lZ;
? ? BYTE rgbButtons[4];
} DIMOUSESTATE, *LPDIMOUSESTATE;

兩個結構的的區(qū)別只在于最后一項rgbButtons[]的大小有所不同。當我們要響應鼠標消息時要利用到rgbButtons[]數(shù)組,rgbButtons[0]代表鼠標左鍵的狀態(tài),rgbButtons[1]代表鼠標右鍵的狀態(tài),同樣采用 and (0x80)的方法判斷鍵的狀態(tài)。


??三、對于游戲控制器,手柄呀什么的判斷哪個鍵是否被按下的方法還是一樣只是取得的狀態(tài)保存的結構不一樣,具體這里不想說,可以查閱MSDN.

????????一個封裝后的DirectInput類,支持響應鼠標和鍵盤輸入。

/******************************************************************** * 游戲輸入類 * * file: CLDirectInput.h * * copyright (C) 2013 by CoderLing * * email : coderling@gmail.com * * blog: http://blog.csdn.net/coderling * ********************************************************************/#ifndef CLDIRECTINPUT_H #define CLDIRECTINPUT_H #define DEBUG #define DIM_LEFT 0 #define DIM_RIGHT 1 #define DIRECTINPUT_VERSION 0x0800 #define KEY_SIZE 256 //鍵盤數(shù)據(jù)大小#include <dinput.h>struct POINT3 {int x, y, z;POINT3( int _x, int _y, int _z){x = _x; y = _y; z = _z;} };class CLDirectInput {//---------------------------------------------//-1.處理鍵盤消息//----上下左右,字符消息//-2.處理鼠標消息//----鼠標左右鍵,中建//---------------------------------------------public:CLDirectInput();~CLDirectInput(); public://初始化directInputbool Initialize( HWND, HINSTANCE ); //更新設備當前狀態(tài)bool UpdateDevices();//響應應鍵盤消息bool IsKeyDown( unsigned int );bool IsKeyUp( unsigned int );//響應鼠標消息bool IsMouseButtonDown( unsigned int );bool IsMouseButtonUp( unsigned int );long GetMouseWheelDir();POINT GetMousePos();POINT GetMousePosRel(); protected://由析構函數(shù)調用,釋放資源void ShutDown();//DirectInput8對象LPDIRECTINPUT8 pInputSystem;//鍵盤設備LPDIRECTINPUTDEVICE8 pKeyboardDevice;char keysBuffer[KEY_SIZE];char keysBufferOld[KEY_SIZE];//鼠標設備LPDIRECTINPUTDEVICE8 pMouseDevice;DIMOUSESTATE mouseState;DIMOUSESTATE mouseStateOld;//鼠標位置信息,為移動量long xMousePos;long yMousePos;private:};#endif/******************************************************************** * 游戲輸入類 * * file: CLDirectInput.cpp * * copyright (C) 2013 by CoderLing * * email : coderling@gmail.com * * blog: http://blog.csdn.net/coderling * ********************************************************************/ #include "stdafx.h" #include "LDirectInput.h" #include <Windows.h> #include <iostream> #include <fstream> #pragma comment(lib, "dinput8.lib") #pragma comment(lib, "DXGuid.lib") //g構造函數(shù) CLDirectInput::CLDirectInput():pInputSystem( NULL ), pKeyboardDevice( NULL ),pMouseDevice( NULL ), xMousePos( 0 ), yMousePos( 0 ) {memset( keysBuffer, 0, sizeof(char)*KEY_SIZE );memset( keysBufferOld, 0, sizeof(char)*KEY_SIZE );memset( &mouseState, 0, sizeof( mouseState ) );memset( &mouseStateOld, 0, sizeof( mouseStateOld ) ); }//析構函數(shù) CLDirectInput::~CLDirectInput() {ShutDown(); }//--------------------------------------------- //-name: Initialize() //初始化DirectInput //-1、創(chuàng)建DirectInput8對象 //-2、創(chuàng)建DirectInputDevice設備 //-3、設置設備數(shù)據(jù)格式,取決于何種設別 //-4、設置設備合作等級 //---------------------------------------------- bool CLDirectInput::Initialize(HWND hWnd, HINSTANCE hInst) {HRESULT hr;HWND _hWnd = hWnd;//-1、創(chuàng)建DirectInput8對象hr = DirectInput8Create( hInst, DIRECTINPUT_VERSION, IID_IDirectInput8, (VOID**)&pInputSystem, NULL );if( FAILED( hr ) ){MessageBox( NULL, L"DirectInput8Create()-FAILED!", NULL, MB_OK );return false;}//---------鍵盤初始化---------------begin////-2、創(chuàng)建鍵盤DirectInput8Devicehr = pInputSystem->CreateDevice( GUID_SysKeyboard, &pKeyboardDevice, NULL );if( FAILED(hr) ){MessageBox( NULL, L"pInputSystem->CreateDevice()-FAILED!", NULL, MB_OK );return false;}//-3、設置鍵盤的數(shù)據(jù)格式hr = pKeyboardDevice->SetDataFormat( &c_dfDIKeyboard );if( FAILED( hr ) ){MessageBox( NULL, L"pKeyboardDevice->SetDataFormat()-FAILED!", NULL, MB_OK );return false;}//-4、設置設備合作等級hr = pKeyboardDevice->SetCooperativeLevel( _hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE );if( FAILED(hr) ){MessageBox( NULL, L"pKeyboardDevice->SetCooperativeLevel()-FAILED!", NULL, MB_OK );return false;}//清空緩沖區(qū)memset( keysBuffer, 0, sizeof(char)*KEY_SIZE );//------鍵盤初始化----------end////------鼠標初始化----------begin////-2、創(chuàng)建鼠標設備hr = pInputSystem->CreateDevice( GUID_SysMouse, &pMouseDevice, NULL );if( FAILED(hr) ){MessageBox( NULL, L"pInputSystem->CreateDevice()-FAILED!", NULL, MB_OK );return false;}//-3、設置鼠標數(shù)據(jù)格式hr = pMouseDevice->SetDataFormat( &c_dfDIMouse );if( FAILED(hr) ){MessageBox( NULL, L"pMouseDevice->SetDataFormat()-FAILED!", NULL, MB_OK );return false;}//-4、設置設備合作等級hr = pMouseDevice->SetCooperativeLevel( _hWnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE );if( FAILED(hr) ){MessageBox( NULL, L"pMouseDevice->SetCooperativeLevel()-FAILED!", NULL, MB_OK );return false;}//-----鼠標初始化--------end//return true; }//---------------------------------------------- //-name:UpdateDevice() //-更新設備狀態(tài) //-GetDeviceState() //---------------------------------------------- bool CLDirectInput::UpdateDevices() {HRESULT hr;//-更新鼠標信息if( pMouseDevice ){//-5、獲取設備hr = pMouseDevice->Acquire();if( FAILED(hr) ){MessageBox( NULL, L"pMouseDevice->Acquire()-FAILED!", NULL, MB_OK );return false;}memcpy( &mouseStateOld, &mouseState, sizeof(mouseState) );if( FAILED(pMouseDevice->GetDeviceState( sizeof(DIMOUSESTATE), (LPVOID)&mouseState )) ){if( FAILED(pMouseDevice->Acquire()) )return false;if( FAILED(pMouseDevice->GetDeviceState( sizeof(DIMOUSESTATE), (LPVOID)&mouseState )) ){MessageBox( NULL, L"pMouseDevice->GetDeviceState()-FAILED!", NULL, MB_OK );return false;}}xMousePos += mouseState.lX;yMousePos += mouseState.lY;}//-更新鍵盤信息if( pKeyboardDevice ){//-5、獲取設備hr = pKeyboardDevice->Acquire();if( FAILED(hr) ){MessageBox( NULL, L"pKeyboardDevice->Acquire()-FAILED!", NULL, MB_OK );return false;}//保留信息用于比較memcpy( keysBufferOld, keysBuffer, sizeof(char)*KEY_SIZE );if( FAILED(pKeyboardDevice->GetDeviceState( sizeof(keysBuffer), (LPVOID)keysBuffer )) ){if( FAILED( pKeyboardDevice->Acquire() ) )return false;if( FAILED( pKeyboardDevice->GetDeviceState( sizeof(keysBuffer), (LPVOID)keysBuffer )) ){MessageBox( NULL, L" pKeyboardDevice->GetDeviceState()-FAILED!", NULL, MB_OK );return false;}}} #ifndef DEBUGstd::ofstream out;out.open("text.txt");for(int i = 0;i < 256;i++){if(keysBuffer[i] != 0)out<<"dfadf"<<' ';}out<<std::endl <<std::endl;out.close(); #endifreturn true; }//---------------------------------------------- //-name:IsKyeDown() //-判斷鍵盤是否有鍵被按下 //---------------------------------------------- bool CLDirectInput::IsKeyDown( unsigned int keyNum ) {return keysBuffer[keyNum] & 0x80; }//---------------------------------------------- //-name:IsKeyUp() //-判斷鍵盤的鍵是否處于一般狀態(tài) //---------------------------------------------- bool CLDirectInput::IsKeyUp( unsigned int keyNum ) {//-如果此鍵沒被按下,而且之前被按下return !(keysBuffer[keyNum] & 0x80) && (keysBuffer[keyNum] != keysBufferOld[keyNum]); }//---------------------------------------- //-name:IsMouseButtonDown() //-判斷鼠標是否被按下 //---------------------------------------- bool CLDirectInput::IsMouseButtonDown( unsigned int buttonId ) {return mouseState.rgbButtons[buttonId] & 0x80; }//--------------------------------------- //-name:IsMouseButtonUp() //-判斷按下的某鍵是否松開 //--------------------------------------- bool CLDirectInput::IsMouseButtonUp( unsigned int buttonId ) {return !(mouseState.rgbButtons[buttonId] & 0x80) &&(mouseState.rgbButtons[buttonId] != mouseStateOld.rgbButtons[buttonId]); }//---------------------------------------- //-GetMouseRelative() //-返回鼠標滾輪滾動方向,true代表向前 //---------------------------------------- long CLDirectInput::GetMouseWheelDir() {return mouseState.lZ; }//------------------------------------------ //-GetMousePos() //-返回鼠標坐標 //------------------------------------------- POINT CLDirectInput::GetMousePos() {POINT pos;pos.x = xMousePos;pos.y = yMousePos;return pos; }POINT CLDirectInput::GetMousePosRel() {POINT rel;rel.x = mouseState.lX;rel.y = mouseState.lY;return rel; } //------------------------------------------ //-name:ShutDown() //-釋放相應資源 //------------------------------------------ void CLDirectInput::ShutDown() {if (pInputSystem){pInputSystem->Release();pInputSystem = NULL;}if (pKeyboardDevice){pKeyboardDevice->Unacquire();pKeyboardDevice->Release();pKeyboardDevice = NULL;}if (pMouseDevice){pMouseDevice->Unacquire();pMouseDevice->Release();pMouseDevice = NULL;} }

?

總結

以上是生活随笔為你收集整理的【Direct3D游戏开发】——DirectInput 让世界动起来的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內容還不錯,歡迎將生活随笔推薦給好友。