winapi - Fenster verliert farben und wird schwarz/weiss

Arjitan

Grünschnabel
Ich habe mich seit längerem mal wieder an das Programmieren rangewagt, um genau zu sein habe ich das letzte mal vor ca 13 Jahren auf nem Amiga in Power D (oder e++) programmiert.

Ich versuche mich grad an Visual c++ express 2010 und komme eigendlich recht gut vorran, was tutorials verstehen angeht. Nur habe ich jetzt ein problem, wo ich einfach nicht weiß was ich falsch mache.

Das Programm stellt eine 60x30 Map grafisch via Rechtecke da in der sich eine Ai auf ihr ziel zu bewegt. Die Ai macht auch ein paar schritte, dann werden die "bunten" rechteecke alle weiß (hintergrundfarbe ist schwarz) und ich kann halt nicht mehr sehen was die ai macht, die scheint aber weiter zu laufen.

hier mal der Sourcecode, nicht lachen ist alles sehr einfach geschrieben und nicht grade super strukturiert:

Code:
#include <windows.h>
#include <math.h>
#include <time.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

#define ID_TIMER_INC    1
//#define ID_TIMER_FAST   2
char szAppName[] = "Simple AI win";
int gmap[60][30];
struct xy
{
	int x;
	int y;
};
struct xy ai8;
struct xy ai6;
struct xy food;

int createmap()
{
	int rnd;
	for (int y=0; y<30; y++)
	{
		for (int x=0; x<60; x++)
		{
			rnd=rand() % 10;
			switch (rnd)
			{
				case 0:
				case 1:
				break;
				default:
				rnd=0;
			}
			gmap[x][y]=rnd;	
		}
	}
	return 0;
}
int place (struct xy &place)
{
	bool roll=false;
	//random place AI
		while (roll==false )
		{
			place.x=rand() % 20;
			place.y=rand() % 20;
			if (gmap[place.x][place.y]==0)
				roll =true;
		}	
	return 0;
}
int aistep (struct xy &self, struct xy &target)
{
	bool ende=false;
	int x= target.x - self.x;
	int y= target.y - self.y;
	struct xy walk;

		// set walk direction
		if (x>0)
		{
			walk.x = 1;
		} else if (x<0)
		{
			walk.x =-1;
		}else
		{
			walk.x=0;
		}

		if (y>0)
		{
			walk.y = 1;
		} else if (y<0)
		{
			walk.y =-1;
		}else
		{
			walk.y=0;
		}	

		// try to walk
		if (gmap[self.x + walk.x][self.y+walk.y]!=1 && walk.x !=0 && walk.y !=0) //walk x&y
		{
			self.x += walk.x;
			self.y += walk.y;
		} else if (gmap[self.x+walk.x][self.y]!=1 && walk.x !=0)// walk x
		{
			self.x=self.x+walk.x;
		} else if (gmap[self.x][self.y+walk.y]!=1 && walk.y !=0)// walk y
		{
			self.y=self.y+walk.y;
		} else if (gmap[self.x][self.y+walk.y]==1 && walk.x ==0)// walk x with walk.x=0
		{
			if (gmap[self.x+1][self.y+walk.y] ==0) //walk x +1
			{
				self.y=self.y+walk.y;
				self.x=self.x+1;
			}else if (gmap[self.x-1][self.y+walk.y] ==0) //walk x -1
			{
				self.y=self.y+walk.y;
				self.x=self.x-1;
			}
		} else if (gmap[self.x+walk.x][self.y]==1 && walk.y ==0)// walk y with walk.y=0
		{
			if (gmap[self.x+walk.x][self.y+1] == 0) //walk y +1
			{
				self.x=self.x+walk.x;
				self.y=self.y+1;
			}else if (gmap[self.x+walk.x][self.y-1] == 0) //walk y -1
			{
				self.x=self.x+walk.x;
				self.y=self.y-1;
			}
		}else // needs more walk conditions. -.-
		{
			//cout << "no more moves" <<endl;
			return(1);
		}		
		if (self.x == target.x)
		{
			if (self.y == target.y)
			{
				ende=true;
				//cout << "Ziel erreicht" <<endl;
				return(2);
			}
		}
	return 0;
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
	MSG			msg;
	HWND		hWnd;
	WNDCLASS	wc;
	
	wc.cbClsExtra		= 0;
	wc.cbWndExtra		= 0;
	wc.hbrBackground	= (HBRUSH) GetStockObject(BLACK_BRUSH);
	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);
	wc.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
	wc.hInstance		= hInstance;
	wc.lpfnWndProc		= WndProc;
	wc.lpszClassName	= szAppName;
	wc.lpszMenuName		= NULL;
	wc.style			= CS_HREDRAW | CS_VREDRAW;
	
	RegisterClass(&wc);
	
	hWnd = CreateWindow(szAppName,
						szAppName,
						 WS_OVERLAPPEDWINDOW,
						 0,
						 0,
						 1240,
						 660,
						 NULL,
						 NULL,
						 hInstance,
						 NULL);
	srand(time(NULL));
	createmap();
	place(ai8);
	//place(ai6);
	place(food);
	gmap[ai8.x][ai8.y]=8;
	//gmap[ai6.x][ai6.y]=6;
	gmap[food.x][food.y]=9;
	ShowWindow(hWnd, iCmdShow);
	UpdateWindow(hWnd);
	
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static RECT	  rect;
	static double	dGrad;
	
	switch (message)
	{
		case WM_CREATE:
		{
			SetTimer(hWnd, ID_TIMER_INC, 500, NULL);
			//SetTimer(hWnd, ID_TIMER_FAST, 10000, NULL);
			return 0;
		}
		case WM_SIZE:
		{
			rect.right  = LOWORD(lParam);
			rect.bottom = HIWORD(lParam);
			return 0;
		}
		case WM_PAINT:
		{
			PAINTSTRUCT	 ps;
			HDC			hDC;
			
			hDC = BeginPaint(hWnd, &ps);
			{
			 HBRUSH hOldBrush;
			 	for (int y=0; y<30; y++)
				{
					for (int x=0; x<60; x++)
					{
						switch (gmap[x][y])
						{
							case 0:
								hOldBrush = (HBRUSH)SelectObject(hDC,CreateSolidBrush(RGB(0,123,0)));//dark_green;
								break;
							case 1:
								hOldBrush = (HBRUSH)SelectObject(hDC,CreateSolidBrush(RGB(64,64,64)));//gray;
								break;
							case 6:
								hOldBrush = (HBRUSH)SelectObject(hDC,CreateSolidBrush(RGB(255,0,0)));//red;
								break;
							case 8:
								hOldBrush = (HBRUSH)SelectObject(hDC,CreateSolidBrush(RGB(200,0,210)));//purple;
								break;
							case 9:
								hOldBrush = (HBRUSH)SelectObject(hDC,CreateSolidBrush(RGB(255,255,0)));//yellow;
								break;
							default:
								hOldBrush = (HBRUSH)SelectObject(hDC,CreateSolidBrush(RGB(0,0,0)));//white;
						}
						RoundRect(hDC, 10+(x*20), 10+(y*20), 30+(x*20),30+(y*20), 0, 0);
					}
				}
				DeleteObject(SelectObject(hDC, hOldBrush));
			}
			EndPaint(hWnd, &ps);
			return 0;
		}
		case WM_TIMER:
		{
			static double dInc = .2;
			switch (wParam)
			{
				case ID_TIMER_INC:
				{
					gmap[ai8.x][ai8.y]=0;
					gmap[ai6.x][ai6.y]=0;
					if (aistep(ai8,food) ==2)
					{
						gmap[food.x][food.y]=0;
						place (food);// place random food
					} 
					//aistep(ai6,ai8);
					gmap[ai8.x][ai8.y]=8;
					//gmap[ai6.x][ai6.y]=6;
					InvalidateRect(hWnd, NULL, FALSE);
					break;
				}
			}
		return 0;
		}
		case WM_DESTROY:
		{
			KillTimer(hWnd, ID_TIMER_INC);
			// KillTimer(hWnd, ID_TIMER_FAST);
			PostQuitMessage(0);
			return 0;
		}
	}
	return DefWindowProc(hWnd, message, wParam, lParam);
}

Also wenn mich jemand mal in die richtige Richtung schupsen mag, wäre ich sehr dankbar.
Denkanstösse werden lieber genommen als komplettlösungen. *g*
 

sheel

I love Asm
Hi und Willkommen bei tutorials.de,

Bei WM_PAINT erzeugst du bei jedem Durchgang 1800 Brushes.
Gelöscht wird nach den Schleifen eine davon.

Bei mir wirds zwischen dem sechsten und siebenten Durchgang hin,
da dürften sich also über 10000 SolidBrushes angehäuft haben.
Windows kommt mit so einer Menge wohl nicht mehr zurecht
(die Returnwerte von CreateSolidBrush überprüft: 0=Fehler).

Mach doch einfach ein Array aus 6 Brushes, für jede verwendete Farbe eine.
Einmal am Anfang anlegen, einmal am Schluss löschen.
Und in den Schleifen nur noch SelectObject, aber kein Neuerzeugen.

Gruß
 

Arjitan

Grünschnabel
Ah, vielen Dank!
ich war irgendwie davon ausgegangen das ich bei jedem neukreieren den alten brush überschreibe. Dabei überschreibe ich ja lediglich den Verweiß auf seine Adresse.

So sieht das ganze dann jetzt aus, momentan, ich habe jetzt erstmal eine grundlage für mich geschaffen und will jetzt mal sehen wie ich das verbessern kann.

Schlagt mich bitte wenn ich das jetzt falsch verstanden habe. *hust*

Code:
#include <windows.h>
#include <math.h>
#include <time.h>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);

#define ID_TIMER_INC    1
//#define ID_TIMER_FAST   2
char szAppName[] = "Simple AI win";
int gmap[60][30];

struct xy
{
	int x;
	int y;
};
struct xy ai8;
struct xy ai6;
struct xy food;

int createmap()
{
	int rnd;
	for (int y=0; y<30; y++)
	{
		for (int x=0; x<60; x++)
		{
			rnd=rand() % 10;
			switch (rnd)
			{
				case 0:
				case 1:
				break;
				default:
				rnd=0;
			}
			gmap[x][y]=rnd;	
		}
	}
	return 0;
}

int place (struct xy &place)
{
	bool roll=false;
	//random place AI
		while (roll==false )
		{
			place.x=rand() % 60;
			place.y=rand() % 30;
			if (gmap[place.x][place.y]==0)
				roll =true;
		}	
	return 0;
}

int aistep (struct xy &self, struct xy &target)
{
	int x= target.x - self.x;
	int y= target.y - self.y;
	struct xy walk;

		// set walk direction
		if (x>0)
		{
			walk.x = 1;
		} else if (x<0)
		{
			walk.x =-1;
		}else
		{
			walk.x=0;
		}

		if (y>0)
		{
			walk.y = 1;
		} else if (y<0)
		{
			walk.y =-1;
		}else
		{
			walk.y=0;
		}	

		// try to walk
		if (gmap[self.x + walk.x][self.y+walk.y]!=1 && walk.x !=0 && walk.y !=0) //walk x&y
		{
			self.x += walk.x;
			self.y += walk.y;
		} else if (gmap[self.x+walk.x][self.y]!=1 && walk.x !=0)// walk x
		{
			self.x=self.x+walk.x;
		} else if (gmap[self.x][self.y+walk.y]!=1 && walk.y !=0)// walk y
		{
			self.y=self.y+walk.y;
		} else if (gmap[self.x][self.y+walk.y]==1 && walk.x ==0)// walk x with walk.x=0
		{
			if (gmap[self.x+1][self.y+walk.y] ==0) //walk x +1
			{
				self.y=self.y+walk.y;
				self.x=self.x+1;
			}else if (gmap[self.x-1][self.y+walk.y] ==0) //walk x -1
			{
				self.y=self.y+walk.y;
				self.x=self.x-1;
			}
		} else if (gmap[self.x+walk.x][self.y]==1 && walk.y ==0)// walk y with walk.y=0
		{
			if (gmap[self.x+walk.x][self.y+1] == 0) //walk y +1
			{
				self.x=self.x+walk.x;
				self.y=self.y+1;
			}else if (gmap[self.x+walk.x][self.y-1] == 0) //walk y -1
			{
				self.x=self.x+walk.x;
				self.y=self.y-1;
			}
		}else // needs more walk conditions. -.-
		{
			//cout << "no more moves" <<endl;
			return(1);
		}		
		if (self.x == target.x)
		{
			if (self.y == target.y)
			{
				return(2);
			}
		}
	return 0;
}


int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
	MSG			msg;
	HWND		hWnd;
	WNDCLASS	wc;
	
	wc.cbClsExtra		= 0;
	wc.cbWndExtra		= 0;
	wc.hbrBackground	= (HBRUSH) GetStockObject(BLACK_BRUSH);
	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);
	wc.hIcon			= LoadIcon(NULL, IDI_APPLICATION);
	wc.hInstance		= hInstance;
	wc.lpfnWndProc		= WndProc;
	wc.lpszClassName	= szAppName;
	wc.lpszMenuName		= NULL;
	wc.style			= CS_HREDRAW | CS_VREDRAW;
	
	RegisterClass(&wc);
	
	hWnd = CreateWindow(szAppName,
						szAppName,
						 WS_OVERLAPPEDWINDOW,
						 0,
						 0,
						 1240,
						 660,
						 NULL,
						 NULL,
						 hInstance,
						 NULL);
	srand(time(NULL));
	createmap();
	place(ai8);
	//place(ai6);
	place(food);
	gmap[ai8.x][ai8.y]=8;
	//gmap[ai6.x][ai6.y]=6;
	gmap[food.x][food.y]=9;
	ShowWindow(hWnd, iCmdShow);
	UpdateWindow(hWnd);
	
	while (GetMessage(&msg, NULL, 0, 0))
	{
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}
	return msg.wParam;
}
	
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	static RECT	  rect;
	static double	dGrad;
	
	switch (message)
	{
		case WM_CREATE:
		{
			SetTimer(hWnd, ID_TIMER_INC, 1, NULL);
			//SetTimer(hWnd, ID_TIMER_FAST, 10000, NULL);
			return 0;
		}
		case WM_SIZE:
		{
			rect.right  = LOWORD(lParam);
			rect.bottom = HIWORD(lParam);
			return 0;
		}
		case WM_PAINT:
		{
			PAINTSTRUCT	 ps;
			HDC			hDC;
			HBRUSH hOldBrush[10];

			hDC = BeginPaint(hWnd, &ps);
			{
				hOldBrush[0] = CreateSolidBrush(RGB(0,123,0));//dark_green;
				hOldBrush[1] = CreateSolidBrush(RGB(64,64,64));//gray;
				hOldBrush[6] = CreateSolidBrush(RGB(255,0,0));//red;
				hOldBrush[8] = CreateSolidBrush(RGB(200,0,210));//purple;
				hOldBrush[9] = CreateSolidBrush(RGB(255,255,0));//yellow;
			 	for (int y=0; y<30; y++)
				{
					for (int x=0; x<60; x++)
					{
						SelectObject(hDC,hOldBrush[gmap[x][y]]);
						RoundRect(hDC, 10+(x*20), 10+(y*20), 30+(x*20),30+(y*20), 0, 0);
					}
				}
			}
			DeleteObject(hOldBrush[0]);
			DeleteObject(hOldBrush[1]);
			DeleteObject(hOldBrush[6]);
			DeleteObject(hOldBrush[8]);
			DeleteObject(hOldBrush[9]);
			EndPaint(hWnd, &ps);
			return 0;
		}
		case WM_TIMER:
		{
			switch (wParam)
			{
				case ID_TIMER_INC:
				{
					gmap[ai8.x][ai8.y]=0;
					gmap[ai6.x][ai6.y]=0;
					if (aistep(ai8,food) ==2)
					{
						gmap[food.x][food.y]=0;
						place (food);// place random food
						gmap[food.x][food.y]=9;
					} 
					//aistep(ai6,ai8);
					gmap[ai8.x][ai8.y]=8;
					//gmap[ai6.x][ai6.y]=6;
					InvalidateRect(hWnd, NULL, FALSE);
					break;
				}
			}
		return 0;
		}
		case WM_DESTROY:
		{
			KillTimer(hWnd, ID_TIMER_INC);

			// KillTimer(hWnd, ID_TIMER_FAST);
			PostQuitMessage(0);
			return 0;
		}
	}
	return DefWindowProc(hWnd, message, wParam, lParam);
}

Ist bei weitem nicht perfekt, aber erstmal eine schnelle Lösung mit dem Array[10].
 

sheel

I love Asm
Das ist schon richtig verstanden.
Hätte die Unterscheidung vllt. in der Schleife gemacht (und nur ein [6]-Array verwendet)...
aber wegen den paar überflüssigen Byte...
 

Neue Beiträge