mit directdraw tiles zeichnen
-
Hallo c++ community
ich hab folgendes problem, hab bis jetzt mit direct draw figuren animiert und gesteuert, das funktioniert alles tadellos. Jezt möchte ich die figuren gerne in eine Welt zeichnen, das heißt ein haufen tiles als boden. Leider hängt sich mein compiler immer auf. hab das welt zeichnen jezt ohne figuren probiert. das funzt auch nicht. Kann mir jemand Helfen?
Hier der Programm-Code//--------------------------------------------------------------------------- #include <vcl.h> #include <ddraw.h> #include <string.h> #include <stdio.h> #include <fstream.h> #include "ddutil.h" #pragma hdrstop #pragma resource "*.dfm" #include "cpp_editor.h" //--------------------------------------------------------------------------- #pragma package(smart_init) #pragma link "frame_unit1" #pragma link "aufloesung" #pragma link "menu_frame" #pragma resource "*.dfm" TForm1 *Form1; //DirectDraw LPDIRECTDRAW ddobjekt; // DirectDraw object LPDIRECTDRAWSURFACE ps; // DirectDraw primary surface LPDIRECTDRAWSURFACE bs; // DirectDraw back surface LPDIRECTDRAWCLIPPER clipper; BOOL active; // is application active? BYTE phase; //Variablen int maxheight=10; int maxwidth=10; int wheight=800; int wwidth=600; int xstart=0, ystart=0; int wtile,htile; int oldItemIndex; HWND Handleform; //Strukturen typedef struct { bool walkable; int IL; int imagenr; }kachel; kachel tile[100][100]; //Funktionen //Kleinigkeiten int getxinpix(int y, int x, int TILE_W); //Files bool existfile(AnsiString file); void loadtiles(TImageList *liste, AnsiString path,AnsiString art); void loadingbitmap(TImageList *liste, AnsiString datei,int transparentcolor); void CreateTile(kachel* tile); //DirectDraw void InitDD(HWND Handle, LPDIRECTDRAW ddobjekt, LPDIRECTDRAWSURFACE ps, LPDIRECTDRAWSURFACE bs, LPDIRECTDRAWCLIPPER clipper, BOOL active, int wheight, int wwidth); void dddrawing(LPDIRECTDRAWSURFACE ps, LPDIRECTDRAWSURFACE bs, int wheight, int wwidth); void ClearSurface( LPDIRECTDRAWSURFACE surface); void AddColorKey (LPDIRECTDRAWSURFACE surface, DWORD Low, DWORD High); void drawtile(LPDIRECTDRAW ddobjekt,LPDIRECTDRAWSURFACE surface, TImageList *list, kachel *tile, int x, int y, int xoffset, int yoffset); void EndDD(LPDIRECTDRAW ddobjekt, LPDIRECTDRAWSURFACE ps, LPDIRECTDRAWSURFACE bs, LPDIRECTDRAWCLIPPER clipper, bool active); //Grpahics Graphics::TBitmap* getbmpfromimagelist(TImageList *List, int index); //----------------------------------------------------------------------- bool existfile(AnsiString file) { FILE *f= fopen (file.c_str(),"r"); if (!f) return false; else { fclose(f); return true; } } //------------------------------------------------------------------- void loadingbitmap(TImageList *liste, AnsiString datei,int transparentcolor) { Graphics::TBitmap *srcbmp= new Graphics::TBitmap; Graphics::TBitmap *bmp= new Graphics::TBitmap; RECT rect; rect.left=0; rect.right=liste->Width; rect.top=0; rect.bottom=liste->Height; srcbmp->LoadFromFile(datei); bmp->Width=liste->Width; bmp->Height=liste->Height; bmp->Canvas->StretchDraw(rect,srcbmp); liste->AddMasked(bmp,transparentcolor); liste->Masked=true; } //-------------------------------------------------------------------------- void loadtiles( TImageList *liste,AnsiString path, AnsiString art) { AnsiString z_str,e_str,h_str,file; int zehner=0,einser=1,hunderter=0; while(1) {einser=1; zehner=0;hunderter=0; if(einser>9) { einser=0; zehner++; } if(zehner>9) { zehner=0; hunderter++; } h_str=IntToStr(hunderter); z_str=IntToStr(zehner); e_str=IntToStr(einser); file="graphic//isotiles//" + art + "_" + h_str +z_str + e_str+".bmp"; if(existfile(file)== true) { loadingbitmap(liste,file,clBlack); } else { break; } } } //--------------------------------------------------------------------------- __fastcall TForm1::TForm1(TComponent* Owner) : TForm(Owner) { } //--------------------------------------------------------------------------- void __fastcall TForm1::Frame11Button1Click(TObject *Sender) { maxheight=StrToInt(Frame11->Edit2->Text); maxwidth=StrToInt(Frame11->Edit1->Text); Frame11->Visible=false; /*for(int y=1;y<=maxheight;y++) { for(int x=1;x<=maxwidth;x++) { tile[x][y] = new(kachel); tile[x][y]->imagenr = 0; tile[x][y]->IL=0; } } */ for(int y=1;y<=maxheight;y++) { for(int x=1;x<=maxwidth;x++) { CreateTile(&tile[x][y]); } } //ResetTiles(); //InitDD(Handleform,ddobjekt,ps,bs,clipper,active,wheight,wwidth); Initdd(); MainLoop(); } //--------------------------------------------------------------------------- void InitDD(HWND Handle,LPDIRECTDRAW ddobjekt, LPDIRECTDRAWSURFACE ps, LPDIRECTDRAWSURFACE bs, LPDIRECTDRAWCLIPPER clipper, BOOL active, int wheight, int wwidth) { struct { RGNDATAHEADER rdh; RECT rgndata[1]; } cliplist; cliplist.rdh.dwSize = sizeof (RGNDATAHEADER); cliplist.rdh.iType = RDH_RECTANGLES; cliplist.rdh.nCount = 1; cliplist.rdh.nRgnSize = 0; cliplist.rdh.rcBound.left = 0; cliplist.rdh.rcBound.top = 0; cliplist.rdh.rcBound.right = wheight; cliplist.rdh.rcBound.bottom = wwidth; cliplist.rgndata[0].left = 0; cliplist.rgndata[0].top = 0; cliplist.rgndata[0].right = wheight; cliplist.rgndata[0].bottom = wwidth; HRESULT result; DDSURFACEDESC ddsd; DDSCAPS ddscaps; HDC DC; char buf[256]; result = DirectDrawCreate(NULL, &ddobjekt, NULL); if(result == DD_OK) { // Get exclusive mode result = ddobjekt->SetCooperativeLevel(Handle, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if(result == DD_OK) { result = ddobjekt->SetDisplayMode(wheight, wwidth, 16); if(result == DD_OK) { // Create the primary surface with 1 back buffer ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd.dwBackBufferCount = 1; result = ddobjekt->CreateSurface(&ddsd, &ps, NULL); if(result == DD_OK) { // Get a pointer to the back buffer ddscaps.dwCaps = DDSCAPS_BACKBUFFER; result = ps->GetAttachedSurface(&ddscaps, &bs); //Clipper erstellen if(result == DD_OK) { result = ddobjekt->CreateClipper(0, &clipper, NULL); if (result != DD_OK) { bs->Release(); bs = NULL; ps->Release(); ps = NULL; ddobjekt->Release(); ddobjekt = NULL; wsprintf(buf, "Clipper init failed (%08lx)\n", result); MessageBox(Handle, buf, "ERROR", MB_OK); Form1->Close(); } result = clipper->SetClipList ((LPRGNDATA) &cliplist, 0); if (result != DD_OK) { clipper->Release(); clipper = NULL; bs->Release(); bs = NULL; ps->Release(); ps = NULL; ddobjekt->Release(); ddobjekt = NULL; wsprintf(buf, "SetClipList init failed (%08lx)\n", result); MessageBox(Handle, buf, "ERROR", MB_OK); Form1->Close(); } //Clipper an bs hängen result = bs->SetClipper(clipper); if (result != DD_OK) { clipper->Release(); clipper = NULL; bs->Release(); bs = NULL; ps->Release(); ps = NULL; ddobjekt->Release(); ddobjekt = NULL; wsprintf(buf, "SetClipList init failed (%08lx)\n", result); MessageBox(Handle, buf, "ERROR", MB_OK); Form1->Close(); } ShowCursor(true); //loadingbitmap(ImageList1,"C:\\Users\\Frank\\Pictures\\spielbilder\\bmps\\Skelett\\Achtung\\Frame_0001.bmp",0x007F858C); active = True; return; } } } } } wsprintf(buf, "Direct Draw Init Failed (%08lx)\n", result); MessageBox(Handle, buf, "ERROR", MB_OK); Form1->Close(); } //------------------------------------------------------------------- void __fastcall TForm1::FormCreate(TObject *Sender) { Handleform=Handle; //il_gras->Draw(Image1->Canvas,0,0,0,true); Frame21->Visible=false; xstart=0; ystart=0; for(int y=1;y<=maxheight;y++) { for(int x=1;x<=maxwidth;x++) { CreateTile(&tile[x][y]); } } //ResetTiles(); //InitDD(Handleform,ddobjekt,ps,bs,clipper,active,wheight,wwidth); Initdd(); MainLoop(); //ResetTiles(); } //--------------------------------------------------------------------------- void __fastcall TForm1::FormDestroy(TObject *Sender) { if(ddobjekt != NULL) { if(ps != NULL) { if(clipper!=NULL) { clipper->Release(); clipper = NULL; } ps->Release(); ps = NULL; } ddobjekt->Release(); ddobjekt = NULL; } } //--------------------------------------------------------------------------- void __fastcall TForm1::FormKeyDown(TObject *Sender, WORD &Key, TShiftState Shift) { switch(Key) { case VK_ESCAPE: //EndDD(ddobjekt,ps,bs,clipper,active); Close(); break; } } //--------------------------------------------------------------------------- void dddrawing(LPDIRECTDRAWSURFACE ps, LPDIRECTDRAWSURFACE bs,int wheight, int wwidth) { HDC DC; HRESULT result; while(1) { result = ps->Flip(NULL, 0); if(result == DD_OK) break; if(result == DDERR_SURFACELOST) { result = ps->Restore(); if(result != DD_OK) break; } if(result != DDERR_WASSTILLDRAWING) break; } } //--------------------------------------------------------------------------- Graphics::TBitmap* getbmpfromimagelist(TImageList *List, int index) {Graphics::TBitmap *bmp; bmp=new Graphics::TBitmap; bmp->Width=List->Width; bmp->Height=List->Height; List->Draw(bmp->Canvas,0,0,index,true); return bmp; } //---------------------------------------------------------------- void drawtile(LPDIRECTDRAW ddobjekt,LPDIRECTDRAWSURFACE surface, TImageList *list,kachel *tile, int x, int y, int xoffset, int yoffset) { HRESULT result; LPDIRECTDRAWSURFACE zwischen; LPDDCOLORKEY ColorKey; RECT rectbitmap; char buf[256]; Graphics::TBitmap *bmp; bmp=new Graphics::TBitmap; DDSURFACEDESC ddsd; BITMAP bm; int pixx, pixy; bmp=getbmpfromimagelist(list,tile->imagenr); pixy= (y-1) * bmp->Height/2 - yoffset; pixx=getxinpix(y,x,bmp->Width); // get size of the bitmap GetObject(bmp->Handle, sizeof(bm), &bm); /* DONE : Bild wird auf gesamte surface kopiert, als nächstes muss das bild auf einen kleinen teil der surface kopiert werden */ //BitmapSurface erstellen ZeroMemory(&ddsd, sizeof(ddsd)); ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT |DDSD_WIDTH; ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN; ddsd.dwWidth = bm.bmWidth; ddsd.dwHeight = bm.bmHeight; if (ddobjekt->CreateSurface(&ddsd,&zwischen,NULL) == DD_OK) { AddColorKey(zwischen,clWhite,clWhite); result=DDCopyBitmap(zwischen,bmp->Handle,0,0,bmp->Width,bmp->Height); SetRect(&rectbitmap,pixx,pixy,pixx + bmp->Width, pixy +bmp->Height); surface->Blt(&rectbitmap,zwischen,NULL,DDBLT_WAIT| DDBLT_KEYSRC,NULL); } else { wsprintf(buf, "DrawWorld Fehler (%08lx)\n", result); MessageBox(Form1->Handle, buf, "ERROR", MB_OK); Form1->Close(); } zwischen->Release(); bmp->Free(); } //------------------------------------------------------------ void AddColorKey (LPDIRECTDRAWSURFACE surface, DWORD Low, DWORD High) { /* Low Value für transparente farbe, high = low solange nicht eine range von farben ausgeblendet werden soll */ DDCOLORKEY key; ZeroMemory(&key, sizeof(key)); key.dwColorSpaceLowValue = Low; key.dwColorSpaceHighValue = High; surface->SetColorKey (DDCKEY_SRCBLT, &key); } //------------------------------------------------------- void ClearSurface(LPDIRECTDRAWSURFACE surface) { DDBLTFX ddbltfx; RECT fill_area; ddbltfx.dwSize = sizeof(DDBLTFX); ddbltfx.dwFillColor = RGB(0, 0, 0); SetRect(&fill_area, 0, 0, wheight, wwidth); surface->Blt(&fill_area, NULL, NULL, DDBLT_COLORFILL|DDBLT_WAIT, &ddbltfx); } //----------------------------------------------------------------- void __fastcall TForm1::Frame21Button2Click(TObject *Sender) { Frame21->RadioGroup1->ItemIndex = oldItemIndex; Frame21->Visible=false; } //--------------------------------------------------------------------------- void __fastcall TForm1::Frame21Button1Click(TObject *Sender) { EndDD(ddobjekt,ps,bs,clipper,active); switch(Frame21->RadioGroup1->ItemIndex) { case 0: wheight=800; wwidth=600; Form1->Height=wheight; Form1->Width=wwidth; break; case 1: wheight=1024; wwidth=768; Form1->Height=wheight; Form1->Width=wwidth;break; case 2: wheight=1152; wwidth=864; Form1->Height=wheight; Form1->Width=wwidth;break; case 3: wheight=1280; wwidth=720; Form1->Height=wheight; Form1->Width=wwidth;break; default: wheight=800; wwidth=600; Form1->Height=wheight; Form1->Width=wwidth;break; } Frame21->Visible=false; InitDD(Form1->Handle,ddobjekt,ps,bs,clipper,active,wheight,wwidth); } //--------------------------------------------------------------------------- void EndDD(LPDIRECTDRAW ddobjekt, LPDIRECTDRAWSURFACE ps, LPDIRECTDRAWSURFACE bs, LPDIRECTDRAWCLIPPER clipper, bool active) { if(ddobjekt != NULL) { if(ps != NULL) { if(clipper!=NULL) { clipper->Release(); clipper = NULL; } ps->Release(); ps = NULL; } ddobjekt->Release(); ddobjekt = NULL; } active=false; } //-------------------------------------------------------------------- int getxinpix(int y, int x, int TILE_W) { int x_px; //Jede zweite Reihe der Tiles um 1/2 Länge versetzt //-> wenn y ungerade, dann 1/2 Länge zu Tilepostion hinzuaddieren if (y%2==1) { x_px = x*TILE_W + (TILE_W/2); } else { x_px = (x*TILE_W);} return x_px; } //----------------------------------------------------------------------- void __fastcall TForm1::MainLoop() { int x,y; while(1) { ClearSurface(bs); y=ystart/il_gras->Height -1; x=xstart/il_gras->Width -1; if(x<1) x=1; if(y<1) y=1; for(int y;y<=maxheight;y++) { for(int x;x<=maxwidth;x++) { switch(tile[x][y].IL) { case 0: drawtile(ddobjekt,bs,il_gras,&tile[y][x],x, y,xstart,ystart); break; case 1: drawtile(ddobjekt,bs,il_gras,&tile[y][x],x, y,xstart,ystart); break; } } } dddrawing(ps,bs,wheight,wwidth); Application->ProcessMessages(); } } //---------------------------------------------------------------------- void __fastcall TForm1::Initdd() { struct { RGNDATAHEADER rdh; RECT rgndata[1]; } cliplist; cliplist.rdh.dwSize = sizeof (RGNDATAHEADER); cliplist.rdh.iType = RDH_RECTANGLES; cliplist.rdh.nCount = 1; cliplist.rdh.nRgnSize = 0; cliplist.rdh.rcBound.left = 0; cliplist.rdh.rcBound.top = 0; cliplist.rdh.rcBound.right = wheight; cliplist.rdh.rcBound.bottom = wwidth; cliplist.rgndata[0].left = 0; cliplist.rgndata[0].top = 0; cliplist.rgndata[0].right = wheight; cliplist.rgndata[0].bottom = wwidth; HRESULT result; DDSURFACEDESC ddsd; DDSCAPS ddscaps; HDC DC; char buf[256]; result = DirectDrawCreate(NULL, &ddobjekt, NULL); if(result == DD_OK) { // Get exclusive mode result = ddobjekt->SetCooperativeLevel(Handle, DDSCL_EXCLUSIVE | DDSCL_FULLSCREEN); if(result == DD_OK) { result = ddobjekt->SetDisplayMode(wheight, wwidth, 16); if(result == DD_OK) { // Create the primary surface with 1 back buffer ddsd.dwSize = sizeof(ddsd); ddsd.dwFlags = DDSD_CAPS | DDSD_BACKBUFFERCOUNT; ddsd.ddsCaps.dwCaps = DDSCAPS_PRIMARYSURFACE | DDSCAPS_FLIP | DDSCAPS_COMPLEX; ddsd.dwBackBufferCount = 1; result = ddobjekt->CreateSurface(&ddsd, &ps, NULL); if(result == DD_OK) { // Get a pointer to the back buffer ddscaps.dwCaps = DDSCAPS_BACKBUFFER; result = ps->GetAttachedSurface(&ddscaps, &bs); //Clipper erstellen if(result == DD_OK) { result = ddobjekt->CreateClipper(0, &clipper, NULL); if (result != DD_OK) { bs->Release(); bs = NULL; ps->Release(); ps = NULL; ddobjekt->Release(); ddobjekt = NULL; wsprintf(buf, "Clipper init failed (%08lx)\n", result); MessageBox(Handle, buf, "ERROR", MB_OK); Form1->Close(); } result = clipper->SetClipList ((LPRGNDATA) &cliplist, 0); if (result != DD_OK) { clipper->Release(); clipper = NULL; bs->Release(); bs = NULL; ps->Release(); ps = NULL; ddobjekt->Release(); ddobjekt = NULL; wsprintf(buf, "SetClipList init failed (%08lx)\n", result); MessageBox(Handle, buf, "ERROR", MB_OK); Form1->Close(); } //Clipper an bs hängen result = bs->SetClipper(clipper); if (result != DD_OK) { clipper->Release(); clipper = NULL; bs->Release(); bs = NULL; ps->Release(); ps = NULL; ddobjekt->Release(); ddobjekt = NULL; wsprintf(buf, "SetClipList init failed (%08lx)\n", result); MessageBox(Handle, buf, "ERROR", MB_OK); Form1->Close(); } ShowCursor(true); //loadingbitmap(ImageList1,"C:\\Users\\Frank\\Pictures\\spielbilder\\bmps\\Skelett\\Achtung\\Frame_0001.bmp",0x007F858C); active = True; return; } } } } } wsprintf(buf, "Direct Draw Init Failed (%08lx)\n", result); MessageBox(Handle, buf, "ERROR", MB_OK); Form1->Close(); } //------------------------------------------------------------------ void __fastcall TForm1::ResetTiles() { for(int y=1;y<maxheight;y++) { for(int x=1;x<maxwidth;x++) { tile[x][y].IL=0; tile[x][y].walkable=true; tile[x][y].imagenr=0; } } } //------------------------------------------------------------------- void CreateTile(kachel* tile) { tile=new(kachel); tile->walkable=true; tile->IL=0; tile->imagenr=0; } //------------------------------------------------------------------- void __fastcall TForm1::FormPaint(TObject *Sender) { loadtiles(il_gras,"graphic//isotiles//","gras"); } //--------------------------------------------------------------------------- void __fastcall TForm1::Neu1Click(TObject *Sender) { Frame11->Visible=true; } //--------------------------------------------------------------------------- void __fastcall TForm1::Schlieen1Click(TObject *Sender) { Form1->Close(); } //--------------------------------------------------------------------------- void __fastcall TForm1::Auflsung1Click(TObject *Sender) { Frame21->Visible=true; oldItemIndex = Frame21->RadioGroup1->ItemIndex; } //---------------------------------------------------------------------------
Danke
-
das ist so ein Durcheinander das da wohl keiner sich ransetzt das auszuprobieren, außerdem fehlen alle Angaben zu eventuell verwendeten Komponenten, wie z.B. TFrame, Buttons usw.
lad das Projekt einschließlich aller notwendigen Dateien doch mal irgendwo hoch, wenn möglich als zip (nicht als rar) und gib bitte die verwendete BCB-Version mit an
-
Ich stimme zu, das ist ja fürchterlich.
Dennoch fände ich die Konkretisierung der folgenden Fragen vorerst wichtiger:
tecnigas schrieb:
Leider hängt sich mein compiler immer auf. [...] das funzt auch nicht.
Anders gesagt: Wer hängt sich da auf, der Compiler, die IDE oder dein Programm? Mit welcher Fehlermeldung? Und was funktioniert da "auch nicht"?
-
^^
meinst du der code ist fürchterlich oder es ist fürchterlich dass sich das programm aufhängt? xDnaja, also im Prinzip macht er mir die DirectDraw-Surfaces und initialisiert alles, aber danach bleib ich am schwarzen bildschirm hängen. auch die Tastenabfrage für ESCAPE zum beenden funktioniert dann nicht.
-
ich verwende bcb 5.
Wo kann ich denn das uploaden, find es grad nicht und bin doch neu hier
-
tecnigas schrieb:
meinst du der code ist fürchterlich
Ganz richtig.
tecnigas schrieb:
naja, also im Prinzip macht er mir die DirectDraw-Surfaces und initialisiert alles, aber danach bleib ich am schwarzen bildschirm hängen. auch die Tastenabfrage für ESCAPE zum beenden funktioniert dann nicht.
Dann nimm den Debugger, unterbrich den Prozeß und sieh im Call-Stack nach, wo es hängt.