Anwählen von Objekten

Von: , Frage gestellt am Do, 21. Jun 2007

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

7 Antworten zu dieser Frage

  1. Antwort von nach 51 Minuten 0 hilfreich
    Re: Anwählen von Objekten

    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 < kastl.right)
    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

    • Antwort von nach einer Stunde 0 hilfreich
      Re^2: Anwählen von Objekten

      Hi Martin, vielen Dank für die schnelle Antwort! if (maus.x >= kastl.left &&
      maus.x < kastl.right)
      Das meinte ich ja, dass das einfach wäre, wenn es nur ein einfacher Kasten wäre. PS: manchmal ist es eine gute Idee, auch hinzuschreiben:
      Welches System?
      Welcher Compiler?
      Welches Framework?
      Ich fand das als nicht so wichtig: Aber System: Windows Xp Home, Compiler: Microsoft Visual C++ 6.0

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

      Viele Grüße
      Manny

      • Antwort von nach 16 Stunden 0 hilfreich
        Re^3: Anwählen von Objekten

        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

      • Antwort von nach einem Tag 0 hilfreich
        Re^3: Anwählen von Objekten

        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

  2. Antwort von nach 5 Tagen 0 hilfreich
    Re: Anwählen von Objekten

    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.

    • Antwort von nach 5 Tagen 0 hilfreich
      Re^2: Anwählen von Objekten

      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.

    • Antwort von nach 6 Tagen 0 hilfreich
      Re^2: Anwählen von Objekten

      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 :-)

      Viele Grüße
      Manny

Keine passende Antwort gefunden? Jetzt eigene Frage stellen!