瑞星卡卡安全论坛

首页 » 技术交流区 » 系统软件 » 【原创】游戏制作新手晋级 之 DirectInput封装
我是天心飞仙 - 2006-8-16 12:53:00
获取外部设备的状态是游戏中必不可少的部分,但是看到很多初学者并不能很好的组织DirectInput,以至于被那些复杂的接口搞得晕头转向。故有此文。
封装要做的工作就是,把那些复杂的接口,做成你自己“看得惯”的东西:)
DI的封装主要有以下几个部分:
[1]Initialize  初始化DI控制组件
[2]GetDevices  获取输入设备状态
[3]SetMousePos  设置鼠标位置
[4]Release      释放DI控制组件
我是天心飞仙 - 2006-8-16 12:54:00
先来看看封装的头文件 MyDirectInput.h

///////////////////////////////////////////////////////////////////////////////
//MyDirectInput.h
//DirectInput封装
///////////////////////////////////////////////////////////////////////////////
#pragma  once
#pragma  message("MyDirectInput.h --> Linking with dinput8.lib")
#pragma  comment(lib,"dinput8.lib")

#include <windows.h>
#include <windowsx.h>
#include <dinput.h>
//DI对象
extern  LPDIRECTINPUT8            lpDInput  = NULL;
extern  LPDIRECTINPUTDEVICE8      lpDIKey  = NULL;
extern  LPDIRECTINPUTDEVICE8      lpDIMouse = NULL;

//数据缓冲
extern  UCHAR        key[256];
extern  DIMOUSESTATE  mouse_state;

//封装接口
extern  BOOL  Initialize(void );    //初始化
extern  BOOL  GetDevices(void );    //获取设备
extern  BOOL  SetMousePos(POINT );  //设置鼠标位置
extern  BOOL  SetMousePos(long ,long );
extern  BOOL  Release(void );      //释放
//封装变量
extern  BOOL          mleft,mright,mcenter; //鼠标按键状态
extern  POINT        mpt;                  //鼠标指针位置

我是天心飞仙 - 2006-8-16 12:55:00
再来看实现部分 MyDirectInput.cpp :


///////////////////////////////////////////////////////////////////////////////
//MyDirectInput.cpp
///////////////////////////////////////////////////////////////////////////////
#include "MyDirectInput.h"
#include <windows.h>
#include <windowsx.h>
#include <dinput.h>
///////////////////////////////////////////////////////////////////////////////

extern HWND            hWnd;
extern HINSTANCE        hInstance;
extern char            buffer[80];

//DI对象
LPDIRECTINPUT8            lpDInput  = NULL;
LPDIRECTINPUTDEVICE8      lpDIKey  = NULL;
LPDIRECTINPUTDEVICE8      lpDIMouse = NULL;

//数据缓冲
UCHAR        key[256];
DIMOUSESTATE  mouse_state;

BOOL          mleft,mright,mcenter;
POINT        mpt;

///////////////////////////////////////////////////////////////////////////////
//[1]Initialize  初始化DI控制组件
//分析:游戏中最常用的两个输入设备就是鼠标和键盘,我们的这个封装就是要完成这对两个设备状态的操作。
//      初始化部分,首先要创建DirectInput对象,再创建设备对象。
///////////////////////////////////////////////////////////////////////////////

BOOL    Initialize(void )
{
//DirectInput Interface
    if(FAILED(DirectInput8Create(hInstance,DIRECTINPUT_VERSION,IID_IDirectInput8,(VOID**)&lpDInput,NULL)))
    {
        ShowError("DirectInput8Create ERROR");
        return FALSE;
    }
//Keyboard
    if(lpDI->CreateDevice(GUID_SysKeyboard,&lpDIKey,NULL)!=DI_OK)
    {
        ShowError("lpDI->CreateDevice Keyboard ERROR");
        return FALSE;
    }
    if(lpDIKey->SetCooperativeLevel(hWnd,DISCL_BACKGROUND|DISCL_NONEXCLUSIVE|DISCL_NOWINKEY)!==DI_OK)
    {
        ShowError("lpDIKeyboard->SetCooperativeLevel ERROR");
        return False;
    }
    if(lpDIKey->SetDataFormat(&c_dfDIKeyboard)!=DI_OK)
    {
        ShowError("lpDIKeyboard->SetDataFormat ERROR");
        return False;
    }
    if(lpDIKey->Aquire()!=DI_OK)
    {
        ShowError("lpDIKeyboard->Acquire ERROR");
        return False;
    }
//Mouse
    if(lpDI->CreateDevice(GUID_SysKeyboard,&lpDIMouse,NULL)!=DI_OK)
    {
        ShowError("lpDI->CreateDevice Mouse ERROR");
        return FALSE;
    }
    if(lpDIMouse->SetCooperativeLevel(hWnd,DISCL_BACKGROUND|DISCL_EXCLUSIVE|DISCL_NOWINKEY)!==DI_OK)
    {
        ShowError("lpDIMouse->SetCooperativeLevel ERROR");
        return False;
    }
    if(lpDIMouse->SetDataFormat(&c_dfDIMouse)!=DI_OK)
    {
        ShowError("lpDIMouse->SetDataFormat ERROR");
        return False;
    }
    if(lpDIMouse->Aquire()!=DI_OK)
    {
        ShowError("lpDIMouse->Acquire ERROR");
        return False;
    }
    return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
//[2]GetDevices  获取输入设备状态
//分析:未经封装的设备状态使用十分不便,这个函数统一获取了有用的状态,以便集中调用
///////////////////////////////////////////////////////////////////////////////

BOOL    GetDevices(void )
{
//获取设备信息
    lpDIKey->GetDeviceState(256,(LPVOID)key);
    lpDIMouse->GetDeviceState(sizeof(DIMOUSESTATE)),(LPVOID)&mouse);
//调整按键状态
    if(mouse.rgbButtons[0]&0x80)    mleft  = TRUE; //左键
    if(mouse.rgbButtons[1]&0x80)    mright  = TRUE; //右键
    if(mouse.rgbButtons[2]&0x80)    mcenter = TRUE; //中键
//调整鼠标位置
//注意,mouse.lX 和 mouse.lY 都是相对于上一次的偏移量!
    mpt.x += mouse.lX;
    mpt.y += mouse.lY;

    return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
//[3]SetMousePos  设置鼠标位置
//分析:由于mouse状态中的lX和lY都是偏移量,所以可以通过直接修改mpt的方法设置鼠标位置
//注意:这个函数有多态性
///////////////////////////////////////////////////////////////////////////////

BOOL    SetMousePos(POINT pt )
{
    mpt = pt;
    return TRUE;
}

BOOL    SetMousePos(long x ,long y )
{
    mpt.x = x;
    mpt.y = y;
    return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
//[4]Release      释放DI控制组件
//注意:由于初始化时创建的顺序不同,所以要相对应的一次释放对象
///////////////////////////////////////////////////////////////////////////////

BOOL    Release(void )
{
    if(lpDIMouse){
        lpDIMouse->Unacquire();
        lpDIMouse->Release();
    }
    if(lpDIKey){
        lpDIKeyboardboard->Unacquire();
        lpDIKeyboardboard->Release();
    }
    if(lpDInput){
        lpDI->Release();
    }
   
    return TRUE;
}

///////////////////////////////////////////////////////////////////////////////
我是天心飞仙 - 2006-8-16 12:59:00
注意:实现部分的错误处理我用了 ShowError这个函数,它不是标准的函数,只是我自己创建的一个便于输入的函数。内容如下:

void ShowError(const char * msg)
{
    MessageBox(NULL,msg,"Error!",MB_OK);
}

(本文结)
我是天心飞仙 - 2006-8-17 12:06:00
无人区?
郁闷ing...
1
查看完整版本: 【原创】游戏制作新手晋级 之 DirectInput封装