Cómo lidiar con las diferencias entre las coordenadas de pantalla 2D y las coordenadas cartesianas

23
  • La mayoría de los sistemas de coordenadas de pantalla 2D / mapa de bits tienen el eje Y positivo apuntando hacia abajo (con el origen en la esquina superior izquierda).
  • Esto es contrario a cómo la mayoría de la gente piensa geométricamente con el eje Y positivo apuntando hacia arriba (con el origen en el centro).

¿Cómo gestionan la mayoría de los juegos los dos sistemas de coordenadas 2D diferentes? Hay dos tipos principales de coordenadas (pantalla frente a cartesiano), pero podría haber muchos espacios de coordenadas diferentes: espacio de sprites, espacio mundial, espacio de vista, espacio de pantalla, etc.

Fondo:

Originalmente hice que las coordenadas mundiales en mi juego coincidieran con la convención de coordenadas de pantalla 2D. Esto hizo que fuera muy natural usar las rutinas de dibujo de gráficos, pero surgieron problemas sutiles al usar funciones trigonométricas como atan2 (). Los resultados de alimentar las coordenadas de la pantalla 2D atan2 () son muy confusos porque atan2 () supone que el eje y positivo apunta hacia arriba.

Así que cambié mis coordenadas mundiales para seguir el clásico sistema de coordenadas cartesianas (con el origen en la parte inferior izquierda de la pantalla). Razonar con atan2 () es mucho más directo, pero ahora es más difícil hacer otros tipos de razonamiento:

  • Si hago clic en la pantalla aquí, ¿qué sprite está debajo?
  • ¿Dónde hice clic en ese sprite?
  • Si un sprite se dibuja en la ubicación incorrecta, ¿qué se calculó incorrectamente? ¿Las coordenadas de la pantalla o las coordenadas mundiales?

Me doy cuenta de que la conversión de la pantalla a coordenadas cartesianas implica simplemente escalar el valor de y en -1 con una traducción opcional de ambos valores (x, y). Estoy más interesado en las mejores prácticas para el diseño de juegos:

  • ¿La mayoría de los juegos se limitan a la convención de coordenadas de pantalla y cambian su forma de pensar sobre cómo deberían funcionar cosas como atan2 ()?
  • ¿Cuándo / cómo se realizan las conversiones del sistema de coordenadas? (Utilizando matrices, abstracción OOP, etc.)
  • ¿Se almacenan las ubicaciones de los sprites como el centro del sprite o una de las esquinas? La altura / anchura del sprite que va en la dirección "incorrecta" parece ser un problema común cuando los dibujo.

Aunque mi pregunta es principalmente sobre juegos 2D, parece que OpenGL usa un sistema de coordenadas donde el eje Y apunta hacia arriba. OpenGL finalmente debe proyectar esas coordenadas 3D en un sistema de coordenadas de pantalla 2D. Quizás se pueda encontrar alguna orientación en el método de OpenGL ...

Leftium
fuente

Respuestas:

8

Después de haber probado todas las formas imaginables de hacerlo, descubrí que si se trata simplemente de un juego en 2D, solo use el sistema de dibujo de pantalla, le hará la vida mucho más fácil. Sin, Cos y atan2 deben usarse de manera ligeramente diferente, pero este inconveniente se compensa fácilmente con la simplicidad de saber en qué dirección están arriba, abajo, en sentido horario y antihorario. También recomendaría trabajar en píxeles en lugar de metros para juegos 2D: es mucho más fácil pensar en las distancias en pantalla, y las posibilidades de que quieras cambiar toda la escala de tu juego son cercanas a cero.

"¿Cómo manejan la mayoría de los juegos los dos sistemas de coordenadas 2D diferentes?"

  • La mayoría de los juegos en 2D que he visto en la fuente para usar el sistema de pantalla, pero cada entidad debe conocer su espacio mundial, deje que su administrador de dibujo lo convierta en una posición de pantalla. En este punto, harás cualquier transformación de matriz que necesites.

"¿Las ubicaciones de los sprites se almacenan como el centro del sprite o una de las esquinas?"

  • Si trabaja desde el centro, hace que la rotación sea más directa, aunque también querrá conocer las esquinas.

"Quizás se pueda encontrar alguna orientación en el método de OpenGL ..."

  • Los motores 3D son un caso completamente diferente. Como tienen cámaras verdaderas, la posición de la pantalla puede ser muy diferente de la posición mundial. Para un juego de arriba hacia abajo, estarías trabajando en los ejes X y Z, en lugar de los X e Y por una cosa.
Iain
fuente
1

Puede que esté simplificando demasiado las cosas aquí, pero mi inclinación sería que cualquier subsistema 2D / UI se ocupe estrictamente de lo que denominó coordenadas de "pantalla". Tendría dos matrices: ScreenToCartesianTransform y CartesianToScreenTransform. Cuando se reciben eventos de entrada del mouse, las coordenadas del mouse se transformarían usando CartesianToScreenTransform antes de pasar al administrador de entrada del sistema 2D / UI. A partir de ahí, el sistema de IU realizaría pruebas de impacto utilizando el sistema de coordenadas de pantalla y manejaría (o no manejaría) el evento en consecuencia. Si un evento de entrada del mouse no es controlado por la 2D / UI, podría pasarse al sistema 3D (si existe) usando las coordenadas originales no transformadas.

Dado que el sistema 2D / UI solo se ocuparía de coordenadas de "pantalla", su geometría necesitaría ser transformada a través de ScreenToCartesianTransform antes de ser procesada por el motor de renderizado.

Mike Strobel
fuente
En realidad, dependiendo del kit de herramientas que esté utilizando, los eventos de entrada del mouse ya pueden estar en las coordenadas de la pantalla. En ese caso, no los transformaría para el sistema 2D / UI, pero lo haría para el sistema 3D (si existe).
Mike Strobel el
0

Prefiero usar un árbol de visualización como en Flash. Tendré un nodo raíz (vista del juego) que contiene un hijo para el mundo (nodo mundial) y uno en la parte superior para el HUD. Dentro del nodo del mundo estarán los nodos para los objetos en el mundo del juego.

Entonces simplemente transformo el nodo mundial. Junto con la traducción (panorámica de la cámara) y la escala proporcional (zoom de la cámara) también aplico otras dos transformaciones:

  • Una escala -1 y para voltear el sistema de coordenadas.
  • Una escala para convertir unidades mundiales (metros) en unidades de pantalla (píxeles)

Luego uso las coordenadas y-up / world en el código de dibujo de objetos del juego y las coordenadas y-down / screen en el código de dibujo de HUD, que se sienten muy naturales.

Para responder preguntas como "en qué objeto estoy haciendo clic", uso métodos de nodo de visualización para convertir coordenadas entre sistemas de coordenadas (como globalToLocaly su inverso en Flash).

Por cierto, atanno funciona de manera diferente cuando y está abajo, solo necesita pensar que todos los ángulos van en sentido horario en lugar de hacerlo en sentido antihorario.

Bart van Heukelom
fuente
0

OpenGL, como DirectX, tiene los ejes X y Z a lo largo del plano horizontal e Y hacia arriba.
Nunca he tenido ningún problema con las coordenadas de la pantalla, y creo que la forma más fácil sería simplemente tratarlo como es: si algo, como atan2, no le gusta, entonces cambie los parámetros que se están alimentando.

Si está utilizando coordenadas relativas o locales, como un gráfico de escena, entonces una función simple como ToGlobalCoords () es buena. De hecho, si desea obtener más información sobre el posicionamiento espacial, los gráficos de escena y localToGlobal, el extracto gratuito de Game Engine Architecture trata sobre eso.

Los sprites se dibujan desde la esquina superior izquierda o (0,0) del origen. Las razones se deben al origen superior izquierdo de la ventana.

Parece un poco tonto cambiar el sistema de coordenadas de la ventana, y haría que cosas como la entrada, que juega un papel más importante en la mayoría de los juegos que el trigonometraje, sean significativamente más difíciles. También lo aleja de la norma y de cualquier usuario de su código.

El pato comunista
fuente