LECKÉK:              

Saját ablak
Directdraw1
Directdraw2
Directdraw_3
Sprite_1

Sprite 2
Billentyű_1
Billentyű_2
Egér
Joystick
Midi
MP3
Directsound
Időzítők
Fájlkezelés
 

Üdvözöllek!
Elérkeztünk az Input osztály utolsó tagjához,a botkormányhoz!
Ez a legnehezebb,mert fel kell ismerni,hogy van-e egyáltalán a rendszerben,és hány darab,
milyen tulajdonságai vannak stb. Vágjunk bele!

Figyelem!

Az osztályon kívül kell létrehozni a következő adattagokat a dekralációk megjegyzés alatt:
LPDIRECTINPUT8 lpDI; //input objektum ezen keresztül hozzuk létre a többit
LPDIDEVICEINSTANCE instance;
LPDIRECTINPUTDEVICE8 joy;

Tehát a directinput objektumunk (lpDI) globális lett,mert amikor felderítjük a botkormányt,kell egy visszatérési függvényt készíteni, annak pedig szüksége van a pointerre.Ha az osztályban maradna,akkor nem érheti el. Fel kell  venni a nem védett tagok közé még:

..........
bool init_joy();
bool get_key(unsigned char,bool frissit=false);
DIMOUSESTATE* get_mouse();//a kitöltött struktúrával tér vissza vagy NULL
LPDIJOYSTATE2 get_joy(); //a kitöltött struktúrával tér vissza vagy NULL
A védett tagváltozók közé pedig:    DIJOYSTATE2 dij2;//botkormány adatoknak

A megvalósítás:
Kell két visszatérési függvény, az egyik a csatolt eszközök közül a botkormány(ok) kiválasztására,a másik pedig a tulajdonság meghatározására:
BOOL CALLBACK enumCallback(const DIDEVICEINSTANCE* instance, VOID* context)
{
HRESULT hr;

// Csatolt eszközök között talált botkormányt létrehozza az objektumot
hr = lpDI->CreateDevice(instance->guidInstance, &joy, NULL);

//Azonban ha nem sikerült,mert nincs,vagy másfajta akkor tovább keres
if (FAILED(hr)) {
return DIENUM_CONTINUE;
}
//instance->dwDevType tipusban tárolja a talált eszköz pontos tipusát
//most az első talált botkormányt illesztjük,leállítjuk a felsorolást
//
return DIENUM_STOP;
}

Ezt a függvényt a EnumDevices() függvény hívja, addig,amíg megtalálja a keresett eszközt.

A másik:

BOOL CALLBACK enumAxesCallback(const DIDEVICEOBJECTINSTANCE* instance, VOID* context)
{
HWND hDlg = (HWND)context;

DIPROPRANGE propRange;
propRange.diph.dwSize = sizeof(DIPROPRANGE);
propRange.diph.dwHeaderSize = sizeof(DIPROPHEADER);
propRange.diph.dwHow = DIPH_BYID;
propRange.diph.dwObj = instance->dwType;
propRange.lMin = -1000;
propRange.lMax = +1000;
if (FAILED(joy->SetProperty(DIPROP_RANGE, &propRange.diph))) {
return DIENUM_STOP;
}

return DIENUM_CONTINUE;
}

Beállítja a botkormány max kimozdulásához az értéket  az instance->dwType által mutatott eszközökben.

Az init_joy() megvalósítása:

bool INPUT::init_joy()
{
DIDEVCAPS capabilities;
BOOL inf; //infó,hogy sikerült- e a függvény
if( !lpDI)//ha még más nem hozta létre az objektumot
{
inf=DirectInput8Create( hinstance, DIRECTINPUT_VERSION, IID_IDirectInput8A, (VOID**)&lpDI, NULL);
if (inf !=DI_OK)return false;//ha nem sikerült
}
//A felsoroló függvény számbaveszi a telepített botkormányokat és az elsőt azonosítja
inf = lpDI->EnumDevices(DI8DEVCLASS_GAMECTRL, enumCallback,NULL, DIEDFL_ATTACHEDONLY);
if (inf !=DI_OK)return false;
if (joy == NULL)return false;//ha nem jött létre az új objektum
if (FAILED(inf = joy->SetDataFormat(&c_dfDIJoystick2)))return false;
if (FAILED(inf = joy->SetCooperativeLevel(hwnd, DISCL_EXCLUSIVE |DISCL_FOREGROUND)))
return false;
capabilities.dwSize = sizeof(DIDEVCAPS);
//számbaveszi a gombokat,tengelyeket stb.
if (FAILED(inf = joy->GetCapabilities(&capabilities)))return false;
//beállítja a botkormány max kitéréséhez az értéket.
if (FAILED(inf = joy->EnumObjects(enumAxesCallback, NULL, DIDFT_AXIS)))return false;
return true;
}

A get_joy() függvény megvalósítása:

LPDIJOYSTATE2 INPUT::get_joy()
{
BOOL inf;
DIJOYSTATE2* mut=NULL;
if (joy == NULL)return mut;
inf = joy->Poll();//mivel nem tudható hogy az eszköz frissíti e önmagát kikényszerítjük
if (inf!=DI_OK)
{
inf = joy->Acquire();//valószínű aktiválni kell következöre jó lesz
if(inf !=DI_OK)return mut;//üres mutatóval vissza
}
inf = joy->GetDeviceState(sizeof(DIJOYSTATE2), & dij2);
if(inf !=DI_OK)return mut;
return & dij2;
}

Kommentezve van,ezért nem szorul magyarázatra. Ha valamilyen hiba miatt nem tud beolvasni adatot, akkor egy üres mutatóval tér vissza,tehát vizsgálni kell a meghívása után a pointert.
Ez igaz az egérre is. Elfelejtettem a konstruktorban nullázni a joy objektumot,és fel is kell szabadítani a destruktorban:

INPUT::INPUT()
{
bill=NULL;mouse=NULL;joy=NULL;
}
//
INPUT::~INPUT()
{
if(bill){bill->Release();bill=NULL;}
if(mouse){mouse->Release();mouse=NULL;}
if(joy){joy->Release();joy=NULL;}
lpDI->Release();lpDI=NULL;
};

A használata:
A Sprite .hpp-ban:

Dekraláljál egy új függvényt : void babu_mozgat_joy();
megvalósítása:
void SPRITE::babu_mozgat_joy()
{
DIJOYSTATE2* adat; //ezt az üres mutatót töltjük fel a függvénnyel,ami
//frissíti az adatokat,és visszaadja az ő osztályában
//lévő struktúra mutatóját
adat=input.get_joy();
if(adat==NULL)return;//ha nem sikerült elérni
sp[0].SP_X+=(int)adat->lX/249;
sp[0].SP_Y+=(int)adat->lY/249;
rajz.kiirszam(adat->lX,300,10);
rajz.kiirszam(adat->lY,300,30);
rajz.kiirszam(adat->rgbButtons[0],300,50);
rajz.kiirszam(adat->rgbButtons[1],300,70);
rajz.kiirszam(adat->rgbButtons[2],300,90);
rajz.kiirszam(adat->rgbButtons[3],300,110);
}
Egyetlen dolog maradt,hogy a main cpp-ben meghívjuk az inicializáló függvényt:
.......
input.init_key();
input.init_mouse();
input.init_joy ();
sprite.sp_init ();
while (fut)
-----------

fordít   futtat...
A programunkban működnie kell a golyónak billentyűzetről, egérről, és botkormányról is.
Botkormányról CSAK AKKOR ha az eszköz telepítve van,és csatlakoztatva van a géphez.
Következik a MIDI zeneformátum használata.
Itt a kód:

vissza