Wie man mit Unterschieden zwischen 2D-Bildschirmkoordinaten und kartesischen Koordinaten umgeht


23
  • Bei den meisten 2D-Bildschirm- / Bitmap-Koordinatensystemen zeigt die positive Y-Achse nach unten (mit dem Ursprung in der oberen linken Ecke).
  • Dies widerspricht dem Denken der meisten Menschen geometrisch mit der positiven Y-Achse nach oben (mit dem Ursprung in der Mitte).

Wie verwalten die meisten Spiele die beiden unterschiedlichen 2D-Koordinatensysteme? Es gibt zwei Haupttypen von Koordinaten (Bildschirm oder kartesisch), aber es kann viele verschiedene Koordinatenräume geben: Sprite-Raum, Weltraum, Sichtraum, Bildschirmraum usw.

Hintergrund:

Ursprünglich habe ich die Weltkoordinaten in meinem Spiel der 2D-Bildschirmkoordinatenkonvention angepasst. Dies machte es sehr natürlich, die Grafikzeichnungsroutinen zu verwenden, aber bei der Verwendung von trigonometrischen Funktionen wie atan2 () traten subtile Probleme auf. Die Ergebnisse der Eingabe von atan2 () 2D-Bildschirmkoordinaten sind sehr verwirrend, da atan2 () davon ausgeht, dass die positive y-Achse nach oben zeigt.

Also änderte ich meine Weltkoordinaten, um dem klassischen kartesischen Koordinatensystem zu folgen (mit dem Ursprung unten links auf dem Bildschirm). Das Argumentieren mit atan2 () ist viel einfacher, aber jetzt ist es schwieriger, andere Argumentationsarten zu verwenden:

  • Wenn ich hier auf den Bildschirm klicke, welches Sprite befindet sich darunter?
  • Wo habe ich auf dieses Sprite geklickt?
  • Was wurde falsch berechnet, wenn ein Sprite an der falschen Stelle gezeichnet wurde? Die Bildschirmkoordinaten oder die Weltkoordinaten?

Ich erkenne, dass die Konvertierung von Bildschirmkoordinaten in kartesische Koordinaten das einfache Skalieren des y-Werts um -1 mit einer optionalen Übersetzung beider (x, y) -Werte umfasst. Ich bin mehr an Best Practices für das Game-Design interessiert:

  • Halten sich die meisten Spiele nur an die Bildschirmkoordinatenkonvention und ändern ihre Überlegungen darüber, wie Dinge wie atan2 () funktionieren sollten?
  • Wann und wie werden Koordinatensystemkonvertierungen durchgeführt? (Verwenden von Matrizen, OOP-Abstraktion usw.)
  • Werden Sprite-Positionen als Zentrum des Sprites oder als eine der Ecken gespeichert? Die Höhe / Breite des Sprites in die "falsche" Richtung scheint ein häufiges Problem zu sein, wenn ich sie zeichne.

Obwohl meine Frage hauptsächlich 2D-Spiele betrifft, scheint OpenGL ein Koordinatensystem zu verwenden, bei dem die Y-Achse nach oben zeigt. OpenGL muss diese 3D-Koordinaten schließlich auf ein 2D-Bildschirmkoordinatensystem projizieren. Vielleicht kann man in der OpenGL-Methode eine Anleitung finden ...

Antworten:


8

Nachdem ich alle erdenklichen Möglichkeiten ausprobiert habe, habe ich festgestellt, dass es sich bei dem Spiel um ein reines 2D-Spiel handelt. Verwenden Sie einfach das Bildschirmzeichnungssystem, um Ihr Leben zu vereinfachen. Sin, Cos und atan2 müssen etwas anders verwendet werden, aber diese Unannehmlichkeit lässt sich leicht durch die Einfachheit ausgleichen, zu wissen, wie hoch, runter, im Uhrzeigersinn und gegen den Uhrzeigersinn verfahren wird. Ich würde auch empfehlen, bei 2D-Spielen in Pixeln anstatt in Metern zu arbeiten - es ist viel einfacher, über Entfernungen auf dem Bildschirm nachzudenken, und die Chancen, dass Sie den gesamten Maßstab Ihres Spiels ändern möchten, liegen nahe bei Null.

"Wie verwalten die meisten Spiele die beiden unterschiedlichen 2D-Koordinatensysteme?"

  • Bei den meisten 2D-Spielen habe ich die Quelle für die Verwendung des Bildschirmsystems gesehen, aber jedes Objekt sollte seinen Weltraum kennen. Lassen Sie Ihren Zeichnungsmanager dies in eine Bildschirmposition konvertieren. An diesem Punkt werden Sie die Matrixtransformation durchführen, die Sie benötigen.

"Werden Sprite-Positionen als Zentrum des Sprites oder als eine der Ecken gespeichert?"

  • Wenn Sie von der Mitte aus arbeiten, wird die Drehung geradliniger, obwohl Sie auch die Ecken kennen möchten.

"Vielleicht kann man in der OpenGL-Methode eine Anleitung finden ..."

  • Ganz anders verhält es sich mit 3D-Engines. Da es sich um echte Kameras handelt, kann die Bildschirmposition stark von der Weltposition abweichen. Für ein Top-Down-Spiel würden Sie eher in der X- und Z-Achse als in der X- und Y-Achse arbeiten.

1

Ich mag die Dinge hier zu stark vereinfachen, aber meine Neigung wäre, dass sich jedes 2D / UI-Subsystem genau mit den von Ihnen genannten "Bildschirm" -Koordinaten befasst. Sie hätten zwei Matrizen: ScreenToCartesianTransform und CartesianToScreenTransform. Wenn Mauseingabeereignisse empfangen werden, werden die Mauskoordinaten mithilfe von CartesianToScreenTransform transformiert, bevor sie an den Eingabemanager des 2D / UI-Systems übergeben werden. Von dort aus würde das UI-System Treffer-Tests unter Verwendung des Bildschirmkoordinatensystems durchführen und das Ereignis entsprechend behandeln (oder nicht behandeln). Wenn ein Mauseingabeereignis von der 2D / UI nicht verarbeitet wird, kann es unter Verwendung der ursprünglichen, nicht transformierten Koordinaten an das 3D-System (sofern vorhanden) weitergeleitet werden.

Da das 2D / UI-System nur "Bildschirm" -Koordinaten verarbeiten würde, müsste seine Geometrie vor der Verarbeitung durch die Rendering-Engine über ScreenToCartesianTransform transformiert werden.


Je nachdem, welches Toolkit Sie verwenden, befinden sich die Mauseingabeereignisse möglicherweise bereits in Bildschirmkoordinaten. In diesem Fall würden Sie sie nicht für das 2D / UI-System, sondern für das 3D-System (falls vorhanden) transformieren.
Mike Strobel

0

Ich bevorzuge die Verwendung eines Anzeigebaums wie in Flash. Ich habe einen Stammknoten (Spieleansicht), der ein Kind für die Welt (Weltknoten) und eines für das HUD enthält. Innerhalb des Weltknotens befinden sich die Knoten für die Objekte in der Spielwelt.

Ich transformiere dann einfach den Weltknoten. Neben der Übersetzung (Kameraschwenk) und der proportionalen Skalierung (Kamerazoom) wende ich zwei weitere Transformationen an:

  • Eine -1 y-Skala zum Umkehren des Koordinatensystems.
  • Eine Skalierung zum Konvertieren von Welteinheiten (Meter) in Bildschirmeinheiten (Pixel)

Ich benutze dann y-up / world-Koordinaten im Spielobjekt-Zeichencode und y-down / screen-Koordinaten im HUD-Zeichencode, die sich beide sehr natürlich anfühlen.

Um Fragen wie "Auf welches Objekt klicke ich?" Zu beantworten, verwende ich Anzeigeknotenmethoden zum Konvertieren von Koordinaten zwischen Koordinatensystemen (z. B. globalToLocalund deren Umkehrung in Flash).

Übrigens atanfunktioniert das nicht wirklich anders, wenn y unten ist. Sie müssen sich nur alle Winkel als im Uhrzeigersinn statt gegen den Uhrzeigersinn vorstellen.


0

Bei OpenGL sind wie bei DirectX die X- und Z-Achsen entlang der horizontalen Ebene und Y nach oben gerichtet.
Ich hatte noch nie Probleme mit Bildschirmkoordinaten, und ich denke, der einfachste Weg wäre, es so zu behandeln, wie es ist: Wenn etwas wie atan2 es nicht mag, ändern Sie die eingegebenen Parameter.

Wenn Sie relative oder lokale Koordinaten verwenden, z. B. ein Szenendiagramm, ist eine einfache Funktion wie ToGlobalCoords () hilfreich. Wenn Sie mehr über räumliche Positionierung, Szenendiagramme und localToGlobal erfahren möchten, ist der kostenlose Auszug aus der Game Engine Architecture genau das Richtige.

Sprites werden aus der oberen linken Ecke oder (0,0) dem Ursprung gezeichnet. Gründe dafür sind der linke obere Ursprung des Fensters.

Es scheint ein wenig albern, das Fensterkoordinatensystem zu ändern, und würde Dinge wie Eingaben, die für die meisten Spiele eine größere Rolle spielen als Trigger, bedeutend schwieriger machen. Es entfremdet Sie auch von der Norm und allen Benutzern Ihres Codes.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.