Anwählen von Objekten

Hallo,
ich hab mal ne Frage wie man erkennen kann, ob sich der Mauszeiger über einem bestimmten Objekt befindet.

Bei 3D-Modellen kann man die Kollision eines Strahls mit einem Modell berechnen, aber wie macht man das mit 2D-Bildern? Wenn diese Rechteckig sind, geht das noch, dann kann man direkt mit den x- und y-Koordinaten rechnen.
Bei Age of Empires II z.B. gibt es im Hauptmenü das Schild mit zwei gekreuzten Schwerten davor um den Multiplayer auszuwählen. Fährt man jetzt mit der Mauszeiger zwischen die Schwerter ist das Objekt noch nicht angewählt, obwohl man sich schon in dem Bild-Rechteck befindet. Erst wenn man sich wirklich über einem der Schwerter oder dem Schild befindet ist das Objekt angewählt.

Gibt es dafür einen Trick oder muss man für das ganze Bild eine Art 2D - Array anlegen, wo für jedem Pixel vermerkt ist, ob dieser schon zu dem Objekt zählt oder nicht? Das wäre aber sehr aufwändig, geht das nicht einfacher?

Vielen Dank für eine Antwort

Manny

Hallo Manny,

Bei 3D-Modellen kann man die Kollision eines Strahls mit einem
Modell berechnen, aber wie macht man das mit 2D-Bildern? Wenn
diese Rechteckig sind, geht das noch, dann kann man direkt mit
den x- und y-Koordinaten rechnen.

Rechnen brauchst Du da eigentlich nichts: es gibt ja die WIN-API-Funktion

RECT kastl = {20, 20, 200, 120};
PtInRect(&kastl, ...)

Weiss jetzt die Argumente nicht auswendig (Internet-Cafe), findest Du aber im MSDN. Die Maus-Koordinaten kriegt sie natürlich (den LPARAM der callback()).

Aber Du kannst es natürlich auch händisch machen, mit

POINT maus; // LPARAM hier rein
if (maus.x \>= kastl.left &&
 maus.x etc.



> Erst wenn man sich  
> wirklich über einem der Schwerter oder dem Schild befindet ist  
> das Objekt angewählt.


Ich kenne das Spiel nicht. Das könnte eine HREGION sein, mit beliebiger Form, für diese gibt es ebenfalls eine PtInRegion(), oder ähnlich, analog zum RECT s.o..



> , wo für jedem Pixel vermerkt ist,  
> ob dieser schon zu dem Objekt zählt oder nicht? Das wäre aber  
> sehr aufwändig, geht das nicht einfacher?


s.o. 
PS: manchmal ist es eine gute Idee, auch hinzuschreiben:
Welches System?
Welcher Compiler?
Welches Framework?

lg
Martin B

Hi Martin, vielen Dank für die schnelle Antwort!

if (maus.x >= kastl.left &&
maus.x

Hi Manny,

Was meinst du denn mit HREGION und PtInRegion genauer, ich
muss gestehen ich bin auf diesem Gebiet Anfänger,?

Da kann ich dir leider auch nicht weiterhelfen, aber „zu Fuß“ macht man sowas am einfachsten, indem man vom derzeitigen Punkt aus einen Strahl in eine beliebige Richtung schickt. Wenn die Anzahl der Schnittpunkte mit dem Umriss der fraglichen Figur gerade ist, dann bist du außerhalb, bei ungerader Anzahl innerhalb der Figur. Voraussetzung ist allerdings, dass die Figur nicht über den Rand des Zeichenbereichs hinausragt.

Gruß
ein anderer Martin

Hallo Manny,

Was meinst du denn mit HREGION und PtInRegion genauer, ich
muss gestehen ich bin auf diesem Gebiet Anfänger,?

Um mit WIN-API durchzusteigen, heisst es „Dampf dahinter machen“, da ist alles ehrlich verdient. Ich sehe nun diese Möglichkeiten:
1
Im MSDN diese zwei finden.
2
Googeln auf diese zwei.
3
Auf WIN-API-Seiten rein schauen, zB:
http://www.winapi.net
http://www.win-api.de/tutorials.php?SessID=69910c16f…
http://willemer.de/informatik/windows/winprg.htm
4
Buch anschauen, das ist die Bibel für WIN-API:
http://www.amazon.de/Windows-Programmierung-Das-Entw…

lg
Martin B

Hallo Manfred

Hallo,
ich hab mal ne Frage wie man erkennen kann, ob sich der
Mauszeiger über einem bestimmten Objekt befindet.

Bei 3D-Modellen kann man die Kollision eines Strahls mit einem
Modell berechnen, aber wie macht man das mit 2D-Bildern? Wenn
diese Rechteckig sind, geht das noch, dann kann man direkt mit
den x- und y-Koordinaten rechnen.

Jepp :o)

Bei Age of Empires II z.B. gibt es im Hauptmenü das Schild mit
zwei gekreuzten Schwerten davor um den Multiplayer
auszuwählen. Fährt man jetzt mit der Mauszeiger zwischen die
Schwerter ist das Objekt noch nicht angewählt, obwohl man sich
schon in dem Bild-Rechteck befindet. Erst wenn man sich
wirklich über einem der Schwerter oder dem Schild befindet ist
das Objekt angewählt.

Soweit ich weiss (und ich weiss nicht viel) kann man mit Hilfe einer Maske das Problem lösen. Also du erstellst eine Maske deines 2D Objekts in Schwarz/Weis anschliessend fragst du ab, ob der Bit gesetzt (Schwarz) => innerhalb von einem Objekt oder nicht gesetzt (Weis) => ausserhalb eines Objekts ist. Ich bin mir nicht sicher ob dafür API’s gibt in DirektX o.ä. sicher aber in „normalen“ Bibliotheken also Win32-API’s sind mir noch keine über den Weg gelaufen :o)

Gibt es dafür einen Trick oder muss man für das ganze Bild
eine Art 2D - Array anlegen, wo für jedem Pixel vermerkt ist,
ob dieser schon zu dem Objekt zählt oder nicht? Das wäre aber
sehr aufwändig, geht das nicht einfacher?

Ja das ist der Weg den ich oben beschrieben habe nur du nimmst kein Array sondern ein zusätzliches Bild (Maske). Zum erstellen der Masken gibt es Progs die es für dich erstellen. Das Ergebnis sind halt die Schwarz/Weis Masken deiner Bilder.

Vielen Dank für eine Antwort

Bitte

Manny

Ich hoffe es Hilft dir!

Gruß

Andreas

PS: Da ich mich zuwenig mit der Spieleprogrammierung auskenne kann ich dir nicht sagen, ob es vielleicht noch einfacher geht. Da musst du mal die entsprechenden Experten anhauen.

Man kann auf Die Maske verzichten, wenn das Bild transparente Pixel enthält.
Aber wie gesagt man muss Pixel für Pixel vergleichen um herauszufinden ob sich zwei Objekte berühren.
Da diese Operation sehr aufwändig ist, sollte man zuvor einen einfachen Check einbauen, ob überhaupt eine Kollision möglich ist. Z.B.: Bei Sprites die Rechtecke vergleichen und nur wenn sich diese schneiden dann den genauen Test durchführen.

Hi Andreas,
vielen Dank für die Antwort. Muss mal in der DirectX Doku nachgucken, wie man die Farbe eines Pixels bei einer bestimmten Position ermitteln kann. Auf jeden Fall danke, ich denke dieser Weg ist auf sehr viel einfacher als der mit dem Array :smile:

Viele Grüße
Manny