Snake: Eure Meinung...
-
Ich hätte gerne eure Meinung zum Aufbau von meinem Snake-Spiel. Mir geht es einfach darum ob ich was verändern sollte, oder ob ich meinen programmierstil grundsätzlich ändern sollte.
Der Code ist doch ziemlich umfangreich geworden:#include <windows.h> #include <stdio.h> #define ID_BUTTON_START 1 #define ID_BUTTON_PAUSE 2 #define ID_BUTTON_ENDE 3 #define ID_EDIT_ZEIT 4 #define ID_EDIT_VERLAENGERN 5 #define ID_BUTTON_WAND 6 //Richtung der Schlange #define RT_HOCH 1 #define RT_RECHTS 2 #define RT_RUNTER 3 #define RT_LINKS 4 //Timer #define Timer_ID 1 //Richtung der Schlangenteile #define WAAGRECHT 1 #define SENKRECHT 2 #define PUNKT 3 #define BG_LINKS 4 #define BG_HOCH 5 #define BG_RECHTS 6 #define BG_RUNTER 7 #define MAX 4000 //MaxSchlangenlänge //TCHAR = char //PSTR = LPSTR = *char; int status, aktiv = 0, befehl = 0, iPunkt[3], iPunkte = 0, iPproPunkt = 0, iZeit, iVerlaengerung; //iPunkte = Anzahl der Erreichten Punkte, berechnet mit iPproPunkt int iPosition[MAX][4] = {0}; //0 = xKoordinate, 1 = yKoordinate, 2 = Ausrichtung int iRichtung, xFelder, yFelder, iSchlLaenge; int iPrevRichtung; static HWND hwndHauptFenster, PrevWndProcEditZeit, PrevWndProcEditVerlaengerung, hwndEditZeit, hwndEditVerlaengerung, hwndButtonWand; LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); LRESULT CALLBACK ChildWndProcEditZeit(HWND, UINT, WPARAM, LPARAM); VOID Thread(PVOID); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR lpCmdLine, int iCmdShow) { static TCHAR szAppName[] = TEXT("Snake"); HWND hwnd; MSG msg; WNDCLASS wndclass; wndclass.style = CS_HREDRAW | CS_VREDRAW; wndclass.lpfnWndProc = WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); wndclass.hInstance = hInstance; wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); wndclass.lpszMenuName = 0; wndclass.lpszClassName = szAppName; RegisterClass(&wndclass); hwnd = CreateWindow(szAppName, TEXT("Snake"), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); 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 HWND hwndButtonStart, hwndButtonEnde, hwndButtonPause; static int cyChar, cxChar, cyClient, cxClient; PAINTSTRUCT ps; HDC hdc; static RECT rect, rectUpdate; static HBRUSH hBrush; int i; static BOOL bPause; TCHAR cBuffer[20]; static HMENU SysMenu; HRGN hRgnTemp[6]; HPEN hPen1; switch(message) { case WM_PAINT: hdc = BeginPaint(hwnd, &ps); MoveToEx(hdc, cxChar * 2, cyChar * 6, NULL); LineTo(hdc, cxChar * 2, cyChar * 6 + 11 * yFelder); LineTo(hdc, cxChar * 2 + 11 * xFelder, cyChar * 6 + 11 * yFelder); LineTo(hdc, cxChar * 2 + 11 * xFelder, cyChar * 6); LineTo(hdc, cxChar * 2, cyChar * 6); SelectObject(hdc, CreateSolidBrush(RGB(0, 0, 0))); if(aktiv == 1) { Ellipse(hdc, cxChar * 2 + 1 + iPosition[0][0] * 11 - 1 - 5 - 3, cyChar * 6 + 1 + iPosition[0][1] * 11 - 1 - 5 - 3, cxChar * 2 + 1 + iPosition[0][0] * 11 - 1 - 5 + 2, cyChar * 6 + 1 + iPosition[0][1] * 11 - 1 - 5 + 2); for(i = 1; i < iSchlLaenge + 1; i++) { switch(iPosition[i][2]) { case SENKRECHT: SetRect(&rect, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 - 3, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 - 5, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 + 2, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 + 5); //5 breit, 10 hoch FillRect(hdc, &rect, hBrush); break; case WAAGRECHT: SetRect(&rect, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 - 5, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 - 3, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 + 5, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 + 2); //10 breit, 5 hoch FillRect(hdc, &rect, hBrush); break; case PUNKT: SelectObject(hdc, CreateSolidBrush(RGB(0, 0, 0))); Ellipse(hdc, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 - 3, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 - 3, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 + 2, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 + 2); break; case BG_RUNTER: SetRect(&rect, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 - 3, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 - 3, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 + 5, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 + 2); //10 breit, 5 hoch FillRect(hdc, &rect, hBrush); SetRect(&rect, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 - 3, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 - 3, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 + 2, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 + 5); //5 breit, 10 hoch FillRect(hdc, &rect, hBrush); break; case BG_RECHTS: SetRect(&rect, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 - 3, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 - 3, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 + 5, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 + 2); //10 breit, 5 hoch FillRect(hdc, &rect, hBrush); SetRect(&rect, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 - 3, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 - 5, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 + 2, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 + 2); //5 breit, 10 hoch FillRect(hdc, &rect, hBrush); break; case BG_HOCH: SetRect(&rect, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 - 5, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 - 3, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 + 2, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 + 2); //10 breit, 5 hoch FillRect(hdc, &rect, hBrush); SetRect(&rect, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 - 3, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 - 5, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 + 2, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 + 2); //5 breit, 10 hoch FillRect(hdc, &rect, hBrush); break; case BG_LINKS: SetRect(&rect, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 - 5, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 - 3, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 + 2, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 + 2); //10 breit, 5 hoch FillRect(hdc, &rect, hBrush); SetRect(&rect, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 - 3, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 - 3, cxChar * 2 + 1 + iPosition[i][0] * 11 - 1 - 5 + 2, cyChar * 6 + 1 + iPosition[i][1] * 11 - 1 - 5 + 5); //5 breit, 10 hoch FillRect(hdc, &rect, hBrush); break; } } if(iPunkt[2] == 1) Ellipse(hdc, cxChar * 2 + 1 + iPunkt[0] * 11 - 1 - 5 - 2, cyChar * 6 + 1 + iPunkt[1] * 11 - 1 - 5 - 2, cxChar * 2 + 1 + iPunkt[0] * 11 - 1 - 5 + 2, cyChar * 6 + 1 + iPunkt[1] * 11 - 1 - 5 + 2); } TextOut(hdc, cxClient - cxChar * 8 - cxChar * 20, cyChar + 10, "Dauer pro Schritt(ms):", 22); TextOut(hdc, cxClient - cxChar * 8 - cxChar * 20, cyChar * 2 + 15, "+Länge:", 7); TextOut(hdc, cxClient - cxChar * 8 - cxChar * 20, cyChar * 3 + 20, "Wand durchgängig:", 17); TextOut(hdc, cxChar * 2, cyChar + 10, TEXT("Punkte pro Treffer:"), 19); TextOut(hdc, cxChar * 2, cyChar * 2 + 15, TEXT("Gesamtpunkte:"), 13); SetTextAlign(hdc, TA_RIGHT); TextOut(hdc, cxChar * 20, cyChar + 10, cBuffer, wsprintf(cBuffer, TEXT("%d"), iPproPunkt)); TextOut(hdc, cxChar * 20, cyChar * 2 + 15, cBuffer, wsprintf(cBuffer, TEXT("%d"), iPunkte)); EndPaint(hwnd, &ps); return 0; case WM_SIZE: cxClient = LOWORD(lParam); cyClient = HIWORD(lParam); SetWindowPos(hwndButtonStart, HWND_TOP, cxClient / 4 - cxChar * 10, cyChar * 2, cxChar * 20, cyChar * 3, SWP_SHOWWINDOW); SetWindowPos(hwndButtonPause, HWND_TOP, cxClient / 2 - cxChar * 10, cyChar * 2, cxChar * 20, cyChar * 3, SWP_SHOWWINDOW); SetWindowPos(hwndButtonEnde, HWND_TOP, cxClient / 4 * 3 - cxChar * 10, cyChar * 2, cxChar * 20, cyChar * 3, SWP_SHOWWINDOW); SetWindowPos(hwndEditZeit, HWND_TOP, cxClient - cxChar * 8, cyChar + 10, cxChar * 5, cyChar, SWP_SHOWWINDOW); SetWindowPos(hwndEditVerlaengerung, HWND_TOP, cxClient - cxChar * 8, cyChar * 2 + 15, cxChar * 4, cyChar, SWP_SHOWWINDOW); SetWindowPos(hwndButtonWand, HWND_TOP, cxClient - cxChar * 8, cyChar * 3 + 20, cyChar, cyChar, SWP_SHOWWINDOW); //Abstand zum Rand = 2 * cxChar //1 Feld = 10 x 10 + 1 Abstand zum nächsten Feld xFelder = ((cxClient - 4 * cxChar) - 1) / 11; yFelder = (cyClient - 6 * cyChar - 2 * cxChar - 1) / 11; SetRect(&rectUpdate, cxChar * 2, cyChar * 6, cxChar * 2 + 11 * xFelder, cyChar * 6 + 11 * yFelder); return 0; case WM_CREATE: hBrush = CreateSolidBrush(RGB(0, 0, 0)); cxChar = LOWORD(GetDialogBaseUnits()); cyChar = HIWORD(GetDialogBaseUnits()); hwndHauptFenster = hwnd; hwndEditZeit = CreateWindow(TEXT("edit"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | ES_WANTRETURN, 0, 0, 0, 0, //Wird bei WM_SIZE verändert hwnd, (HMENU) ID_EDIT_ZEIT, (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE), NULL); PrevWndProcEditZeit = SetWindowLongPtr(hwndEditZeit, GWLP_WNDPROC, (LONG_PTR) ChildWndProcEditZeit); SetFocus(hwndEditZeit); hwndButtonWand = CreateWindow(TEXT("button"), NULL, WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, 0, 0, 0, 0, //Wird bei WM_SIZE verändert hwnd, (HMENU) ID_BUTTON_WAND, (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE), NULL); hwndEditVerlaengerung = CreateWindow(TEXT("edit"), NULL, WS_CHILD | WS_VISIBLE | WS_BORDER | ES_MULTILINE | ES_WANTRETURN, 0, 0, 0, 0, //Wird bei WM_SIZE verändert hwnd, (HMENU) ID_EDIT_VERLAENGERN, (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE), NULL); PrevWndProcEditVerlaengerung = SetWindowLongPtr(hwndEditVerlaengerung, GWLP_WNDPROC, (LONG_PTR) ChildWndProcEditZeit); hwndButtonStart = CreateWindow(TEXT("button"), "Start", WS_CHILD | WS_VISIBLE | BS_CENTER, 0, 0, 0, 0,//Wird bei WM_SIZE verändert //cxClient / 4 - cxChar * 10, cyChar * 2, //cxChar * 20, //cyChar * 3, hwnd, (HMENU) ID_BUTTON_START, (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE), NULL); hwndButtonPause = CreateWindow(TEXT("button"), "Pause", WS_CHILD | WS_VISIBLE | BS_CENTER, 0, 0, 0, 0,//Wird bei WM_SIZE verändert //cxClient / 2 - cxChar * 10, cyChar * 2, //cxChar * 20, //cyChar * 3, hwnd, (HMENU) ID_BUTTON_PAUSE, (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE), NULL); EnableWindow(hwndButtonPause, FALSE); hwndButtonEnde = CreateWindow(TEXT("button"), "Stop", WS_CHILD | WS_VISIBLE | BS_CENTER, 0, 0, 0, 0,//Wird bei WM_SIZE verändert //cxClient * 3 /4 - cxChar * 10, cyChar * 2, //cxChar * 20, //cyChar * 3, hwnd, (HMENU) ID_BUTTON_ENDE, (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE), NULL); EnableWindow(hwndButtonEnde, FALSE); return 0; case WM_KEYDOWN: if(befehl == 0) //Wurde letzte Richtungsangabe schon verarbeitet? { switch(wParam) { case VK_LEFT: if(iPosition[0][2] != RT_RECHTS) { iPosition[0][2] = RT_LINKS; befehl = 1; } break; case VK_UP: if(iPosition[0][2] != RT_RUNTER) { iPosition[0][2] = RT_HOCH; befehl = 1; } break; case VK_RIGHT: if(iPosition[0][2] != RT_LINKS) { iPosition[0][2] = RT_RECHTS; befehl = 1; } break; case VK_DOWN: if(iPosition[0][2] != RT_HOCH) { iPosition[0][2] = RT_RUNTER; befehl = 1; } break; } } case WM_COMMAND: if(HIWORD(wParam) == BN_CLICKED) { switch(LOWORD(wParam)) { case ID_BUTTON_START: ////////////////////////////// //Zeitabstände für Timer abfragen aus Edit GetWindowText(hwndEditZeit, cBuffer, 19); if(cBuffer[0] == '\0') { MessageBox(hwnd, "Bitte eine Zeit angeben!", "Fehler", MB_OK | MB_ICONINFORMATION); SetFocus(hwndEditZeit); return 0; } sscanf(cBuffer, "%d", &iZeit); if(iZeit > 0) SetTimer(hwnd, Timer_ID, iZeit, 0); else { MessageBox(hwnd, "Zeiteingabe zu klein!", "Fehler", MB_OK | MB_ICONINFORMATION); SetFocus(hwndEditZeit); return 0; } ////////////////////////////////////// //Wert, um den die Schlange wachsen soll aus Edit abfragen GetWindowText(hwndEditVerlaengerung, cBuffer, 19); if(cBuffer[0] == '\0') { MessageBox(hwnd, "Bitte einen Wert eingeben!", "Fehler", MB_OK | MB_ICONINFORMATION); SetFocus(hwndEditVerlaengerung); return 0; } sscanf(cBuffer, "%d", &iVerlaengerung); if(iVerlaengerung < 0 || iVerlaengerung > 100) { MessageBox(hwnd, "Die Zahl sollte >0 und <100 sein!", "Fehler", MB_OK | MB_ICONINFORMATION); SetFocus(hwndEditVerlaengerung); return 0; } /////////////////////////////////////////////// Init_Schlange(20); //Anfangslänge der Schlange aktiv = 1; bPause = FALSE; SetFocus(hwnd); SysMenu = GetSystemMenu(hwnd, 0); if(!SysMenu) return 0; RemoveMenu(SysMenu, SC_SIZE, MF_BYCOMMAND); EnableWindow(hwndButtonStart, FALSE); EnableWindow(hwndButtonPause, TRUE); EnableWindow(hwndButtonEnde, TRUE); EnableWindow(hwndButtonWand, FALSE); EnableWindow(hwndEditZeit, FALSE); EnableWindow(hwndEditVerlaengerung, FALSE); return 0; case ID_BUTTON_ENDE: KillTimer(hwnd, Timer_ID); aktiv = 0; iPunkte = 0; AppendMenu(SysMenu, MF_MENUBREAK, SC_SIZE, NULL); //SC_SIZE wieder in Menü einfügen InvalidateRect(hwnd, NULL, TRUE); EnableWindow(hwndButtonStart, TRUE); EnableWindow(hwndButtonPause, FALSE); EnableWindow(hwndButtonEnde, FALSE); EnableWindow(hwndButtonWand, TRUE); EnableWindow(hwndEditZeit, TRUE); EnableWindow(hwndEditVerlaengerung, TRUE); return 0; case ID_BUTTON_PAUSE: if(bPause == TRUE) { ////////////////////////////// //Zeitabstände für Timer abfragen aus Edit GetWindowText(hwndEditZeit, cBuffer, 19); if(cBuffer[0] == '\0') { MessageBox(hwnd, "Bitte eine Zeit angeben!", "Fehler", MB_OK | MB_ICONINFORMATION); SetFocus(hwndEditZeit); return 0; } sscanf(cBuffer, "%d", &iZeit); if(iZeit > 0) SetTimer(hwnd, Timer_ID, iZeit, 0); else { MessageBox(hwnd, "Zeiteingabe zu klein!", "Fehler", MB_OK | MB_ICONINFORMATION); SetFocus(hwndEditZeit); return 0; } ////////////////////////////////////// //Wert, um den die Schlange wachsen soll aus Edit abfragen GetWindowText(hwndEditVerlaengerung, cBuffer, 19); if(cBuffer[0] == '\0') { MessageBox(hwnd, "Bitte einen Wert eingeben!", "Fehler", MB_OK | MB_ICONINFORMATION); SetFocus(hwndEditVerlaengerung); return 0; } sscanf(cBuffer, "%d", &iVerlaengerung); if(iVerlaengerung < 0 || iVerlaengerung > 100) { MessageBox(hwnd, "Die Zahl sollte >0 und <100 sein!", "Fehler", MB_OK | MB_ICONINFORMATION); SetFocus(hwndEditVerlaengerung); return 0; } /////////////////////////////////////////// SetTimer(hwnd, Timer_ID, iZeit, 0); bPause = FALSE; //Wird bei Start in Init_Schlage() gesetzt iPproPunkt = ((iVerlaengerung * 100) / iZeit) / ((xFelder * yFelder) / 100);//muss noch verbessert werden if(iPproPunkt < 1) iPproPunkt = 1; InvalidateRect(hwnd, NULL, TRUE); SetFocus(hwnd); EnableWindow(hwndButtonWand, FALSE); EnableWindow(hwndEditZeit, FALSE); EnableWindow(hwndEditVerlaengerung, FALSE); } else { KillTimer(hwnd, Timer_ID); bPause = TRUE; EnableWindow(hwndButtonWand, TRUE); EnableWindow(hwndEditZeit, TRUE); EnableWindow(hwndEditVerlaengerung, TRUE); } return 0; } } return 0; case WM_TIMER: befehl = 0; if(iPunkt[2] == 0)//Fresspunkt erstellen { iPunkt[0] = rand() % xFelder; iPunkt[1] = rand() % yFelder; iPunkt[2] = 1; for(i = 0; i <=iSchlLaenge + 1; i++)//Zusammenstoß mit Schlange verhindern if(iPosition[i][0] == iPunkt[0] && iPosition[i][1] == iPunkt[1] && iPosition[i][2] != 0) { i = 0; iPunkt[0] = rand() % xFelder; iPunkt[1] = rand() % yFelder; } } for(i = iSchlLaenge; i > 0; i--) //Nachrutschen der Schlangenteile { iPosition[i][0] = iPosition[i - 1][0]; iPosition[i][1] = iPosition[i - 1][1]; iPosition[i][2] = iPosition[i - 1][2]; } switch(iPosition[0][2]) { case RT_HOCH: if(SendMessage(hwndButtonWand, BM_GETCHECK, 0, 0) == BST_UNCHECKED) { if((iPosition[0][1] - 1) <= 0) //Außenbegrenzung oben { KillTimer(hwnd, Timer_ID); MessageBox(hwnd, "Ende", "Ende", MB_OK); EnableWindow(hwndButtonStart, TRUE); EnableWindow(hwndButtonPause, FALSE); EnableWindow(hwndButtonEnde, FALSE); EnableWindow(hwndButtonWand, TRUE); EnableWindow(hwndEditZeit, TRUE); EnableWindow(hwndEditVerlaengerung, TRUE); AppendMenu(SysMenu, MF_MENUBREAK, SC_SIZE, NULL); //SC_SIZE wieder in Menü einfügen aktiv = 0; return 0; } iPosition[0][1] -= 1; //Neue Position des Schlangenkopfs } else { if((iPosition[0][1] - 1) <= 0) iPosition[0][1] = yFelder; else iPosition[0][1] -= 1; } if(iPrevRichtung != RT_HOCH) if(iPrevRichtung == RT_LINKS) iPosition[1][2] = BG_RECHTS; else iPosition[1][2] = BG_HOCH; else iPosition[1][2] = SENKRECHT; iPrevRichtung = RT_HOCH; break; case RT_RECHTS: if(SendMessage(hwndButtonWand, BM_GETCHECK, 0, 0) == BST_UNCHECKED) { if((iPosition[0][0] + 1) > xFelder)//Außenbegrenzung rechts { KillTimer(hwnd, Timer_ID); MessageBox(hwnd, "Ende", "Ende", MB_OK); EnableWindow(hwndButtonStart, TRUE); EnableWindow(hwndButtonPause, FALSE); EnableWindow(hwndButtonEnde, FALSE); EnableWindow(hwndButtonWand, TRUE); EnableWindow(hwndEditZeit, TRUE); EnableWindow(hwndEditVerlaengerung, TRUE); AppendMenu(SysMenu, MF_MENUBREAK, SC_SIZE, NULL); //SC_SIZE wieder in Menü einfügen aktiv = 0; return 0; } iPosition[0][0] += 1; //Neue Position des Schlangenkopfs } else { if((iPosition[0][0] + 1) > xFelder) iPosition[0][0] = 1; else iPosition[0][0] += 1; } if(iPrevRichtung != RT_RECHTS) if(iPrevRichtung == RT_HOCH) iPosition[1][2] = BG_RUNTER; else iPosition[1][2] = BG_RECHTS; else iPosition[1][2] = WAAGRECHT; iPrevRichtung = RT_RECHTS; break; case RT_RUNTER: if(SendMessage(hwndButtonWand, BM_GETCHECK, 0, 0) == BST_UNCHECKED) { if((iPosition[0][1] + 1) > yFelder) //Außenbegenzung unten { KillTimer(hwnd, Timer_ID); MessageBox(hwnd, "Ende", "Ende", MB_OK); EnableWindow(hwndButtonStart, TRUE); EnableWindow(hwndButtonPause, FALSE); EnableWindow(hwndButtonEnde, FALSE); EnableWindow(hwndButtonWand, TRUE); EnableWindow(hwndEditZeit, TRUE); EnableWindow(hwndEditVerlaengerung, TRUE); AppendMenu(SysMenu, MF_MENUBREAK, SC_SIZE, NULL); //SC_SIZE wieder in Menü einfügen aktiv = 0; return 0; } iPosition[0][1] += 1; //Neue Position des Schlangenkopfs } else { if((iPosition[0][1] + 1) > yFelder) iPosition[0][1] = 1; else iPosition[0][1] += 1; } if(iPrevRichtung != RT_RUNTER) if(iPrevRichtung == RT_LINKS) iPosition[1][2] = BG_RUNTER; else iPosition[1][2] = BG_LINKS; else iPosition[1][2] = SENKRECHT; iPrevRichtung = RT_RUNTER; break; case RT_LINKS: if(SendMessage(hwndButtonWand, BM_GETCHECK, 0, 0) == BST_UNCHECKED) { if((iPosition[0][0] - 1) <= 0) //Außenbegrenzung links { KillTimer(hwnd, Timer_ID); MessageBox(hwnd, "Ende", "Ende", MB_OK); EnableWindow(hwndButtonStart, TRUE); EnableWindow(hwndButtonPause, FALSE); EnableWindow(hwndButtonEnde, FALSE); EnableWindow(hwndButtonWand, TRUE); EnableWindow(hwndEditZeit, TRUE); EnableWindow(hwndEditVerlaengerung, TRUE); AppendMenu(SysMenu, MF_MENUBREAK, SC_SIZE, NULL); //SC_SIZE wieder in Menü einfügen aktiv = 0; return 0; } iPosition[0][0] -= 1; //Neue Position des Schlangenkopfs } else { if((iPosition[0][0] - 1) <= 0) iPosition[0][0] = xFelder; else iPosition[0][0] -= 1; } if(iPrevRichtung != RT_LINKS) if(iPrevRichtung == RT_HOCH) iPosition[1][2] = BG_LINKS; else iPosition[1][2] = BG_HOCH; else iPosition[1][2] = WAAGRECHT; iPrevRichtung = RT_LINKS; break; } for(i = 1; i <=iSchlLaenge + 1; i++) //Damit sich Schlange nicht selbst beist if(iPosition[i][0] == iPosition[0][0] && iPosition[i][1] == iPosition[0][1] && iPosition[i][2] != 0) { KillTimer(hwnd, Timer_ID); MessageBox(hwnd, TEXT("Ende"), TEXT("Ende"), MB_OK); EnableWindow(hwndButtonStart, TRUE); EnableWindow(hwndButtonPause, FALSE); EnableWindow(hwndButtonEnde, FALSE); EnableWindow(hwndButtonWand, TRUE); EnableWindow(hwndEditZeit, TRUE); EnableWindow(hwndEditVerlaengerung, TRUE); AppendMenu(SysMenu, MF_MENUBREAK, SC_SIZE, NULL); //SC_SIZE wieder in Menü einfügen aktiv = 0; return 0; } if(iPunkt[0] == iPosition[0][0] && iPunkt[1] == iPosition[0][1]) //Schlange wird länger { iPunkt[2] = 0; //Punkt wird nicht mehr angezeigt, da gefressen iSchlLaenge += iVerlaengerung; //Wert um den die Schlange länger wird iPunkte += iPproPunkt; InvalidateRect(hwnd, NULL, TRUE); } else InvalidateRect(hwnd, &rectUpdate, TRUE); return 0; case WM_DESTROY: DeleteObject(hBrush); PostQuitMessage(0); return 0; } return DefWindowProc(hwnd, message, wParam, lParam); } int Init_Schlange(int anzahl) //anzahl = Länge der Schlange am Anfang { int i; iPunkt[0] = iPunkt[1] = iPunkt[2] = 0; //Kein Punkt zum auffressen 0 = xKoordinaten, 1 = yKo., 2 = status iPrevRichtung = RT_HOCH; //Anfangsrichtung befehl = 0; //Keine Eingabe vorhanden iSchlLaenge = anzahl; //Anfangs-Schlangenlänge auf 20 setzten iPunkte = 0; //Startpunktzahl festlegen iPproPunkt = ((iVerlaengerung * 100) / iZeit) / ((xFelder * yFelder) / 100);//muss noch verbessert werden if(iPproPunkt < 1) iPproPunkt = 1; for(i = 0; i < MAX - 1; i++) iPosition[i][0] = iPosition[i][1] = iPosition[i][2] = 0; //Startwerte festlegen, Schlange steht Senkrecht, Kopf ist oben //Kopf iPosition[0][0] = xFelder / 2; iPosition[0][1] = yFelder / 2; iPosition[0][2] = RT_HOCH; //Richtung nächstes Feld //Rest der Schlange for(i = 1; i < anzahl + 1; i++) { iPosition[i][0] = xFelder / 2; iPosition[i][1] = yFelder / 2 + i; iPosition[i][2] = SENKRECHT; //Ausrichtung des Schlangteils } InvalidateRect(hwndHauptFenster, NULL, TRUE); return 1; } LRESULT CALLBACK ChildWndProcEditZeit(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HWND hhwnd; hhwnd = GetFocus(); switch(message) { case WM_KEYDOWN: switch(wParam) { case VK_TAB: if(hhwnd == hwndEditZeit) { SetFocus(hwndEditVerlaengerung); SetWindowText(hwndEditVerlaengerung, TEXT("")); return 0; } if(hhwnd == hwndEditVerlaengerung) { SetFocus(hwndEditZeit); SetWindowText(hwndEditZeit, TEXT("")); return 0; } break; } } if(hwnd == hwndEditZeit) return CallWindowProc((WNDPROC) PrevWndProcEditZeit, hwnd, message, wParam, lParam); if(hwnd == hwndEditVerlaengerung) return CallWindowProc((WNDPROC) PrevWndProcEditVerlaengerung, hwnd, message, wParam, lParam); }
-
Also ich habe mir das jetzt nicht ganz durchgelesen, aber ich glaube das wird sich auch niemand antun. Naja, ich habs mal in den Compiler geschmissen und geguckt was passiert. Du scheinst Compiler-Warnungs resistent zu sein? Denn bevor das Ganze überhaupt lief, musste ich erstmal zwei Casts einfügen und eine Funktion vorwärtsdeklarieren..
Auch danach fallen dem Compiler(!) noch Sachen auf:
(105): warning C4101: 'hPen1': Unreferenzierte lokale Variable
(104): warning C4101: 'hRgnTemp': Unreferenzierte lokale Variable
(779): warning C4715: "ChildWndProcEditZeit": Nicht alle Steuerelementpfade geben einen Wert zurück.Und warum nimmt man sscanf() für eine String->Int konvertierung??^^
Zu deutschen Variablennamen sage ich jetzt einfach mal nichts..
Was noch auffällt, sind endlose Code-Wiederholungen.
Ich habe vor etwas längerer Zeit man etwas vergleichbares geschrieben, nur hat das auf ca. 200 Zeilen gepasst. Und ich achte noch darauf 80 Zeichen in einer Zeile nicht zu überschreiten
Das Ganze "EnableWindow" Zeug kann man doch in eine kleine Funktion packen, damit wären wahrscheinlich schon mal 100 Zeilen weg.Zudem finde ich das mit dem "befehl" bei der Eingabeverarbeitung unglücklich gelöst, es sollte doch immer die letzte Eingabe vor der "Runde" zählen. Besser wäre eine Art "direction" und "cur_direction". Damit kann man immer korrekt vergleichen, und trotzdem zählt die letzte Eingabe. (Bei jeder Runde wird cur_direction dann zu direction).
#define MAX 4000
Ist auch wieder mal ein gutes Beispiel für eine viel zu kurze, nichtssagende Konstanten.
Rückgabewert von RegisterClass wird nicht geprüft.
Rückgabewert von CreateWindow wirdnichtnie geprüft.Die Buttons/Editfelder/etc. sind bei mir im übrigen alle übereinander, war gar nicht so einfach das Spiel überhaupt zu starten
Als generellen Tipp kann ich dir vielleicht mitgeben dass Du wirklich versuchen solltest gleichen oder ähnlichen Code irgendwie in Funktionen zu packen damit das ganze übersichtlicher wird. Sich wiederholender Code sollte möglichst vermieden werden, dafür gibts schießlich Funktionen.
So, das wars was mir bei kurzen überfliegen aufgefallen ist, ich hoffe ich habe nicht zu viel kritisiert, keine sorge, man kann sich natürlich noch verbessern
PS:
Zudem gehören "Code-Reviews" etc. wohl eher ins Projekte Forum.
-
erstmal thx für deinen (den einzigen ) beitrag,
ich hoffe ich habe nicht zu viel kritisiert
das war ja der Sinn der Sache , je mehr desto besser
zu
Du scheinst Compiler-Warnungs resistent zu sein?
auf die Warnungen hab ich echt nicht geachtet
und
Denn bevor das Ganze überhaupt lief, musste ich erstmal zwei Casts einfügen und eine Funktion vorwärtsdeklarieren..
also bei mir läuft das ohne Probleme und die Buttons sind auch nebeneinander. wo musstest du denn was einfügen?
was wäre denn eine alternative zu sscanf, in den Beispielen mit denen ich c-gelernt hab, wurde das immer benutzt
-
Nutzt Du den GCC Compiler? Dann compiler mal mit -Wall (hoffe ich erinnere mich da richtig) und geh ALLE Warnungen durch und versuche nachzuvollziehen warum diese ausgegeben werden.
Alternative zu sscanf wäre atoi
-
Nein, ich nutze VS2010. Ich hab meinen Code jetzt verbessert und fast alle warnungen weg. Ich bekomm noch für die Zeile
PrevWndProcEditZeit = SetWindowLong(hwndEditZeit, GWLP_WNDPROC, (LONG_PTR) ChildWndProcEditZeit);
die meldung
warning C4047: '=': Anzahl der Dereferenzierungen bei 'HWND' und 'LONG' unterschiedlich
was stimmt da nicht?
Außdem schmiert das Programm irgendwann ab, wenn die Schlange immer länger wird. Zuerst werden die Punkte nicht mehr gefüllt (sonst läuft alles weiter) bis ich irgendwo anstoß. Dann geht gar nichts mehr. Könnte das an den vielen Teilen sein die pro Schritt immer wieder gezeichnet werden?
-
Der Returnwert von SetWindowLong muss ebenfalls gecastet werden. Besser wäre es auch, gleich SetWindowLongPtr zu verwenden.
Außerdem:
SelectObject(hdc, CreateSolidBrush(RGB(0, 0, 0)));
Bei jedem Neuzeichnen des Fensters wird ein neuer Brush erstellt, der nicht wieder freigegeben wird. Irgendwann ist die maximale Anzahl an GDI-Handles erreicht und es passiert, wie beschrieben, nichts mehr.
Einen schwarzen Brush braucht man auch nicht selber erstellen, GetStockObject(BLACK_BRUSH)
liefert so einen (auch hier ist ein Cast nötig).
-
Dieser Thread wurde von Moderator/in Martin Richter aus dem Forum WinAPI in das Forum Projekte verschoben.
Im Zweifelsfall bitte auch folgende Hinweise beachten:
C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?Dieses Posting wurde automatisch erzeugt.
-
neo47 schrieb:
Könnte das an den vielen Teilen sein die pro Schritt immer wieder gezeichnet werden?
Im übrigen musst Du eigentlich immer nur den Kopf und das letzte Teil neu zeichnen..
-
Snake ist eine Schlange, die gefährlich beissen kann. Dein Code wohl auch. Also, was willst du machen?
-
@_FALKE: thx, alle warnungen weg und der Fehler taucht auch nicht mehr auf.
@coody451: Ja, sowas hatte ich im Kopf, werd das gleich mal so machen.