DirectX8 与 键盘
by Mason "masonium" Smith
这个主题假设你已经知道了基本的Win32编程;
DirectX是一组API, 假如你在使用Windows9x/NT/2000/XP,它允许你直接访问硬件。这是很漂亮的,你不必写特殊的代码就能够访问每一个图形卡、声卡和输入
设备。DirectX能够处理细节,这很好。这篇文章将像你介绍如何使用DirectInput8来访问键盘。首先,你必须包含 dihput.h头文件,而且还要连接dxguid.lib和dinput8.lib库。
DirectInput是DirectX API当中最容易的部分。下面我们看一下初始化代码:
//Globals
LPDIRECTINPUT8 lpdi ;
LPDIRECTINPUTDEVICE8 m_keyboard ;
unsigned char keystate[256] ;
void Init( void )
{
if( FAILED( DirectInput8Create( GetModuleHandle( NULL ), DIRECTINPUT_VERSION,
IID_IDirectInput8, (void**)&lpdi, NULL )))
{
//error code
}
if( FAILED( lpdi->CreateDevice( GUID_SysKeyboard, &m_keyboard, NULL )))
{
//error code
}
if( FAILED( m_keyboard->SetDataFormat( &c_dfDIKeyboard )))
{
//error code
}
if( FAILED( m_keyboard->SetCooperativeLevel( hwnd, DISCL_BACKGROUND |
DISCL_NONEXCLUSIVE )))
{ // error code }
if( FAILED( m_keyboard->Acquire() ))
{ // error code }
}
上面的代码是为了使用键盘,而对DirectInput进行了初始化。假如函数返回的不是DI_OK,则宏FAILED返回TRUE,表明这个函数调用失败。
现在, 让我们来看看如何得到键盘输入数据
void Render( void )
{
if( FAILED( m_keyboard->GetDeviceState( sizeof(unsigned char[256], (LPVOID)keystate)))
{ // error code }
if( keystate[DIK_LCONTROL] & 0X80 )
{
//shoot gun ,jump, react somehow
}
}
GetDeviceState函数用于更新键盘的状态, 并且为了得到键盘的输入,你必须在游戏主循环的开始呼叫它。
如果你觉得(keystate[DIK_LCONTRLO] & 0X80 )样式看着不是很顺眼的话,你可以定义如下两个宏
#define KeyDown(data, n) ((data[n] & 0x80) ? true : false)
#define KeyUp(data, n) ((data[n] & 0x80) ? false : true)
这样好了好了很多, 不是吗, 你只需像下面那样调用就可以了
if (KeyDown(keystate, DIK_LCONTROL))
{ /* do something */ }
最后,我们要做的事情就是创建一个Destroy函数用来释放DirectInput
void Destroy(void)
{
if (m_keyboard)
m_keyboard->Release();
if (lpdi)
lpdi->Release();
}
现在我们来整体看一下
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <dinput.h>
// Globals
LPDIRECTINPUT lpdi;
LPDIRECTINPUTDEVICE m_keyboard;
unsigned char keystate[256];
HWND hWND;
HINSTANCE g_hinstance;
bool done = false;
// Defines
#define KeyDown(data, n) ((data[n] & 0x80) ? true : false)
#define KeyUp(data, n) ((data[n] & 0x80) ? false : true)
// Function declarations
void Init(void);
void Render(void);
void Destroy(void);
// Message Loop CallBack Function
LRESULT CALLBACK WinProc ( HWND hWnd, UINT iMsg, WPARAM wParam, LPARAM lParam )
{
HDC hDC;
switch( iMsg )
{
// Called when window is first created
case WM_CREATE:
Init();
return( 0 );
// Called when the window is refreshed
case WM_PAINT:
hDC = BeginPaint(hWnd, &paintStruct);
EndPaint(hWnd, &paintStruct);
return( 0 );
// Called when the user closes the window or terminates the application
case WM_DESTROY:
Destroy();
PostQuitMessage( 0 );
return( 0 );
}
return DefWindowProc( hWnd, iMsg, wParam, lParam );
}
// Function to Create the Window and Display it
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
// basic windows creation stuff
while (!done)
{
PeekMessage(&msg, hWnd, NULL, NULL, PM_REMOVE);
if (msg.message == WM_QUIT) // do we receive a WM_QUIT message?
{
done = true; // if so, time to quit the application
}
else
{
Render();
TranslateMessage(&msg); // translate and dispatch to event queue
DispatchMessage(&msg);
}
}
return ( msg.wParam );
}
void Init(void)
{
if (FAILED(DirectInput8Create(GetModuleHandle(NULL), DIRECTINPUT_VERSION,
IID_IDirectInput8, (void**)&lpdi, NULL)))
{
// error code
}
if (FAILED(lpdi->CreateDevice(GUID_SysKeyboard, &m_keyboard, NULL)))
{ /* error code */ }
if (FAILED(m_keyboard->SetDataFormat(&c_dfDIKeyboard)))
{ /* error code */ }
if (FAILED(m_keyboard->SetCooperativeLevel(hWND, DISCL_BACKGROUND |
DISCL_NONEXCLUSIVE)))
{ /* error code */ }
if (FAILED(m_keyboard->Acquire()))
{ /* error code */ }
}
void Render(void)
{
if (FAILED(m_keyboard->GetDeviceState(sizeof(unsigned char[256]), (LPVOID)keystate)))
{ /* error code */ }
if (KeyDown(keystate, DIK_ESCAPE))
{
PostQuitMessage(0);
}
}
void Destroy(void)
{
if (m_keyboard)
m_keyboard->Release();
if (lpdi)
lpdi->Release();
}
一定不要忘了在你的工程中连入dxguid.lib和dinput8.lib。如果你不知道如何连接这些库,请看编译手册。
// whole lot of stuff
// initiates the program
void Init(void)
{
// other important stuff
Init_CInput8(hWND); // takes handle to the window as parameter
Init_Keyboard(g_hinstance); // takes instance handle as parameter
Init_Mouse(g_hinstance); // takes instance handle as parameter
// other important stuff
}
// renders the program
void Render(void)
{
Read_Keyboard();
Read_Mouse();
// stuff
if (KeyDown(DIK_SPACE))
{
shooting = true;
}
if (KeyUp(DIK_SPACE))
{
shooting = false;
}
if (KeyPress(DIK_RETURN))
{
FireRockets(5);
}
// stuff
float mx, my;
Get_Mouse_Movement(mx, my);
cursor_x += mx;
cursor_y += my;
if (Button_Down(LEFT_BUTTON))
{
LaunchGrenade();
}
}
// de-initiates the program
void Destroy(void)
{
Release_Mouse();
Release_Keyboard();
Shutdown_CInput8();
}
这篇文章翻译自 http://www.gamedev.net
随便翻译了一篇文章, 如有翻译的不对的地方,还请路上的朋友指正,谢谢
MSN: closeall@hotmail.com
e_mail : closeallster@gmail.com
译者;closeall
时间:2005.09. 17