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

Pretender:    2498
szeki:    2440
Seeting:    2306
Geri:    2188
Orphy:    1893
Joga:    1791
Bacce:    1783
MaNiAc:    1735
ddbwo:    1625
syam:    1491
(C++) Foxi 2D-s programozás leckéi 2. - Directdraw 2006.12.29 04:34


Directdraw I.

Az első lecke a saját képernyő volt. Most megpróbálunk a windows-tól kikunyerálni egy teljes képernyős ablakot. Ehhez létrehozunk egy új fájl-t, egy új osztállyal. A lényeg a játékokban, hogy a bábuk mindig mozognak a képernyőn, és ehhez mindig újra kell rajzolni őket. Ebből következik, hogy miközben a vidikártya bőszen rajzolja a monitorra a képet, közben a mi progink meg a saját bábuját a vidikártyára, hát ebből lesz a kép villodzása, feldarabolódása....

Ennek lekerülésére kell egy directx felületet létrehozni, és mindjárt két képernyőnek kell helyet foglalni. Az első amit látunk, és egy hátsó amire rajzolunk... Ha minden rajzolással készen vagyunk, akkor egy váltás, és máris rajzolhatunk a másik képernyőre. Ezzel ki van lőve a képernyő villogása, feldarabolódása. A projecthez adjál egy új fáljt, méghozzá a Header mappába. A neve legyen Rajz.hpp. A hpp kiterjesztés előnye hogy nem kell külön .h és .cpp fájl.

DEVC++ nál:msvc6.0:

Az új fájl-ban hozzuk létre az osztályunkat....

//RAJZ OSZTÁLY
//

#ifndef _RAJZ_ //ujabb definíció és fordítási hiba elkerülésére
#define _RAJZ_

#include <ddraw.h>

//dekralációk:
class RAJZ //osztály neve
{
    public: //public szó alatti függvények- változók kívülről láthatóak
        RAJZ(); //konstruktor dekralálása
        ~RAJZ(); //destruktor
    protected: //protected alattiakat csak az osztály láthatja és még az utód osztályok
        LPDIRECTDRAW7 obj; //objektum mutató
        LPDIRECTDRAWSURFACE7 front; //elsőképernyőre mutató pointer
        LPDIRECTDRAWSURFACE7 back; //hátsóképernyőre mutató pointer
        LPDIRECTDRAWCLIPPER cl; //klipper objektum

};
#endif

Nos akinek idegen egy osztály, annak idegen a konstruktor és destruktor fogalma is. A lényege: ha az osztályt statikusan hozzuk létre, akkor az exe betöltődésekor, ha dinamikusan, akkor a memória foglalásakor meghívódik a konstruktor..... Felfogható az osztály inicializáló függvényének, azaz meghívhat más függvényeket, lefoglalhat újabb dinamikus változókat, mindent, amit csak akarunk, vagy éppen semmit sem. A destruktor akkor aktivizálódik, amikor megszűnik az osztályunk, de ott nekünk kell gondoskodni a dinamikus helyfoglalás felszabadításáról....

A dekralációban tulajdonképpen helyet foglalunk a directdraw7 típusú mutatóknak, amelyek sorra megkapják az értéküket a különböző függvényhívások után: Kell egy directdraw objektum, amin keresztül létrehozhatjuk az első és hátsó képernyő felületeket, valamint egy klipper objektumot, ez utóbbi arra kell, hogyha egy képet szeretnénk átrajzolni a háttérre, akkor ha csak egy pixellel is kilóg, akkor már nem rajzolja ki a Blt(...) függvény. A vágóobjektum nélkül.

Nos a directx felülethez kell az ablakunk hwnd típusú változója, de ez ugye egy másik fájl-ban a main.cpp -ben van. Ha már egyszer dekraláltuk, akkor itt is egyszerűen használhatjuk, csak mondjuk meg a fordítónak, hogy ez egy külső változó (majd megkeresi a helyét) tehát valahova a #define _RAJZ_ alá kell beírni:

extern HWND hwnd;

Csapjunk bele!

Hozzunk létre egy init() függvényt a rajz osztályban:
dekralációkhoz: bool init();
Az #endif utasítás előtt építjük ki a megvalósítását a függvényeinknek:

//MEGVALÓSÍTÁSOK:

Elsőnek a konstruktor, destruktor,majd az init függvény:

//Megvalósítások:
RAJZ::RAJZ() //A konstruktor neve maga az osztálynév nem adhat vissza értéket,
{ //tehát tipusa sem lehet itt csak egy üres konstruktor van egyelőre
}
//
RAJZ::~RAJZ() //destruktor egyelőre ez is üres.
{
}
//
bool RAJZ::init()    // a RAJZ:: -tal jelöljük hogy az osztály függvénye és nem globális
{
    HRESULT hr; //egy visszajelzés,hogy sikerült-e a függvényt végrehajtani
    hr = DirectDrawCreateEx( NULL, (VOID**)&obj,IID_IDirectDraw7, NULL );//átadjuk a mutatót
    //a directdraw objektum létrehozásához

    if(hr!=DD_OK) return false;
    hr = obj->SetCooperativeLevel( hwnd, DDSCL_EXCLUSIVE|DDSCL_FULLSCREEN );//együttműködési szint
    //teljes képernyő kell

    if(hr!=DD_OK) return false;
    hr=obj->SetDisplayMode( 800, 600, 32,75,0);//képernyő felbontás,színmélység,frekvencia.
    if(hr!=DD_OK) return false;
    DDSURFACEDESC2 ddsd;//struktúra helyfoglalása
    ZeroMemory( &ddsd, sizeof( ddsd ) );//adatok kitöltése
    ddsd.dwSize = sizeof( ddsd );
    ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT;
    ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP |DDSCAPS_COMPLEX ;
    ddsd.dwBackBufferCount = 1;//1 db háttérfelület kell
    hr = obj->CreateSurface( &ddsd, &front,NULL );//létrehozzuk a felületet
    if(hr!=DD_OK) return false;
    DDSCAPS2 ddscaps;
    ZeroMemory( &ddscaps, sizeof( ddscaps ) );
    ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
    hr = front->GetAttachedSurface( &ddscaps,&back );//lekérdezzük a hátsóképernyő címét
    if(hr!=DD_OK) return false;
    hr = obj->CreateClipper( 0, &cl, NULL );//klipper objektum létrehozása
    cl->SetHWnd( 0, hwnd );
    hr = back->SetClipper(cl);//és hozzárendelése a háttérhez.
    UpdateWindow(hwnd); //ablakfrissítés

    return true;//ha eddig elér a progi,akkor van dx felületünk.

}

Nos azért írtam hogy ha eddig elér a progi mert ezzel a függvénnyel szokott probléma lenni:SetDisplayMode( 800, 600, 32,75,0)Vagy a videokártya vagy a monitor nem bírja,akkor állítgatni kell.felbontás pl 640x 480 színmélység 16 , 8 frekvencia 50 60 75 100 Hertz vagy NULL ekkor a monitor alapfrekvenciája lesz a mérvadó.

Menjél a Main.cpp-be, és add hozzá a Rajz.hpp-t a fájl-hoz:

#include <Rajz.hpp>

fordítás....

Hibaüzenet elhárítása:

DEVC++


msvc


Marad a ddraw.h és a ddraw.lib hozzáadása:

DEVC++:


MSVC:


Ha sikerültek a beállítások,akkor a main cpp-ben hozzuk létre az új statikus osztályt:

RAJZ rajz;

Használni pedig az egyes tagfüggvényeket a . operátorral lehet:
Irjad be a ShowWindow(hwnd,nFunsterStil); után hogy:

if(rajz.init())MessageBox(NULL,"directdraw nem oké","",0);;


fordít futtat.

Ha lett egy teljesképernyős szürke képed, akkor minden oké. Azonban nem frissül, de ezt a következőben...

itt a kod:

Ha nem lenne meg a ddraw.h és ddraw.lib itt letölthetitek.


Directdraw II.

Most, hogy van direcx felületünk, de még nem látszik, nekifoghatunk az osztály fejlesztéséhez. Mindenek előtt azonban kell egy struktúrát létrehozni, aminek 3 tagja lesz: LPDIRECTDRAWSURFACE7 tipusú mutató a betöltött kép memória címének, egy int sor és egy int oszlop változónak, hogy eltárolja a betöltött kép szélességét és magasságát.

Tehát a rajz.hpp-ben valahol a dekralációk felett írd be:

typedef struct
{
    LPDIRECTDRAWSURFACE7 kep; //a memóriára mutató pointer
    int sor; //betöltött kép magassága (pixelekben)
    int oszlop; //szélesség pixelekben
}KEP,*LPKEP;

Azért előnyös a typedef, mert létrejön egy új típus a KEP és egy ilyen típusú pointer is. Ezt a struktúrát később fogjuk használni. Most létrehozunk a védett tagváltozók között egy ilyen KÉP tipusú tömböt:

KEP kepek[10]; //várhatóan ennyi képfelület elég lesz.

Azért kell ezzel kezdeni, mert a destruktorban törölni szeretnénk minden általunk létrehozott objektumot. (Szerintem amikor bezáródik az ablakunk, akkor a Win automatice felszabadítja a memóriákat de ha nem??? elfogynak az erőforrások)

Megírjuk a képek és a ddraw objektum törlését, pedig még nem is tudjuk mennyi kép lesz!

dekraláció:

void torles();

megvalósítás:

//
void RAJZ::torles()
{
    for(int i=0;i<10;i++) //elsőnek a képfelületeket törüljük
    {
        if(kepek[i].kep){ kepek[i].kep->Release();kepek[i].kep=NULL;}
    }
    obj->Release();obj=NULL;// és magát at ddraw objektumot
}

(Fontos! Ha egy mutató "mögötti" adatállományt törlünk, akkor az értékét is NULLázzuk ki, mert legközelebb egy egyszerű vizsgálattal eldönthető, hogy van e mögötte érvényes objektum. Statikus mutatóknál a fordító "garantálja" a 0-val való feltöltést, de utána nekünk illik kézben tartani.)

Ezt a függvényt be kell írni a destruktorba: torles(); Ha nem volt ennyi kép akkor sincs baj.

Nem beszéltem még a képernyő váltásáról, pedig ez fontos dolog lesz. Csak egy függvényt kell meghívni, mégpedig a flip() nevűt, dekraláljuk: void flip();

Megvalósítása:

//KÉPERNYŐVÁLTÁS
void RAJZ::flip()
{
    BOOL inf=front->Flip(NULL,0);
}

Használni pedig a Main .cpp-ben a végtelen ciklusban kell:

while (fut)
{
    uzenetkezelo();
    rajz.flip();

}

Fordít futtat... Az eredmény egy villódzó képrenyő, pedig mi nem ezt akarjuk... Valójában pont ez kell nekünk, mert a megadott ütemben (képernyő frekvencia) váltogatva van a képernyő. Csakhogy az első szép szürke a hátsó pedig fekete.Gyorsan írunk is egy háttérszinező függvényt.

Vissza a Rajz.hpp hez.

dekraláció:
void hatter (DWORD szin=0);//ha így dekralálod,akkor "üres meghívás esetén 0 lesz a bemenő adat

megvalósítás:

// HÁTTÉRSZIN
void RAJZ::hatter(DWORD szin)
{
    DDBLTFX dfx;ZeroMemory(&dfx,sizeof(dfx));
    dfx.dwSize=sizeof(dfx);dfx.dwFillColor=szin;
    back->Blt(NULL,NULL,NULL,DDBLT_COLORFILL,&dfx);
    front->Flip(NULL,0);back->Blt(NULL,NULL,NULL,DDBLT_COLORFILL,&dfx);

}

Tulajdonképpen a háttérfelülethez tartozó Blt(...) függvényét hívja meg, előtte kitölt egy struktúrát. Használni az init függvény végén célszerű, de bárhol, bármikor meghívható.

Szúrjad be az init() függvény végére:

    UpdateWindow(hwnd); //ablakfrissítés
    hatter(0x00000080);
    return true;//ha eddig elér a progi,akkor van dx felületünk.

A színfelállás a következő: 00 rr gg bb azaz piros zöld kék tehát a 0x00000080 közepes kéket jelent.

Ha csak a 16 bites színt sikerült volna inicializáni, akkor 5 bit piros 6bit zöld és 5 bit kék a szín. Fordít futtat. Most már igazán egyszínű középkék képernyőnek kell lennie. Vibrálás nélkül. A program fejlesztése közben jó lenne ha ki tudnánk írni számokat és szövegeket a képernyő felületére. Legyen a két függvény neve kiirszam és kiirbetu.

Dekraláció:

void kiirbetu(LPCTSTR betu,int x,int y);//sztringre mutató pointer és pozíció
void kiirszam(int szam,int x, int y);//szám és pozíció

Megvalósítás:

void RAJZ::kiirbetu(LPCTSTR betu,int x,int y)
{

    char buffer[64];HDC hdc;
    back->GetDC(&hdc);sprintf(buffer,betu); //lekérdezzük a háttérfelület címét
    SetTextColor(hdc,0x00ff40ff);//RGB(64,64,255)
    //SetBkColor(hdc,0x000000ff); //00bbggrr háttérszin

    SetBkMode(hdc,TRANSPARENT);//OPAQUE
    TextOut(hdc,x,y,buffer,strlen(buffer)); //strlen függvény megállapítja a sztring hosszát
    back->ReleaseDC(hdc);//ha már nem kell megszüntetjük
}
/**/
void RAJZ::kiirszam(int szam,int x,int y)
{
char bufer[20];

itoa(szam,bufer,10);
kiirbetu(bufer,x,y);

Azonban hogy a strlen() és az itoa() függvényeket használjuk, csatolni kell a stdio.h állományt. Fennt:

#include <stdio.h>

A két függvény használata legegyszerűbben a flip függvényben lehet:

void RAJZ::flip()
{
    kiirbetu("első szövegem",100,100);
    kiirszam(0x00ff00ff,100,120);
    BOOL inf=front->Flip(NULL,0);

    ......


Fordít futtat. Ha minden oké, akkor megjelenik a felirat és a szöveg.

Jó tudni! A flip() függvény meghívása addig várakoztatja a programot, amíg a monitor nem végez a rajzolással, tehát 75Hz-nél 1/75 másodpercenként ez egy jól használható időzítő is lehet. Azonban később más időzítőket is használunk.

itt a kód:


Directdraw III.

Ebben a leckében létrehozzuk az un. képernyőn kívüli felületeket, és betöltjük a bmp képeket sorra a memóriába. Én szoktam csinálni egy atom nevű bmp-t, mert oda teszek minden sprite képet, amolyan elemi részeknek gondolom. Egy másik kép pedig lehet maga a pálya egy harmadik pl grafikus számok betűk stb..

Most csak egy háttér és egy sprite-os képet fogunk betölteni.

Ha a betöltés megtörtént, akkor a folyamat úgy zajlik, hogy átlapoljuk az egész háttérképet a hátsó képernyő felületére, ezzel minden sprite-ot letöröltünk. Majd szépen egyesével felrajzoljuk a sprite-okat az új pozícióban. Ha minden rajzolással készen vagyunk, akkor jön a flip() függvény és kezdjük elölről. Régebbi lassabb gépeken azt a megoldást kell választani, hogy csak a sprite régi helyén állítjuk vissza a hátteret, és úgy rajzoljuk ki az új helyre őket. Ezzel kb fél képernyőnyi újrarajzolást meg lehet spórolni.... De a mai világ a sebességé.

A felmerülő probléma hogy egy sprite ritkán téglalap alakú, pedig átlapolni csak téglalapokat lehet. A megoldás, hogy a haszontalan területet egy átlátszó színnel kell feltölteni, aminek az értékét megadhatjuk. A load függvényt kettéválasztottam, mégpedig azért, mert elveszhetnek a képernyő felületek, és akkor a helyreállításra újból be kell tölteni a képet. Ezért lesz úgy megírva, hogy melyik képet hova, és lesz egy olyan függvény, ami mindet betölti. Tehát dekraláció:

protected:

    void load_init(int melyiket=-1,int hova= 0); //üresen meghívva =inicializálja az összeset
    bool loadbmp(LPCTSTR nev,int hova); //ez tölti be a képet
    DWORD szinkulcs; //az átlátszó szín tárolására

megvalósítás:

Konstruktorban inicializáljuk a színkulcs értékét:
színkulcs=0x00ff00ff;//lila szín.

Hozz létre a projectben egy új mappát map néven és ide tegyél egy 800x600-as háttérképet h8.bmp néven valamint a csatolt fájl-ból (lásd lent) az atom.bmp képet.

Megvalósítás:

/**/
void RAJZ::load_init(int melyiket,int hova)
{
    int i=0,hossz;
    LPCTSTR nevek[]={"map\h8.bmp","map\atom.bmp",""}; //itt tároljuk a neveket,utoljára egy üres sztring
    if (melyiket ==-1)
    {
        while(1)
        {
            hossz= strlen( nevek[i]);//lekérdezzük a sztring hosszát
            if(hossz==0)break; //ha nincs vagy üres asztring vége
            hova=i;
            loadbmp( nevek[i],hova);
            i++;
        }
        return;
    }
    else
    {
        hossz= strlen( nevek[melyiket]);
        if(hossz==0)return;
        loadbmp( nevek[melyiket],hova);
    }

}
//
//

bool RAJZ::loadbmp(LPCTSTR nev,int i)
{


    if(kepek[i].kep) //volt e mér brtöltve kép?
    {
        kepek[i].kep->Release();kepek[i].kep=NULL; //Ha volt már betöltve töröljük
    }
    HRESULT hRet; //info a függvény lefutásáról
    DDSURFACEDESC2 ddsd;
    DWORD* lPSurface=NULL;
    int lPitch=0;
    FILE *fp;
    DWORD szine=0,size=0;
    unsigned long width,height,lineend;
    short type;/*,lineend*/;
    unsigned char *sor;
    fp=fopen(nev,"rb"); //megnyitjuk olvasásra
    if(fp==NULL)
    {
        MessageBox(NULL,"nem jó név vagy elérési út","",0); return false;
    }
    fread(&type, sizeof(short), 1, fp);//a file nem 0x4d42 vel kezdődik,akkor nem bmp
    if (type != 0x4D42)
    {
        fclose(fp);
        return false;
    }
    fread(&size,sizeof(DWORD),1,fp);//fájl mérete
    fseek(fp, 18, SEEK_SET); //18.byte-on van a szélesség magasság adat
    fread(&width, sizeof(long), 1,fp);
    fread(&height, sizeof(long), 1,fp);
    lineend=(size-54-(width*height*3))/height;//hossz-fejléc * 3 szin a végr
    ZeroMemory(&ddsd,sizeof(ddsd));//mivel tudjuk az adatokat létre lehet hozni a felületet
    ddsd.dwSize = sizeof(ddsd);
    ddsd.dwFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT;
    ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_VIDEOMEMORY;
    ddsd.dwWidth =width;
    ddsd.dwHeight =height;
    ddsd.ddpfPixelFormat.dwSize = sizeof(ddsd.ddpfPixelFormat);
    ddsd.ddpfPixelFormat.dwFlags = DDPF_RGB;
    ddsd.ddpfPixelFormat.dwRGBBitCount = 32;
    ddsd.ddpfPixelFormat.dwRBitMask = 0x00ff0000;
    ddsd.ddpfPixelFormat.dwGBitMask = 0x0000ff00;
    ddsd.ddpfPixelFormat.dwBBitMask = 0x000000ff;
    ddsd.ddpfPixelFormat.dwRGBAlphaBitMask = 0x00000000;
    hRet = obj->CreateSurface(&ddsd, &kepek[i].kep, NULL); //előállítjuk a felületet
    if (hRet != DD_OK) //a video memóriában
    {
        ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
        hRet = obj->CreateSurface(&ddsd, &kepek[i].kep, NULL); //ha nincs hely,akkor a rendszerben
    }
    if (hRet != DD_OK)
        return false;
    DDCOLORKEY ddck;
    ddck.dwColorSpaceLowValue = szinkulcs;//hozzárendeljük a felülethez at átlátszó színt
    ddck.dwColorSpaceHighValue = szinkulcs;
    kepek[i].kep->SetColorKey( DDCKEY_SRCBLT, &ddck );
    ZeroMemory(&ddsd,sizeof(ddsd));
    ddsd.dwSize=sizeof(ddsd);
    if ((kepek[i].kep->Lock(NULL, &ddsd, DDLOCK_WAIT, NULL)) != DD_OK)//zároljuk az adatfeltöltéshez
        //a Lock() függvény egyben visszaadja felület memóriacímét a lpSurface adattagban

        MessageBox(hwnd, "Failed to lock the surface", "Surface Error", MB_OK);
    lPitch = (int)ddsd.lPitch;
    lPSurface = (DWORD*)ddsd.lpSurface; //felület memóriája
    fseek(fp,54,SEEK_SET); //ráállunk az adatok elejére
    for(int k=height-1; k>=0; k--)
    {

        sor=(unsigned char*)calloc(3*width,sizeof(unsigned char));//helyfoglalás egy sornyi adatnak
        fread(sor,width*3*sizeof(char),1,fp);//belvasunk szélesség*3 byte-ot
        for(unsigned long i=0; i<width; i++) //
        {
            szine=(*(sor+i*3+2)<<16)|(*(sor+i*3+1)<<8)|(*(sor+i*3));//átkonvertáljuk DWORD-é
            lPSurface[i+k*(lPitch>>2)]=szine;
        }
        free(sor);
        if(!feof(fp)) fseek(fp,lineend,SEEK_CUR); //sorvége átlépése
    }
    fclose(fp); //file lezárása
    kepek[i].kep->Unlock(NULL); //képfelület felszabadítása
    kepek[i].oszlop= width; //eltesszük a szélességet,és a magasságot hátha még kell.
    kepek[i].sor= height;
    return true;
}

Elég hosszúra sikerült, de kommentezve van. Gyakorlatilag addig olvas a sztringek között, amíg egy üreset be nem olvas. Csak arra kell figyelni, hogy a dekralációban több legyen a képek száma, mint amennyit betöltünk ( KEP kepek[10]; ) Ha elfogy a videomemória beteszi a rendszermemóriába.

Hova is tennénk a load függvényünekt, mint az init végére!

    .....

    UpdateWindow(hwnd); //ablakfrissítés
    hatter(0x00000080);
    load_init();// mivel nincs bemenő adat mindet betölti.
    return true;//ha eddig elér a progi,akkor van dx felületünk.

Most jön az egész RAJZ osztály legfőbb függvénye a rajzoló függvény. A bemenő paraméterek magukért beszélnek. Dekraláció:

void rajzol(int forrasfelulet,int forrasx,int forrasy,int forrassz,int forrasm, int celfelulet,int celx,int cely);

Azaz megadod melyik betöltött képfelületről akarsz rajzolni, ott kijelölöd a téglalapot, majd megadod a célfelületet. Ez lehet első képernyő, hátső képernyő, és akármelyik betöltött képfelület. Tehát képet másolhatsz a képre (akár). Azonban, ha a célfelület = -1 akkor a háttérre rajzol. Megvalósítás:

void RAJZ::rajzol(int fsurf,int fx,int fy,int fsz,int fm,int csurf,int cx,int cy)
{
    HRESULT hr;LPDIRECTDRAWSURFACE7 mut;
    if(csurf==-1) mut=back;
    else mut=kepek[csurf].kep;RECT f,c;
    f.top=fy;f.left=fx;f.right=fx+fsz;f.bottom=fy+fm;
    c.top=cy;c.left=cx;c.right=cx+fsz;c.bottom=cy+fm;
    hr=mut->Blt(&c,kepek[fsurf].kep,&f,DDBLT_KEYSRC | DDBLT_WAIT,0);
}

2db RECT tipusú struktúrát kell kitölteni, a bemenő adatokból számítjuk ki, utána átadjuk a Blt() függvénynek.

használata:

A legegyszerűbben most a flip() függvénybe tesszük, mert mielőtt lapozunk, előtte rajzolunk. Később más osztályból fogunk rajzolni. Elsőnek a hátteret, majd egy sprite-ot, ami egy golyó.

    .......

    rajzol(0,0,0,800,600,-1,0,0);//a 0-dik képfelületről 800x600 pixelt
    rajzol(1,0,0,18,18,-1,400,300);//az 1.képfelületről 18x18 pixelt
    kiirbetu("első szövegem",100,100);
    kiirszam(0x00ff00ff,100,120);

fordít futtat. Most vége van a rajz osztályunknak, jöhetnek a sprite-ok. A sprite-ok -nak nevezzük a képernyőn lévő mozgó bábukat, tárgyakat, amik aktívak, azaz elmozdulnak.

Ez lesz a következő osztály.

Jó tudni! VC6.0 debug mappában csak úgy futtatható az .exe ha odamásolod a map nevű mappát.

itt a kód:

foxi


Kapcsolódó linkek:

A cikksorozat további részei:

Értékelés: 5.00

Új hozzászólás
analyser          2009.03.11 09:40
Köszönöm azok nevében is, akik előttem s utánam járnak majd itt.

analyser
doggministah          2007.03.29 13:24
Nekem nem tudja megnyitni a Rajz.hpp-t fordításkor. Ezt írja ki: Cannot compile the file '...Rajz,hpp'; no compile tool is associated with the file extension. ..Ez miért van, meg tudja mondani valaki??
Csaba42          2007.01.03 06:34
Jó ez, igaz, volt már elődje, így újat nem tudott mutatni. Megnéztem a honlapod, ott viszont találtam kedvemre valót (pl.: Joystick-kezelés). Remélem, mihamarabb elkészül a DD3-as cikk is, és a végén egy egyszerű DD-s játék elkészítését is cikkbe fogod öntenI!