使用DirectInput來控制遊戲

2021-08-25 15:50:15 字數 2819 閱讀 9296

使用directinput來控制遊戲

directinput是我很久以前就接觸的了。在乙個學期前,我就除錯過由allen sherrod編寫的程式,由於對directinput不了解,所以我只能從程式的表象來認識它,沒有從內部了解它的原理。

以前的文章請點這裡

在這個寒假我看了很多的遊戲程式設計的書,它們都介紹了怎樣使用directinput進行遊戲程式設計,這才使我對它有了更深層次的了解。但是爭論還是存在的。主要原因是到底該不該使用這個技術。正方觀點認為directinput可以繞開windows訊息佇列機制,能夠更即時地操作硬體,這對遊戲的操作來說是至關重要的。反方觀點則用微軟自己官方的建議來說明使用directinput的效果不如其它效果。至於我,由於自己還未涉足專案,所以不好說孰優孰劣。但是自從我實現了directinput後我就覺得應當使用這個技術,因為它在處理即時事件的效果確實比windows的訊息佇列機制要好。

順便說明一下,還有乙個方法可以實現按鍵的功能。那就是getkeystate()和getasynckeystate()函式。其中getkeystate()用來處理延時的訊息,而getasynckeystate()採用了非同步操作,可以處理即時的訊息。對於windows開發者來說,使用乙個函式要比建立物件並且初始化,程式結束後刪除物件、釋放空間要快得多。但是這或許對小遊戲是如此,但是對於專業的遊戲呢?你們看到一些3d遊戲使用的是方向盤,另一些使用的是電子槍,而更多的或許是手柄。這些使用windows的訊息機制又是怎樣對映呢?對於鍵盤和滑鼠的訊息,windows可以轉換為ascii碼,但是那些遊戲互動裝置的訊息windows就無能為力了,所以我們只好退而求其次:使用雖然複雜但是更加專業的directinput了。

一些書和部落格上詳盡地講述了directinput的使用。這裡我就我遇到的情況進行分析講述,希望能夠解大家的困惑。

我知道當初為什麼allen sherrod會編寫錯誤的**了。因為它引用的庫函式和我們開發的不同。也就是說,direct的sdk版本不一致。誠然,allen sherrod沒錯,我們的電腦也沒錯,就是版本的不一致而使得他們的**變得難以辨認。我在看了一些遊戲程式設計的書後,決定不再沿著allen sherrod的老路走了,因為自己已經建立了乙個win32的程式框架,有什麼理由不讓我在自己的**的基礎上進行開發呢?

好吧,我們行動了!

首先我要說明的是,我使用的是xp系統+vs2005,配上的directx sdk版本是「microsoft directx sdk (april 2006)」,比較老了,但是還挺好用。以後如果是任何執行不了我程式的問題,可以參照一下我的配置,問題應該出現在這兒。

接下來我就要說的就是我遇到的問題了。首先我在遵循書上的**進行編譯的時候,發現有乙個編譯錯誤和兩個連線錯誤。編譯錯誤是我在寫#include的時候,它提醒我沒有定義directinput_version這個巨集。經過它們的提醒,我在include語句前面加上了define語句,將巨集的值定義為0x0800,錯誤就消失了。另外兩個連線錯誤就有些難辦了。我開始想是不是少用了include語句新增標頭檔案呢?結果我在include資料夾找到了一些類似的標頭檔案,結果還是沒有解決問題。後來根據我的經驗,發現是沒有這個函式的實現造成的。我就想是不是少連線了什麼庫函式。於是在這種想法的驅使下,我開啟了以前allen sherrod的**,這個**是我修改過的,應該沒有什麼問題。結果我發現,我的**相比我以前修改的**,少了兩句「#pragma comment( lib, "dinput8.lib")和#pragma comment( lib, "dxguid.lib")」。我在加上這兩句後,編譯,連線,一切正常。這個問題終於解決了。

現在我給大家分享一下我使用directinput(鍵盤)的步驟:

1、在全域性定義乙個lpdirectinput8和lpdirectinputdevice8物件,初始化為null。

2、使用directinput8create()函式來建立物件。

3、使用lpdirectinput8物件的成員函式createdevice()來建立裝置。

4、使用lpdirectinputdevice8物件的成員函式setdataformat()來設定資料格式。

5、使用lpdirectinputdevice8物件的成員函式setcooperativelevel()來設定合作等級,這裡非獨占有,程式前台控制有效的標誌符最好。

6、使用lpdirectinputdevice8物件的成員函式acquire()來獲取輸入裝置。

7、使用lpdirectinputdevice8物件的成員函式getdevicestate()來將鍵盤的按鍵對映到乙個長度為256位元組的字元陣列中。

8、現在可以使用按位與運算和0x80進行運算,判斷按鍵是否被按下。

9、程式關閉後先使用lpdirectinputdevice8物件的成員函式unacquire()來解除獲取輸入裝置。並且呼叫release()函式進行物件記憶體空間的釋放。

聽起來聽複雜的,但是為了在大型的遊戲中獲取比windows訊息更優越的效能,這一點工作還是值得的。

我自己做了乙個程式,將它和我以前使用windows訊息機制的程式作對比,發現使用directinput果然好用。它可以連貫、流暢地響應按鍵,而使用windows訊息的話則沒有那麼連貫。舉個例子吧,我在以前的程式中,按著乙個鍵不放,精靈圖形先走一步,頓一下,再進行連貫的行走;而使用directinput可以沒有停頓地進行行走,更好的是它支援組合按鍵同時響應。我試了下,按緊上和左,精靈就往左上走,這多麼的方便啊!

程式的截圖如下所示:

這個程式還存在著以下兩個問題:

1、載入精靈影象的時候,發現和源影象有著一定比例的壓縮,影象總是扁一些。我不知道為什麼會這樣;

2、在進行程式切換,再切回我們編寫的程式的時候,directinput無法工作,這個問題我暫時沒能拿出好的解決方案。

有時間的話,我還會對遊戲的其它的部分(例如模型載入、聲音系統、指令碼系統)進行深入的研究的!

如何使用VSS來管控你工程程式碼

vss visual source safe 是微軟隨同visual studio一起推出的版本控管軟體.它可以集中管理工程程式碼.一般情況下乙個專案可能有很多人一起開發,每乙個人只負責乙個或幾個模組的編寫與修改,那麼這就導致了程式碼分散在不同的機器上,而且每台機器上的程式碼版本會與實際版本不一致....

Android 重寫View來實現全新的控制項

xmlversion 1.0 encoding utf 8 resources declare styleable name myarcscalemap attr name myarcscalemap titletext format string attr name myarcscalemap t...

天穹飛控使用指引

必裝 git for windows 管理工具 github desktop github桌面版圖形化軟體,配合git使用 可選 拿到飛控後,首先需要進行以下校準 飛控板上帶有硬體恆溫,建議等待溫度穩定後,再進行校準。而且前三個校準每個飛控只需要進行一次,後續無需再次校準。建議將飛控安裝在機架的正中...