játékfejlesztés.hu
FórumGarázsprojectekCikkekSegédletekJf.hu versenyekKapcsolatokEgyebek
Legaktívabb fórumozók:
Asylum:    5440
FZoli:    4892
Kuz:    4455
gaborlabor:    4449
kicsy:    4304
TPG:    3402
monostoria:    3284
DMG:    3172
HomeGnome:    2919
Matzi:    2519

Pretender:    2498
szeki:    2440
Seeting:    2306
Geri:    2185
Orphy:    1893
Joga:    1791
Bacce:    1783
MaNiAc:    1735
ddbwo:    1625
syam:    1491
(C++) DirectX programozás 8. - DirectInput 2005.10.06 09:16



DirectX programozás 8. - DirectInput


Azt hiszem a DirectInput alapvetõ részei elintézhetõk egyetlen ilyen cikkel. Itt most a billentyûzet és az egér kezelését ismertetném, a joystick és egyéb elemek kezelése megtalálható a Microsoft Developer Net-en.

Dev-C++-ban DirectInputhoz importáljuk a dinput.h-t(#include ), majd a Project options-ban a Load objects files gombbal töltsük be a libdinput8.a és a libdxguid.a fájlokat. Ha DirectX 7-et akarunk használni, akkor importáljuk a libdinput.a-t.

Lássunk hozzá! Amiket én raktam fel header és lib fájlokat, azokban valamilyen rejtélyes módon van egy hiba. Könnyen kijavítható, csak bele kell írni a dinput.h fájl legelejére:

#define UINT_PTR UINT*

Ugyanis gondolom az UINT_PTR egy UINT típusú mutató akar lenni...

Természetesen, mint mindig, kell egy objektum, amivel kézben tarthatjuk a DirectInputot:

LPDIRECTINPUT8 lpDI    = NULL;

Ez lesz a DirectInput osztályunk. Ezen keresztül tudunk létrehozni új eszközöket(pl. billentyûzet, egér, joystick). Természetesen ezt az objektumot elõbb létre kell hozni, ugyanis anélkül nem érünk semmit egy sehova se mutató mutatóval:

hRet = DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8A, (VOID**)&lpDI, NULL);

A visszatérési érték egyértelmû, az elsõ paraméter az ablakunk példánya, a második a DirectInput verziószáma (a mellékelt forráskódban megírtam DirectX 7-re is, ott látjuk, hogy más parancsokat kell kiadni, de ez a forráskódból kiderül.). A harmadik kötelezõ paraméter(legalábbis DirectX 8-nál), a negyedik pedig maga az objektumunk.

A DirectInput inicializálásával készen is lennénk!


Egér kezelése DirectInputban

Ez sem lesz túl bonyolult téma, ugyanis csupán létrehozzuk az eszközt, majd mindig lekérdezzük az állapotát. Lássuk, hogyan hozunk létre egy egér eszközt. Kell egy objektum:

LPDIRECTINPUTDEVICE8 lpDIMouse    = NULL;

Tehát minden eszköz ugyanolyan objektumnak számít! Akkor hozzuk létre:

hRet = lpDI->CreateDevice(GUID_SysMouse, &lpDIMouse, NULL)

Látszik, hogy ugyanúgy, mint DirectDraw-ba, a CreateDevice a DirectInput objektumunk függvénye! Az elsõ paraméter mondja meg, hogy egeret akarunk(ezek a konstansok a libdxguid.a-ban vannak!). A második paraméter egyértelmûen az egér objektuma. Ha sikerült létrehozni(hibakezelés!), akkor állítsuk be, hogy milyen formátumban várnánk az adatokat ettõl az eszköztõl! Erre van a DIrectInputban egy elõre elkészített adatcsomag, amit a c_dfDIMouse konstanssal jelölünk. Tehát az adatformátum beállítása:

hRet = lpDIMouse->SetDataFormat(&c_dfDIMouse);

Ez már az egerünk egyik függvénye. Az egyetlen paraméter maga az adatcsomag azonosítója. Ha ez is megvan, akkor be kell állítanunk, hogy más program is használhatja e az egerünket. Mondjuk azt, hogy nem, tehát exluzív elérést akarunk:

hRet = lpDIMouse->SetCooperativeLevel(hwnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND);

És készen is lennénk az eszköz létrehozásával. Már csak az eszköz "élesítése" van hátra, ezt a

hRet = lpDIMouse->Acquire();

paranccsal érhetjük el. Természetesen az eszköz fel is függeszthetjük az Unacquire() paranccsal! Vigyázzunk arra, hogy ha az ablakunk elveszti az aktív szerepet, akkor vele az eszközt is elveszítjük! Ezt megelõzendõ, az ablak aktívvá válására figyelni kell, és ha megint aktív lesz, akkor megint "élesíteni" kell az eszközt. Ez a forráskódban az üzenetkezelõ eljárásban jól látszik, és elég egyértelmû! Szóval ha ezt tudjuk, akkor már csak az adatok lekérdezése van hátra!

Az adatokat akárhol lekérdezhetjük a programban, ahol látszik az eszközünk(lpDIMouse). A lekérdezéshez szükségünk van egy struktúrára, amibe az egér adatait kérdezzük le(ügye az adat milyenségét beállítottuk az eszköz létrehozásánál!).

struct  DIMOUSESTATE {
    LONG lX;
    LONG lY;
    LONG lZ;
    BYTE rgbButtons[4];
};

Tehát ebben a strúktúrában fognak tárolódni az adatok. Az lX,lY,lZ mind az egér irányait jelöli, azaz az lX például az egér vízszintes elmozdulásának a sebességét jelöli(ez átlagos egerészés közben -100-100 között van). Azaz ha az lX negatív, akkor az egér balra mozog, ha pozitív, akkor jobbra. lY-nál az egér lefele mozgása pozitiv, felfele mozgása negatív eredményt ad! Az lZ az egér görgõje. Az rgbButtons[4] tömb az egér gombjait jelzi, ha nulla, akkor nincs lenyomva, ha 128, akkor igen. Simán if paranccsal így lekérdezhetõ: if(rgbButtons[0]) {}. Ez azt jelenti, hogy ha le van nyomva, akkor ezt csináld! Az rgbButtons[0] a bal gomb, az rgbButtons[1] a jobb gomb. Figyeljük meg, hogy koordinátákról nincs szó, azokat nem lehet lekérdezni! Ugyanis a DirectInput csak az egér mozgásával foglalkozik! Akkor tehát kérdezzük le az egér pillanatnyi adatait! Ehhez a struktúra:

DIMOUSESTATE mouse_state;

Biztos, ami biztos kinullázzuk:

ZeroMemory(&mouse_state,sizeof(mouse_state));

Majd lekérjük az adatokat:

hRet = lpDIMouse->GetDeviceState(sizeof(mouse_state), &mouse_state);

Innentõl már csak ki kell õket értékelni! Szóval akkor az egérkezeléssel készen is lennénk!


Billentyûzet kezelése DirectInputban

Ugyanúgy, mint az egeret, csak más paraméterekkel, létre kell hozni a billentyûzetet:

LPDIRECTINPUTDEVICE8 lpDIKeyboard    = NULL;

hRet = lpDI->CreateDevice(GUID_SysKeyboard, &lpDIKeyboard, NULL);
hRet = lpDIKeyboard->SetDataFormat(&c_dfDIKeyboard);
hRet = lpDIKeyboard->SetCooperativeLevel(hwnd, DISCL_EXCLUSIVE | DISCL_FOREGROUND);

Ennek is az "élesítésére" van szükség ezután, teljesen azonos módon, mint az egér esetében. Amit inkább részleteznék, az az adatlekérdezés! Az adatokat egy 256 elemû, elemenként 1 bájt méretû tömbbe kérdezzük le:

char keyboard_state[256];

Kérdezzük le az adatokat(persze miután biztonságból ezt is kinulláztuk!):

hRet = lpDIKeyboard->GetDeviceState(sizeof(keyboard_state), &keyboard_state);

Namost, ennek a tömbbnek minden elem egy gombot jelent. De melyiket? A DirectInput tartalmaz erre definiált konstansokat. Pl. a DIK_ESCAPE az ESC gombbé, a DIK_RETURN az ENTER gombbé! Tehát az ESC gomb állapota: keyboard_state[DIK_ESCAPE]. Hogy honnan tudjuk, hogy meg van nyomva? Onnan ,hogy akkor a bajt legfelsõ bitje ponált állapotban lesz, azaz 1 lesz. Ezért maszkoljuk meg az állapotunkat az 10000000 kettes számrendszer beli számmal, melynek hexadecimális alakja 0x80:

keyboard_state[DIK_ESCAPE] & 0x80;

Tehát ha ez nem nullát ad vissza, akkor a gomb meg van nyomva, ha 0-t, akkor nincs megnyomva. És innentõl már tudunk billentyûzetet is kezelni. Célszerû az elõbbi mûveletre egy makrót írnim és úgy használni. Akkor itt a forráskód:

dinput.rar


Kapcsolódó linkek:
   Crusader DirectX programozás honlapja
   Itt található Crusader összes tutoriáljának eredetije.


A cikksorozat további részei:
DirectX programozás 1. - Bevezetés, Windows ablak létrehozása, Idõzítõ
DirectX programozás 2. - DirectDraw inicializálása, használata
DirectX programozás 3. - DirectDraw megjelenítés 1.
DirectX programozás 4. - DirectDraw megjelenítés 2.
DirectX programozás 5. - Izometrikus grafika
DirectX programozás 6. - Matematika összefoglaló 1.
DirectX programozás 7. - Matematika összefoglaló 2.: Lineáris algebra
DirectX programozás 8. - DirectInput
DirectX programozás 9. - DirectSound, Ogg Vorbis lejátszás
DirectX programozás 10. - Izometrikus grafika 2.
DirectX programozás 11. - Objektumorientált programozás

Értékelés: 0

Új hozzászólás
Nincs megjegyzés