Mauskoordinaten komfortabel abfragen ?
-
Habe folgendes Problem.
Frage in meinem Programm die Mauskoordinaten ab, um zu gucken, ob auf einem bestimmten Bereich geklickt wurde.Mauskoordinaten holen:
// in Callback-Funktion: case WM_LBUTTONDOWN: PosX = LOWORD( lParam ); PosY = HIWORD( lParam );Dann gucke ich, ob der Klick in einem bestimmten Bereich war und lasse passend die Anweisung ausführen:
if (((PosX > x_0) && (PosX < x_0+50)) && ((PosY > y_0) && (PosY < y_0+50))) { Direct3D.change_Card(0); } else if // [...]Geht das auch noch komfortabler?
Weil ich habe ein Memory-Spiel mit 36 Karten, also 36 Bereichen und so werden das total viele if-Verzweigungen....Hoffe mal, ihr habt nen paar Tipps für mich!
MfG
Hundefutter
-
GetCursorPos()
PtInRect()
EqualRect()
PtInRegion()
RectInRegion()Vllt. hilft dir das...
-
Sind das schon vorgegebene Funktionen? Wenn ja, welche Bibliothek?
Oder beschreibt das einfach nur die Vorgehensweise?MfG
Hundefutter
-
Das sind WinAPI-Funktion...
PtInRect sollte eigentlich das sein, was Du suchst...
-
siehe Jochens Post...
Wichtig/hilfreich ist vllt noch die Funktion ScreenToClient(...), der die Koordinaten auf Client-Koordinaten auf dein Fenster umrechnet.
-
Alles klar, danke für die Antworten.
Lese mir dann mal nen paar Sachen zu den Funktionen durch und versuche die dann mal einzubauen. Vielen Dank!MfG
Hundefutter
-
Habe mir jetzt mal die Funktion PtInRect() angeguckt.
Jetzt müsste ich ja für jede Karte ein Rechteck anlegen und dann trotzdem noch mit if überprüfen, ob die Mauskoordinate in dem Rechteck liegt, oder?
Das würde das ganze zwar etwas vereinfachen, aber um die riesige if-Verzweigung komme ich ich trotzdem nicht herum....Naja, wenigstens eine kleine Verbesserung

MfG
Hundefutter
-
Ich nehme mal an, dass die Memorykarten regelmässig über den Bildschirm verteilt sind.
Dann könntest du mit folgender Formel die Spalte und die Zeile der Karte herausbekommen, sofern die Karten direkt aneinander liegen.int zeile = PosY / kartenHoehe; int spatle = PosX / kartenBreite;Dann müsstest du nur noch die Koordinaten (zeile, spalte) in die "Kartennummer" umrechnen.
-
Hundefutter schrieb:
Jetzt müsste ich ja für jede Karte ein Rechteck anlegen und dann trotzdem noch mit if überprüfen, ob die Mauskoordinate in dem Rechteck liegt, oder?
Nein.
Hundefutter schrieb:
Das würde das ganze zwar etwas vereinfachen, aber um die riesige if-Verzweigung komme ich ich trotzdem nicht herum....
Doch:
RECT rect; rect.top = 10; rect.bottom = 20; rect.left = 10; rect.right = 20; POINT pt; pt.x = 15; pt.y = 15; if( PtInRect( &rect, pt ) ) { ; // mach sonstwas. }Greetz, Swordfish
-
Nun habe ich 36 rechtecke. Kann ich jetzt mit ner for-schleife arbeiten und dann mit jedem durchlauf die Rechteck-Koordinaten verschieben?
Also:RECT rect; rect.top = 10; rect.bottom = 20; rect.left = 10; rect.right = 20; POINT pt; pt.x = PosX; //Mauskoordinate X pt.y = PosY; //Mauskoordinate Y for(int i=0;i<36;i++) { if( PtInRect( &rect, pt ) ) { ; // mach sonstwas. } //if //Rechteck verschieben rect.top += 80; // [...] } //forProbiere es jetzt so mal aus, wenn das falsch ist, ober es besser anders zu machen ist, bitte sagen.
Danke für die Hilfen!MfG
Hundefutter--------------
EDIT:Alles klar, funktioniert so gut mit der For-Schleife!
Vielen Dank!
-
und was bringt hier die for-Schleife?
Greetz, Swordfish
-
Swordfish schrieb:
und was bringt hier die for-Schleife?
Greetz, Swordfish
Also ich habe mir das so gedacht:
Mit dem folgenden Quellcode durchlaufe ich die erste Reihe, also die ersten 6 Karten.//in der Callback-Funktion: case WM_LBUTTONDOWN: //Mauskoordinaten in einem Punkt speichern POINT pt; pt.x = LOWORD( lParam ); pt.y = HIWORD( lParam ); //Ein Recheck definieren, welches dann immer verschoben wird RECT rect; rect.left = 250; rect.top = 150; rect.right = 300; rect.bottom = 200; //Mit Hilfe einer For-Schleife Abfragen und das Rechteck verschieben for(i=0;i<6;i++) { if(PtInRect( &rect, pt )) { Direct3D.change_Card(i); }; //Rechteck verschieben rect.left += 80; rect.right += 80; }; break;Dafür brauche ich dann doch die For-Schleife, oder nicht?
MfG
Hundefutter
-
Achso, ja, passt schon.
Greetz, Swordfish
-
Ok.
So ist das ganze natürlich schon viel kürzer und komfortabler.Wenn das jetzt noch zu steigern ist, bitte melden.
Nochmals vielen Dank für die Hilfen.
MfG
Hundefutter
-
for (unsigned int i = 0; i < 6; ++i) { if (PtInRect(&rect, pt)) Direct3D.change_Card(i); //Rechteck verschieben rect.left += 80; rect.right += 80; }
Ist nicht wirklich kürzer... aber nen Bissel
..
-
@(D)Evil: Witzkeks

Greetz, Swordfish
-
Ich weiß ja nicht ob es beabsichtigt ist aber bei
case WM_LBUTTONDOWN:wird die WM andauernd gesendet und schluckt somit Zeit ...
Mit
case WM_LBUTTONUP:geschieht alles wenn du die Taste loslässt...also nur einmal
MfG Kuldren
-
Wenn die Karten immer an festen Positionen sind, warum definierst du dir nicht deine 36 Rechtecke in einem globalen Array?
RECT CardRect[36];Dann kannst du in der Behandlungroutine schreiben
case WM_LBUTTONUP: //Mauskoordinaten in einem Punkt speichern POINT pt; pt.x = LOWORD( lParam ); pt.y = HIWORD( lParam ); for(i=0;i<36;++i) { if( PtInRect( &rect[i], pt ) ) Direct3D.change_Card(i); } break;Was noch effizienter wäre: Alle Rechtecke in einer Region zusammenfassen. Dann kannst du erstmal abfragen, ob sich der Cursor in der Region befindet mit PtInRgn() (oder so ähnlich) und dann erst in die for-Schleife gehen.
-
Habe es jetzt folgendermaßen aufgebaut:
case WM_LBUTTONUP: //Mausklick-Zähler um 1 erhöhen click_zaehler++; //Mauskoordinaten in einem Punkt speichern POINT pt; pt.x = LOWORD( lParam ); pt.y = HIWORD( lParam ); //Ein Recheck definieren, welches dann immer verschoben wird RECT rect; rect.left = 250; rect.top = 150; rect.right = 300; rect.bottom = 200; //Mit Hilfe einer For-Schleife Abfragen und das Rechteck verschieben for(i=0;i<36;i++) { if(PtInRect( &rect, pt )) { Direct3D.change_Card(i); } //Rechteck verschieben rect.left += 80; rect.right += 80; if(i == 5) //Wechsel in Zeile 2 { rect.left = 250; rect.top = 230; rect.right = 300; rect.bottom = 280; } else if (i == 11) //Wechsel in Zeile 3 { rect.left = 250; rect.top = 310; rect.right = 300; rect.bottom = 360; } else if (i == 17) //Wechsel in Zeile 4 { rect.left = 250; rect.top = 390; rect.right = 300; rect.bottom = 440; } else if (i == 23) //Wechsel in Zeile 5 { rect.left = 250; rect.top = 470; rect.right = 300; rect.bottom = 520; } else if (i == 29) //Wechsel in Zeile 6 { rect.left = 250; rect.top = 550; rect.right = 300; rect.bottom = 600; }; //if }; //for break;Könnte das mit dem Rechteck-Array noch machen. Würde sich das noch sehr positiv auf die Performance des Programms auswirken?
Wenn ja, dann baue ich das gerne ncoh ein.MfG
Hundefutter
-
Hundefutter schrieb:
Könnte das mit dem Rechteck-Array noch machen. Würde sich das noch sehr positiv auf die Performance des Programms auswirken?
Naja, nicht wirklich merkbar. Aber trotzdem würde ich das so machen. Erstens wird der Code so besser lesbar und zweitens: wer weiß, wozu du die Rechtcke noch brauchst... Dann musst du wieder das Geschiebe da machen.