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? 🙂


  • Mod

    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 🙄


  • Mod

    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

    Autocogito

    Gruß, 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


Anmelden zum Antworten