Crear un juego – Parte III (Filosofía y términos)


Sé que la teoría es una cosa fundamental y más si uno quiere aprender muchas cosas o mejor dicho si uno pretende hacer cosas cuando las herramientas no te dan más, como es el caso de los FW que uno usa para programar, si el FW te permite hacerlo es bueno, pero cuando nos topamos con pared es cuando se debe de aprender hacer las cosas para así uno poder programarlas.

Pero imagínense si solo me dedico a la teoría, nos tomaría mucho tiempo (días, meses o años),  un ejemplo es la teoría del color lleva muchos temas y subtemas o como es que funciona un monitor (a nivel de juegos) o porque son juegos de 8bits o 32bits, un ejemplo claro es uno de los juegos más aclamados en la historia que es starcraft y aun que es solo un juego programado en 2D está basado en una profundidad de color de 8bits y hay una razón para eso, pero eso sería meternos en un mundo de muchas teorías así que solo iré con lo más superficial de las cosas o como otros llamarían los principios teóricos, ya si alguien quiere entrar en profundidad puede contactarme o estudiar por su cuenta.

Esto es necesario para que si buscan tutoriales de SDL pueden tener ese complemento del principio teórico y puedan ir entendiendo como funciona el desarrollo del juego.

Lo primero que quiero remarcar es la diferencia 3D y 2D, aparte de lo obvio que marca su diferencia, pero los que estén acostumbrados a programar en una librería 3D, ejemplo OpenGL y cuando regresa al 2D encuentra unas diferencias filosóficas entre ambos.

Como mencione lo obvio es que en 3D se basa en polígonos y esos a su vez por vértices que se distribuyen en un espacio tridimensional en coordenadas para ir formando las figuras y lo que hace la API (OpenGL) es proyectar estas figuras (polígonos) sobre un plano (monitor) o más técnicamente una zona de la pantalla que se llama viewport.

Cuando pasamos los vértices en el espacio 3D formando una figura (polígono) que pueden ser de un color solido o una imagen (textura) a la pantalla, este proceso se llama rasterización o mejor conocido en el 3D como render.

Antes de seguir unos dirán que han visto juegos 2D hecho en 3D, lo cual es cierto, se puede desarrollar un juego 2D con librerías 3D, solo bastaría cambiar el tipo de cámara de perspectiva a ortogonal (su proyección).

Entonces en un desarrollo 3D que se basa en un principio básico como proyección, forma de ver los elementos (polígonos) más una rasterización (render), en otras palabras proyección + rasterización.

Esto en el mundo 2D no existe, sería bueno que siguiéramos la misma filosofía y un estándar mundial, pero así no se dan las cosas en el mundo 2D o por lo menos en la clásica (no 2D con librerías 3D).

Una librería gráfica 2D se basa en el concepto de SUPERFICIES, y de operaciones entre superficies. Una superficie no es más que un espacio en memoria donde guardar una imagen, y las operaciones que se realizan entre superficies, son copias de trozos de una superficie origen sobre una superficie destino. Al igual que el mundo 3D tiene su propia terminología aquí en el 2D también tiene la suya como Blit, Buffer Primario, Double Buffer, etc.

Ahora imagínense que tienen 2 superficies, en una superficie tenemos un dibujo de algo y la otra superficie no tiene nada, ahora seleccionamos una región de la primera superficie y copiamos esa región en la segunda superficie en la posición que queremos. Esta operación es a la que se llama Blit, y es la más importante en cualquier librería 2D.

Al hacer un Blit, lo que había en la segunda superficie (superficie destino) en la región que sobrescribamos se pierde para siempre. Al copiar sobre esa posición machacamos los datos anteriores. Esto es importante si tenemos, por ejemplo, un personaje moviéndose sobre un escenario. Al dibujar el personaje destruimos esa región del escenario, así que, si el personaje se mueve, tendremos que volver a dibujar de nuevo el escenario por cada fotograma.

También de esto sacamos que el orden en que hagamos los Blits importa y mucho. Si algo tiene que quedar por encima, tiene que ser lo último que le haremos Blit.

Todo esto está muy bien para copiar imágenes entre superficies. ¿Pero cómo se muestra todo eso en pantalla?, eso es muy fácil y es tendremos una superficie especial, que va representar a la pantalla propiamente dicha. Todo lo que pongamos en esa superficie será lo que aparecerá por pantalla.

Se me olvidaba un término importante y es el Flipping o Flip aunque puede decir su significado o copiar y pegar la definición que hay en la wiki, sería mejor si se lo voy explicando en las siguientes líneas, pero antes de continuar, es que la superficie especial que le pertenece a la pantalla se inicia o se crea cuando se inicializa la librería en este caso SDL y es lo que llamamos Buffer Primario y su tamaño es la resolución que especificamos en la librería.

Como dijimos al principio cuando se programa en videojuegos siempre debemos ir dibujando en cada fotograma todos los elementos del videojuego (escenario, Hero, enemigos, etc.) y para actualizar la superficie de la pantalla o el Buffer Primario, se puede hacer de manera fácil con SDL_UpdateRects (pensando que estamos usando SDL), eso hace que la tarjeta gráfica envíe lo que haya en ese instante en el buffer primario al monitor. El problema de esto es que el monitor tiene un refresco de actualización, y si llamamos a esta función en el momento en que el monitor está dibujando algo, lo que veremos será un parpadeo bastante molesto.

Lo que queremos es que esa actualización se produzca justo en el momento en que el monitor ha terminado de dibujar un fotograma, y está preparándose para el siguiente. A esto se le llama sincronizarlo con el refresco vertical o en inglés, VSYNC (teoría del monitor de cómo trabaja, pero como dije si alguien quiere profundizar lo puede hacer en la red).

Para hacer eso, lo que se usa es una técnica llamada Double Buffer, consiste en que tendremos un buffer Secundario (o BackBuffer), además del primario. Nuestra imagen la compondremos en el secundario y llegado el momento, intercambiaremos ambos buffers para que el secundario pase a ser el primario y viceversa, actualizando la imagen en el monitor. Este intercambio estará sincronizado con el refresco del monitor.

 

A nivel práctico, seguiremos usando nuestra superficie de pantalla como antes, sólo que, a la hora de inicializar la librería, habrá que indicarle que use Double Buffer y a la hora de actualizar la pantalla después de procesar toda la información, llamaremos a SDL_Flip en lugar de a SDL_UpdateRects.

Y a todo esto que acabamos de explicar es lo que llamamos Flipping.

Entonces viendo algo de la filosofía de ambos (3D y 2D), se puede poner en 3 puntos

  • Programación 3D != Programación 2D
  • Programación 3D == Punto Flotante, matrices, proyecciones + rasterizaciones
  • Programación 2D == Operaciones enteras, ints, copias de trozos de memoria de un lado a otro

Y En cuestiones generales los términos de la filosofía de 2D seria:

  • Superficie: Espacio en memoria donde tenemos una imagen.
  • Blit: Copy-paste de una región de una superficie sobre otra.
  • Buffer Primario: Superficie que contiene lo que se dibuja en pantalla.
  • Buffer Secundario: Algo raro que evita los parpadeos
  • Flip: Orden a SDL para que actualice lo que se muestra en el monitor

 

Programador Mexicano con 14 años de experiencia, ha incursionado en diferentes áreas ampliando su experiencia. Aprendí programación por que quería hacer mi propio video juego aun que he tocado otras áreas como servidores, web, aplicaciones móviles, etc., pero la programación de video juegos fue más por hobby, primero con el 2D, aprendiendo usar SDL que es una herramienta que te da muchas libertades y optima, después Engine 3D como ogre o como CryEngine pero me enfoque mucho a Engine Source de valve. Me gusta compartir mi conocimiento y ayudar a la gente cuando puedo y los que me van conociendo saben que es cierto.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *