Problem: Kniffel mit LLC und WinAPI
-
Hi,
ich hoffe ich bin mit meiner Frage hier im richtigen Bereich.
Ich muss an meiner Hochschule als Projekt das Spiel Kniffel mit dem LLC-Compiler programmieren. Das ganze soll dann als A+eusführbare Exe-Datei selbständig laufen. Die Ausgabe und Steuerung erfolgt über WinAPI (soweit ich das verstehe).
Ich bin komplett kein Programmierer und habe davon auch wenig Ahnung. Durch das gelernte der Vorlesung habe ich auch schon einen Teil machen können. Nur stecke ich nun seit ein paar Tagen fest und weiß nicht weiter.
Mein Problem ist die Steuerung des Spiels mit der Maus. Man muss die Würfel auswählen können, die man neu wirft. Dabei werden die Punkte der würfel rot.
http://www7.pic-upload.de/thumb/21.05.13/lvh4dtli99.jpg
Nur versteh ich nicht wie man das auswählen der Würfel umsetzt.
Ich wollte das bis jetzt so realisieren, dass das Programm beim Mausklick erkennt in welchem Bereich geklickt wurde und daran den Würfel markiert oder eine Aktion ausführt.
Das wollte ich durch eine do/while Schliefe lösen. In dieser wird dann die abfrage der geklicken Bereiche durch eine If Auswahl gesteuert. Daraufhin wird das ganze Bild wieder neu gezeichnet (das zeichnen des Bildes wird durch eine einzelne Funktion gemacht).
Nun habe ich schon verschiedene Varianten versucht, und jedesmal hängt sich mein Programm auf, was wohl an der do/while Schleife liegt.
Deshalb meine Frage, wie kann ich realiseren das mein Programm wartet bis die Maustaste gedrückt wird, und dann dadurch die Koordinaten des Mauszeigers abfragt und zB. das Spiel mit markiertem Würfel neu zeichnet.
Gibs dazu irgendwo Beispiele wie man das Umsetzt?
Also richtige für Dummies?
Hab schon einige Tutoriale gelesen, aber da gib es keines für meinen Fall.Hier noch der Code meiner *.c der Maussteuerungsdatei:
-------------------------------------------------------------->*/ /*@@2->@@*/ LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam) { POINT punkt; switch (msg) { /*@@3->@@*/ case WM_SIZE: SendMessage(hWndStatusbar,msg,wParam,lParam); InitializeStatusBar(hWndStatusbar,1); break; case WM_MENUSELECT: return MsgMenuSelect(hwnd,msg,wParam,lParam); case WM_COMMAND: HANDLE_WM_COMMAND(hwnd,wParam,lParam,MainWndProc_OnCommand); break; case WM_DESTROY: PostQuitMessage(0); break; // Maussteuerung case WM_LBUTTONDOWN: maus_x = LOWORD( lParam ); maus_y = HIWORD( lParam ); break; case WM_LBUTTONUP: break; default: return DefWindowProc(hwnd,msg,wParam,lParam); } /*@@3<-@@*/ return 0; } /*@@2<-@@*/
Hier der Code zum Steuern des Programms (hier mit Switch versucht, do/while ausgegraut):
int z = 0; //do //{ switch (m_lb) { case 1: if ( (maus_y >= 100) && (maus_y <= 160) ) { if ( (maus_x >= 10) && (maus_x <= 70) ) { w1_mark = 1; } if ( (maus_x >= 80) && (maus_x <= 140) ) { w2_mark = 1; } if ( (maus_x >= 150) && (maus_x <= 210) ) { w3_mark = 1; } if ( (maus_x >= 220) && (maus_x <= 280) ) { w4_mark = 1; } if ( (maus_x >= 290) && (maus_x <= 350) ) { w5_mark = 1; } } printf("x = %5i y = %5i \n\n", maus_x, maus_y); zeichnen(hwnd); // m_lb = 0; z = z + 1; break; } //} //while (z != 1);
-
Ok, hab es mit Hilfe hinbekommen.
Threat kann geschlossen werden.
-
Wolfi_1988 schrieb:
Ok, hab es mit Hilfe hinbekommen. Threat kann geschlossen werden.
Lässt Du uns an deinen neuen Erkenntnissen teilhaben ?
Ich habs aus Spass mal ausprobiert und es sollte in etwa so aussehen:
case WM_LBUTTONDOWN: { // Bei Mausklick erkennen in welchem Bereich geklickt wurde, den Würfel markieren, Punkte des Würfels rot färben. maus_x = GET_X_LPARAM(lParam); maus_y = GET_Y_LPARAM(lParam); int nr = FindeWuerfel(maus_x, maus_y); Wuerfel[nr].color = WCOL_RED; RedrawWindow(hMainWin, NULL, NULL, RDW_INVALIDATE); } break;
Wobei ich die Würfel hier in einer Struktur verwaltet werden:
// Definition eines Wuerfels (Position, Wert, Farbe) typedef struct { int x, y, wert, color; } WuerfelDefTyp; // Position, Wert, Farbe der 5 Würfel WuerfelDefTyp Wuerfel[6] = { ...
Und wie üblich in WM_Paint alles zeichnen ...
-
Der Fehler war das ich alles im Unterprogramm machen wollte, über Variablen gesteuert.
Musste einfach nur die Auswahl in das Hauptprogramm schreiben, dann ging es.
case WM_LBUTTONDOWN: maus_x = LOWORD( lParam ); maus_y = HIWORD( lParam ); // Würfel markieren if ( (maus_y >= 100) && (maus_y <= 160) ) { if ( (maus_x >= 10) && (maus_x <= 70) ) { if (w1_mark == 1) { w1_mark = 0; } else { w1_mark = 1; } } if ( (maus_x >= 80) && (maus_x <= 140) ) { if (w2_mark == 1) { w2_mark = 0; } else { w2_mark = 1; } } if ( (maus_x >= 150) && (maus_x <= 210) ) { if (w3_mark == 1) { w3_mark = 0; } else { w3_mark = 1; } } if ( (maus_x >= 220) && (maus_x <= 280) ) { if (w4_mark == 1) { w4_mark = 0; } else { w4_mark = 1; } } if ( (maus_x >= 290) && (maus_x <= 350) ) { if (w5_mark == 1) { w5_mark = 0; } else { w5_mark = 1; } } }
Bin jetzt auch fast fertig mit dem Spiel. Fehlen nur noch die ein paar Funktionen für kleine Straße usw.
-
Bei mir funktioniert es Super im Unterprogramm FindeWuerfel(). Das toggeln könnte man noch einbauen.
ungestest:
if(Wuerfel[nr].color == WCOL_BLACK) Wuerfel[nr].color = WCOL_RED; else Wuerfel[nr].color = WCOL_BLACK;
Wie bekommt deine GUI denn die Änderung mit?
Können wir einen Link bekommen wenns fertig ist
-
Also ich habe auch lauter Globale Variable für den Status der Tabelle (markiert/unmarkiert).
Nach einem Mausklick wird dann am schluss durch eine große Funktion (zeichnen) das komplette Spielfeld gezeichnet abhängig von diesen Globalen Variablen (mit markierten Würfel, Tabelle usw.).
Das größte Problem war dann noch die ganzen Bedienungen für die Ergebnisse.
---
-
Der obere Link funktioniert nicht.
Hier der richtige Link der geht:
-
Habe die Version gerade angetestet.
Download und Start haben funktioniert.
Ein Testspiel ging auch erstmal - bis ich die Hilfe aufgerufen habe.
Danach war ein grosser Teil des Spielfeldes weg und wurde auch nicht neu gezeichnet.Es ist auch so, das man das Spielfeld mit dem Hilfedialog regelrecht wegradieren kann.
Wenn man das Fenster vergrössert oder verkleinert oder in die Symbolleite
minimiert ist es danach auch leer.Vergrössern, Verkleinern und Minimieren könnte man (notfalls) abschalten, allerdings
sollte sich das Fenster unbedingt wieder neu aufbauen wenn es z.B. von einem anderen Fenster verdeckt wurde.merano schrieb:
Wie bekommt deine GUI denn die Änderung mit?
Vermutlich war die Frage nicht unberechtigt und die Antwort würde das Problem lösen ..
-
Du darfst nur in WM_PAINT zeichnen. Wenn das Fenster eine Änderung benötigt sendet Windows WM_PAINT.
Scheinbar reagierst Du nicht korrekt auf WM_PAINT.
-
Danke für die Hinweise!
@ Merano:
Ich weis was Du meinst, und wenn man in das Fenster klickt dann ist das Bild wieder da (durch eine if_Funktion).@ Martin:
Ich hab keinen Plan wovon Du redest.
Unser Prof hat dazu extrem wenig erklärt und uns im Prinzip nur ne Anleitung gegeben wie man anfängt und wo was stehen muss.
-
Wolfie_1988 schrieb:
@ Merano:
Ich weis was Du meinst, und wenn man in das Fenster klickt dann ist das Bild wieder da (durch eine if_Funktion).@ Martin:
Ich hab keinen Plan wovon Du redest.
Unser Prof hat dazu extrem wenig erklärt und uns im Prinzip nur ne Anleitung gegeben wie man anfängt und wo was stehen muss.Martin und ich sprechen über die gleiche Baustelle ...
Wir versuchen Dich darauf aufmerksam zu machen, das man alle Zeichenbefehle
ausschliesslich in WM_PAINT verwendet. Du zeichnest nur als Reaktion auf
Mausklicks, was natürlich nichts nützt wenn Windows das Fenster neu zeichnen muss.
->Ich hatte oben auch schon Beispielcode gepostet ...Das das Fenster sich nicht neuzeichnet oder leerradiert werden kann, ist aus Anwendersicht unerwartet.
Wenn im Skript Deines Profs was anderes stehen sollte wäre das schlicht falsch.
PS: Hier mein Gerüst zur Ansicht:
http://remixshare.com/dl/nj2yj/kniffel1.exeHinweise:
- Der Hintergrund besteht aus der von Dir vorgeschlagenen Bitmap
- Zur Positionsbestimmung lasse ich die Mausposition in der Statusbar anzeigen.
- Gezeichnet werden nur die Würfelpunkte in schwarz oder rot (wobei die Bitmap
eigentlich keine Würfelpunkte enthalten sollte)
-
Lies ein Tutorial. Man zeichnet nur in WM_PAINT!
http://suite101.com/article/win32-drawing-wm-paint-processing-a26003