LECKÉK:              

Saját ablak
Directdraw1
Directdraw2
Directdraw_3
Sprite_1

Sprite 2

Üdvözöllek!
Elérkeztünk a sprite- osztályhoz.
Azonban van még egy adósságom a RAJZ osztályból:
Az egérkurzort eltüntetheted a Main cpp-ben a rajz.init() függvény elé kell beírni:


ShowWindow(hwnd,nFunsterStil);
ShowCursor(false);    //egér eltüntetése
if(!rajz.init())MessageBox(NULL,"directdraw nem oké","",0);

A másik, hogy amikor leteszed az alkalmazást kis méretbe, akkor elveszik a memória fekülete,és amikor újból előjön az ablak, akkor nincs kép, csak villódzás..
Orvoslása a flip() függvényben:
 if(inf!=DD_OK ){obj->RestoreAllSurfaces();UpdateWindow( hwnd);load_init();};
azaz ha nem sikerült a flip meghívjuk a restore() függvényt,helyreállítja a felületeket,de a bmp képadatok elvesztek, és ezért betöltjük újból mindet.

Mivel egy sprite- nak nagyon sokféle adata lehet,ezért, hogy ne legyen káosz, ezeket az adatokat összefogjuk egy struktúrába,és ebből a struktúrából létrehozunk egy tömböt,hogy az összes sprite adatát egységesen lehessen kezelni. Mik is ezek az adatok????
van szélessége, magassága, x helyzete és y helyzete a képernyőn van sebessége x és y irányban
van egy kép valahol amit ki kéne rajzolni, ha animált,akkor annak hány fázisa van, és mennyi az összes fázis? (pl egy forgó kerék hány képkockából áll és melyik az aktuális) az animáció sebessége
Szabadon megválaszthatod,mire van szükséged,de ha mindet feltünteted,akkor sincs baj,legfeljebb nem használod fel, a mai 512 ,1024 Mega RAM- os gépeknél ez a párszor 2 byte nem oszt nem szoroz.
Tehát hozz létre a projectben egy új fájl-t Sprite.hpp néven. és hozd létre a SPRITE osztályt:

#ifndef _SPRITE_
#define _SPRITE_

//dekralációk:
class SPRITE
{
    public:
            SPRITE ();
            ~SPRITE();
    protected:
};

//megvalósítások:


#endif

Ha eddig megvagy, akkor készítsd el a struktúrát is: a dekralációk fölé
/**/
typedef struct
{
int SP_X; //sprite x helyzete a képernyőn
int SP_Y; // y helyzet
int SP_SZ; // szélesség pixelekben
int SP_M; // magasság pixelekben
char SP_AN; // aktuális képpozíció
char SP_ANMAX; // maximum ennyi képpozíció van
char SP_X_IRANY; //
char SP_Y_IRANY;
int SP_KEPE; // melyik betöltött képen van a sprite rajza
int SP_KEP_X; // a képen az x helyzet
int SP_KEP_Y; // a képen az y helyzet
int SP_FX; // forrópont x
int SP_FY; // forrópont y
}SP, *LPSP;
/**/
Tehát létrejött egy  SP típus és egy LPSP típusú mutató tehát ha valahol azt írod,hogy
LPSP mut , akkor a    mut  egy üres mutató, ami "lefoglal" egy sprite -nyi területet, de mivel nincs
még értéke sehova sem mutat.
A protected: //védett tagváltozók   alá elhelyezzük a tömbünket:
SP sp[25]; //25 sprite számára hely
Lehet akár 500 db is....
kellene a sprite-okat inicializálni értékkel feltölteni, ezért dekraláljuk az init() függvényt! ezt esetleg más osztályokból fogjuk hívni,ezért public- okhoz tesszük:
void sp_init();
a megvalósítása úgy lesz, hogy a pozíciói és az iránya sebessége szinte minden véletlen szerűen
lesz inicialzálva, mert ez nem egy játék,csak oktató progi. csillag lesz,ami animált.
Az egyes dolgokhoz megírjuk külön külön a függvényeket.
megvalósítás:

void SPRITE::sp_init()
{
srand(GetTickCount()); //véletlenszám generátor inicializálása a rendszerszámlálóval
for (int i=1;i<25;i++)
{
LPSP mut=&sp[i];//csak azért hoztam létre a mutatót, mert nehezebb állandóan sp[i] -t irni.
mut->SP_X=rand()%752;
mut->SP_Y=rand()%552; //x és y helyzet a képernyőn
mut->SP_SZ=mut->SP_M=48;//szélesség magasság 48 pixel
mut->SP_AN=rand()%10; //hogy ne egyszerre villogjanak
mut->SP_ANMAX=10; //ennyi kép van
mut->SP_X_IRANY=rand()%4-2; //xértéke -2 és 2 között lesz
if(!mut->SP_X_IRANY)mut->SP_X_IRANY=1;//ha nullaa random,akkorlegyen 1
mut->SP_Y_IRANY=rand()%4-2;
if(!mut->SP_Y_IRANY)mut->SP_Y_IRANY=1;
mut->SP_KEP_X=197; //a bmp képen a sprite x képe
mut->SP_KEP_Y=mut->SP_AN*49;// megnézheted paint-ban mutatja a koordínátát alul
}
}

Ha többféle tulajdonsággal kellene az init,akkor a for(   ) ciklust többször és kisebb db számmal kell meghívni. Eldöntheted,rakhatod a konstruktorba is.Vagy másfélét kell írni,lehet több pálya.stb.
Ez most nem feladat.
A sprite-okat ki is kell rajzolni a képernyőre! dekraláció:      void sp_rajz();
Azonban kellene a RAJZ osztály rajzol függvénye....   nem egy új new operátorral, hanem amit a main cpp-ben jött létre: extern RAJZ rajz;
A  rajzolás megvalósítása:
void SPRITE::sp_rajz()//függetlenüla tulajdonságaiktól és méretüktől mindet kirajzoljuk
{
for(int i=0;i<25;i++)
{
LPSP mut=&sp[i];//átvesszük az aktuális sprite mutatóját
rajz.rajzol(mut->SP_KEPE,mut->SP_KEP_X,mut->SP_KEP_Y,mut->SP_SZ,mut->SP_M,-1,mut->SP_X,
mut->SP_Y);//a sprite strukrúra minden adatot tartalmaz
}

}

Most már ki kéne tudni rajzolni a sprite- okat, azonban létre kell hozni még egy függvényt,mert ebben az osztályban több függvényt is meg kell írni, és egyszerűbb egy frissít nevűt meghívni "kívülről" majd a frissít() szépen sorba meghívja az osztályon belül az összes többit. tehát dekr.:
void frissit();
Megvalósítása:

void SPRITE::frissit()
{
rajz.rajzol(0,0,0,800,600,-1,0,0)//háttér
sp_rajz();
rajz.flip();
}
Látható most már innen vezéreljük a kirajzolást,tehát a RAJZ osztály flip() függvényét soványítani kell:
void RAJZ::flip()
{
BOOL inf=front->Flip(NULL,0);
if(inf!=DD_OK /*&& aktiv*/){obj->RestoreAllSurfaces();UpdateWindow( hwnd);load_init();};
}

 

Megyünk a Main Cpp-be!

Itt a lap tetején csatoljuk a Sprite forráskódot:

#include <Sprite.hpp>  A rajz osztály mellé tesszük a sprite osztályt is:
SPRITE sprite;
Az maradt csak hátra, hogy kicsit módosítsuk a végtelen ciklus környékét:

if(!rajz.init())MessageBox(NULL,"directdraw nem oké","",0);
sprite.sp_init();// nem lehet a rajzinit()  előtt mert a felületeket előbb inicializálni kell!
while (fut)
{
uzenetkezelo();
sprite.frissit();// a sprite osztály átvette a rajzoló rutinokat

}
return 0;
Fordít---  futtat. A sprite-oknak meg kell jelenniük a képernyőn, véletlenszerű pozícióval, és véletlen

animációs képpel.

Vissza Sprite hpp-be!
Megcsinálom még az animációját is. dekr.: void anim();
Mivel ez az osztály belügye tedd a protected közé! Megvalósítás:
void SPRITE::anim()
{
static char szamlalo=5;//minden 5 képkirajzolásakor léptetünk
szamlalo--;
if(szamlalo)return;
szamlalo=5;
for(int i=0;i<25;i++)
{
LPSP mut=&sp[i];
mut->SP_AN++; //+1
if(mut->SP_AN==mut->SP_ANMAX)mut->SP_AN=0;//ha elérte a maxot akkor 0
mut->SP_KEP_Y=mut->SP_AN*49;//jelen esetben a bmp rajzon egymás alatt vannak
//tehát y koordináta egy rajzzal lejjebb ugrik

}
}

Most már csak használni kell, a  SPRITE::frissit() függvényébe kell beírni:

void SPRITE::frissit()
{
rajz.rajzol(0,0,0,800,600,-1,0,0);//háttér
sp_rajz();
rajz.flip();
anim();
}

fordít- futtat. Ha nem gépeltünk el ketten semmit, akkor mennie kell!
Ha nem,  itt a forrás:
Következik a mozgatás függvény és az ütközés függvény.

Vissza