Laufzeitfehler
-
Hallo ich habe ein kleines Game geschrieben dass sich PingPong nennt
gespielt wird mit 2 spielern
gesteuert wird mit [Einfg],[Entf] und [Bild auf], [Bild ab]
jetzt habe ich folgendes Problemm:
nach einer bestimmten laufzeit so 1min Stürtzt es ab.
Es hört auf in den Clientbereich zu zeichnen und zeichnet in den desktop//--------------------------------------------------------------------------- /* Fehler: Nach einer bestimmten zeit für auserhalb des Clientbereiches gezeichnet Kann mir nicht erklären warum. Hinweis: Gespielt wird mit 2 spielern. Steierung Spieler1: [Einfg] (ins) [Entf] (del) Steuerung Spieler2: [Bildauf] (pup) [Bildab] (pdn) */ //--------------------------------------------------------------------------- ////////// //Header// ////////// #include <windows.h> #include <stdlib.h> #include <time.h> //--------------------------------------------------------------------------- ////////////// //Prototypen// ////////////// LRESULT CALLBACK WinProc(HWND hwnd,UINT msg, UINT wParam, LONG lParam); void BewegeBall(); void Zeichnen(HWND hwnd); void Neu(HWND hwnd); void Punkt(HWND hwnd); //--------------------------------------------------------------------------- //////////// //Globales// //////////// #define Klasse "PingPong" HBRUSH MyBrush = CreateSolidBrush(RGB(150,150,150));// grau HWND hPunkt[2]; HINSTANCE hI; struct _VKoo { int Ax,Ay; //Koordinaten Linke Obere Ecke int Bx,By; //Koordinaten Rechte Untere Ecke }; _VKoo Schl1,PS1, Schl2,PS2, Ball, PrevBall; //PS1 und PS2 löschen die Schläger und PrevBall löscht den Ball int Key; //Tastaturtaste int Punkte[2]={0,0}; //Punkte für beide Spieler bool BallxFlag,BallYFlag; //Flags für die Ballflugrichtung char cKey[4]; //Wird nicht verwendet //--------------------------------------------------------------------------- ////////////// //Funktionen// ////////////// //WinMain int _stdcall WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdShow, int nCmdShow) { //Windows Standart HWND hwnd; MSG msg; WNDCLASS wc; hI=hInst; //Globale Variablen initialesieren PS1=Schl1; PS2=Schl2; BallxFlag=true; //Ball fliegt nach rechts BallYFlag=true; //Ball fliebt nach unten Ball.Ax = 390; Ball.Ay = 200; Ball.Bx = Ball.Ax+20; Ball.By = Ball.Ay+20; Schl1.Ax=50; Schl1.Ay=100; Schl1.Bx=Schl1.Ax+20; Schl1.By=Schl1.Ay+110; Schl2.Ax=720; Schl2.Ay=100; Schl2.Bx=Schl2.Ax+20; Schl2.By=Schl2.Ay+110; //Fensterklasse Definieren if (!hPrevInst) { wc.style = 0 ; wc.lpfnWndProc = WinProc ; wc.cbClsExtra = 0 ; wc.cbWndExtra = 0 ; wc.hInstance = hInst ; wc.hIcon = LoadIcon (NULL , IDI_APPLICATION) ; wc.hCursor = LoadCursor (NULL , IDC_ARROW) ; wc.hbrBackground = MyBrush; wc.lpszMenuName = NULL; wc.lpszClassName = Klasse ; RegisterClass (&wc) ; } //Hauptfenster Erstellen hwnd=CreateWindow(Klasse,"API PingPong",WS_SYSMENU,250,300,800,500,NULL,NULL,hInst,NULL); ShowWindow(hwnd,nCmdShow); UpdateWindow(hwnd); hwnd=SetFocus(hwnd); if(MessageBox(NULL,"Spiel starten","Start",MB_YESNO)==IDNO) return 0; //Nachrichtenschleife while(msg.message!=WM_QUIT) { Sleep(10); BewegeBall(); Punkt(hwnd); Zeichnen(hwnd); PrevBall=Ball; PS1=Schl1; PS2=Schl2; PeekMessage(&msg,NULL,0,0,PM_REMOVE); TranslateMessage(&msg); DispatchMessage(&msg); } return msg.wParam; }//WinMain //--------------------------------------------------------------------------- //WinProc LRESULT CALLBACK WinProc(HWND hwnd,UINT msg, UINT wParam, LONG lParam) { //Variablen zum Zeichnen PAINTSTRUCT ps; //Nur für WM_PAINT HDC hdc; //Gerätekontext //Wenn 3 Punkte erreicht ist aus if(Punkte[0]==3 || Punkte[1]==3) msg=WM_DESTROY; //Prüfe Nachrichten switch(msg) { case WM_CREATE: { // Punktefenster "EditBoxen" erstellen hPunkt[0]=CreateWindow("edit","0.",WS_CHILD|WS_VISIBLE|ES_CENTER,70,440,100,15,hwnd,NULL,hI,NULL); hPunkt[1]=CreateWindow("edit","0.",WS_CHILD|WS_VISIBLE|ES_CENTER,663,440,100,15,hwnd,NULL,hI,NULL); //und schreibgeschützt setzen SendMessage(hPunkt[0],EM_SETREADONLY,true,0); SendMessage(hPunkt[1],EM_SETREADONLY,true,0); return 0; } case WM_DESTROY: PostQuitMessage(0); return 0; case WM_PAINT: { //Grenzlinien zeichnen hdc=BeginPaint(hwnd,&ps); MoveToEx(hdc,70,28,NULL); LineTo(hdc,720,28); MoveToEx(hdc,70,421,NULL); LineTo(hdc,720,421); //Texte ausgeben SetTextColor(hdc, RGB(0,0,0) ); SetBkColor(hdc, RGB(150,150,150) ); TextOut(hdc,70,422,"Spieler 1",9); TextOut(hdc,663,422,"Spieler 2",9); EndPaint(hwnd,&ps); return 0; } //Tastatureingabe case WM_KEYDOWN: { Key=wParam; switch(wParam) { case 46: { if(Schl1.By>=420) break; Schl1.Ay+=10; Schl1.By+=10; break; } case 45: { if(Schl1.Ay<=30) break; Schl1.Ay-=10; Schl1.By-=10; break; } case 34: { if(Schl2.By>=420) break; Schl2.Ay+=10; Schl2.By+=10; break; } case 33: { if(Schl2.Ay<=30) break; Schl2.Ay-=10; Schl2.By-=10; break; } }//wParam return 0; } }//msg return DefWindowProc(hwnd,msg,wParam,lParam); }//WinProc //--------------------------------------------------------------------------- void BewegeBall() { //Ball pralt ab (Flags verändern) if(Ball.Bx+3>=720) if(Ball.Ay<=Schl2.By+30 && Ball.By>=Schl2.Ay) BallxFlag=false; if(Ball.Ax-3<=69) if(Ball.By>=Schl1.Ay&&Ball.Ay<=Schl1.By+30) BallxFlag=true; if(Ball.By>=420) BallYFlag=false; if(Ball.Ay<=30) BallYFlag=true; //Ballkoordinaten verändern if(BallxFlag==true) { Ball.Ax+=3; Ball.Bx+=3; } else { Ball.Ax-=3; Ball.Bx-=3; } if(BallYFlag==true) { Ball.Ay+=3; Ball.By+=3; } else { Ball.Ay-=2; Ball.By-=2; } } //--------------------------------------------------------------------------- void Zeichnen(HWND hwnd) { HDC hdc; HPEN grau, weis; grau=CreatePen(PS_SOLID,1,RGB(150,150,150)); weis=CreatePen(PS_SOLID,1,RGB(255,255,255)); hdc=GetDC(hwnd); //Schläger 1 löschen SelectObject(hdc,grau); MoveToEx(hdc,PS1.Ax,PS1.Ay,NULL); LineTo(hdc,PS1.Ax,PS1.By); LineTo(hdc,PS1.Bx,PS1.By); LineTo(hdc,PS1.Bx,PS1.Ay); LineTo(hdc,PS1.Ax,PS1.Ay); //und neu zeuchnen SelectObject(hdc,weis); MoveToEx(hdc,Schl1.Ax,Schl1.Ay,NULL); LineTo(hdc,Schl1.Ax,Schl1.By); LineTo(hdc,Schl1.Bx,Schl1.By); LineTo(hdc,Schl1.Bx,Schl1.Ay); LineTo(hdc,Schl1.Ax,Schl1.Ay); //Schläger 2 löschen SelectObject(hdc,grau); MoveToEx(hdc,PS2.Ax,PS2.Ay,NULL); LineTo(hdc,PS2.Ax,PS2.By); LineTo(hdc,PS2.Bx,PS2.By); LineTo(hdc,PS2.Bx,PS2.Ay); LineTo(hdc,PS2.Ax,PS2.Ay); //und neu zeuchnen SelectObject(hdc,weis); MoveToEx(hdc,Schl2.Ax,Schl2.Ay,NULL); LineTo(hdc,Schl2.Ax,Schl2.By); LineTo(hdc,Schl2.Bx,Schl2.By); LineTo(hdc,Schl2.Bx,Schl2.Ay); LineTo(hdc,Schl2.Ax,Schl2.Ay); //Ball löschen SelectObject(hdc,grau); Arc(hdc,PrevBall.Ax,PrevBall.Ay,PrevBall.Bx,PrevBall.By,PrevBall.Ax,(PrevBall.Ay+PrevBall.By)/2,PrevBall.Ax,(PrevBall.Ay+PrevBall.By)/2); //und neu zeichnen SelectObject(hdc,weis); Arc(hdc,Ball.Ax,Ball.Ay,Ball.Bx,Ball.By,Ball.Ax,(Ball.Ay+Ball.By)/2,Ball.Ax,(Ball.Ay+Ball.By)/2); ReleaseDC(hwnd,hdc); } //--------------------------------------------------------------------------- void Neu(HWND hwnd) { //Ball neu setzten und warten Ball.Ax = 390; Ball.Ay = 200; Ball.Bx = Ball.Ax+20; Ball.By = Ball.Ay+20; Zeichnen(hwnd); Sleep(1000); } //--------------------------------------------------------------------------- void Punkt(HWND hwnd) { //Prüfen ob Punkt if(Ball.Ax<Schl1.Bx-10) { Punkte[1]+=1; BallxFlag=true; Neu(hwnd); _gcvt(Punkte[1],10,cKey); SetWindowText(hPunkt[1],cKey); } if(Ball.Bx>Schl2.Ax+10) { Punkte[0]+=1; BallxFlag=false; Neu(hwnd); _gcvt(Punkte[0],10,cKey); SetWindowText(hPunkt[0],cKey); } }
-
stürzt es von sich aus ab, oder brauchst du im durchschnitt ~1 minute, um die fatale testenkombination rauszukriegen?

-
an welcher stelle bleibt es im debugger haengen?
-
Es stürtzt von selbst ab
-
schau dir das programm mit dem debugger ganz genau an, sonst würde ein bisschen logging nicht schaden, da siehst du zumindest direkt, wo es stress gibt

-
Artez schrieb:
Es stürtzt von selbst ab
an welcher stelle?
-
Gib die mit CreatePen () erzeugten "Stifte" nach Gebrauch wieder frei :
void Zeichnen(HWND hwnd) { HDC hdc; HPEN grau, weis; grau=CreatePen(PS_SOLID,1,RGB(150,150,150)); weis=CreatePen(PS_SOLID,1,RGB(255,255,255)); hdc=GetDC(hwnd); ... ... ... DeleteObject (weis); // <- ! DeleteObject (grau); // <- ! ReleaseDC(hwnd,hdc); }Sonst hast Du nach einer Minute etliche tausend davon.

-
AFAIK: SelectObject merkt sich alles, wenn man es nicht wieder richtig abschaltet, das geht aber nur bis etwa 2^16 Objekten. f'`8k
AutocogitoGruß, TGGC (making great games since 1992)
-
Vielen Dank jetzt läufts

-
Wars jez also ein memory leak oder wie? Und da stirbt das programm bereits nach einer minute?

-
scheint so