Implementando una cámara / viewport a un juego 2D

21

¿Cuál es la forma más práctica de implementar la cámara / vista en un juego 2D?

He leído que debo almacenar la posición del mundo del objeto en lugar de la posición relativa a la pantalla.

Situación actual:

He implementado un juego 2D simple donde cargo objetos y niveles desde archivos XML. Actualmente, el archivo XML de nivel tiene este aspecto:

<map>
   <tile obj="ground" x="0" y="555" />
   <tile obj="ground" x="16" y="555" />
   <tile obj="ground" x="32" y="555" />
   ...
</map>

Todos los objetos tienen una "posición" de 2d-vector que almacena su ubicación actual en la pantalla.

Lo que quiero que sea:

Ilustración de viewport / gameworld

En la imagen:

  • La cámara es de 800x600 o 640x480
  • Los bloques y sprites son de 16x16 píxeles.
  • El tamaño mundial puede variar
  • ¿Las coordenadas probablemente deberían normalizarse en relación con el mundo, no con la pantalla?
  • Posición de la vista relativa a la x, y del jugador y se mueve cuando el jugador alcanza la zona muerta de la cámara (similar a este video ).

Estoy preguntando pseudo ejemplos / artículos, pero si necesita saber lo que estoy usando para el desarrollo: SDL & C / C ++.

bluekirai
fuente
1
Agregue su tercer enlace en los comentarios aquí y puedo agregarlo a su pregunta.
MichaelHouse
Esto es lo que quise decir con la zona muerta de la cámara: youtube.com/watch?v=89TRXUm8jMI
bluekirai
posible duplicado de gamedev.stackexchange.com/questions/38672/…
wolfdawn
Hola @Arthur Wulf White, ¿quieres elaborar? Gracias.
bluekirai
La cámara que menciona es una versión específica de una cámara 2D general que solo se usa para compensar la vista (sin rotación y zoom). El comportamiento de seguimiento se puede implementar al verificar la distancia entre el personaje del jugador y la cámara, moviendo la cámara si la distancia es demasiado grande.
wolfdawn

Respuestas:

20

Debe tener cada objeto posicionado en relación con el mundo en lugar de la pantalla. Su cámara también debe tener sus propias coordenadas mundiales para poder dibujarla en una posición relativa en el mundo. También puede ser conveniente que su cámara siga un objeto, de modo que donde sea que esté, la cámara solo usa sus coordenadas. Por lo general, las coordenadas de la cámara la posicionarán desde la esquina superior izquierda. Esto significa que la cámara tendría una posición mundial de aproximadamente (0,24) en la imagen .

En cuanto a dibujar realmente los objetos que la cámara puede "ver", debe dibujar todos los objetos en relación con las coordenadas mundiales de la cámara. Para calcular la posición de la pantalla de un objeto en relación con la cámara, simplemente haga:

int screenX, screenY; //screen position of the object being drawn

screenX = object.x-camera.x;
screenY = object.y-camera.y;

Obviamente, algunos objetos no son realmente visibles para la cámara, por lo que es posible que desee implementar un sistema de selección de vistas.

Dan Watkins
fuente
2

Es mejor hacer todo esto en la GPU utilizando las matrices World y View, no modificando dónde dibuja los objetos en la CPU.

De esa manera, puede cambiar la cámara arbitrariamente (¡incluso acercarla y alejarla!) Y funcionará mágicamente. También puede ver el sacrificio visual para ahorrar tiempo de sorteo. Y ninguno de sus códigos para dibujar el mundo tendrá que cambiar después de haber configurado la vista y las matrices del mundo correctamente.

En SDL, probablemente pueda simplemente hacer llamadas OpenGL en línea como glOrthoy glTranslate.

Ver este hilo .

mklingen
fuente
¿Alguien puede explicar el voto negativo? Esto tiene sentido.
Hola Mundo,
1
No voté en contra, pero creo que es porque esto ni siquiera responde la pregunta. La pregunta es sobre cómo calcular algo, no si es más eficiente o más fácil de hacer en una GPU vs CPU. El OP incluso dijo que está buscando pseudo ejemplos. No hay duda de que usar una combinación de matrices de cámara / mundo / modelo sería más eficiente, por lo que mklingen tiene un punto mínimo.
Dan Watkins
¡Esta respuesta no es mala en absoluto! Es más específico para el desarrollo de OpenGL / DX, pero es el enfoque correcto, ya que puede calcular una matriz de traducción basada en los núcleos de la cámara y mover objetos a través de la matriz de la leva, sin cambiar sus posiciones reales.
nenchev