Razón Artificial

La ciencia y el arte de crear videojuegos

Introducción a la programación gráfica 2D (III)

Escrito por adrigm el 20 de agosto de 2010 en Desarrollo Videojuegos, Noticias, Programación | 4 Comentarios.

En este tutorial vamos a hablar algo más acerca de los superficies y el “Blit”. Ya que al final todo juego 2D se basa en copiar superficies (por lo menos la parte gráfica).

En realidad el “Blittelado” es algo más complejo que copiar y pegar de una superficie a otra, a lo mejor las superficies no tienen el mismo formato de pixel y hay que convertirlos, por lo general esto será trasparente para el usuario y se encargará de ello la api gráfica, de todos modos esto es mejor consultar sobre la api en particular que se esté usando.

Sistemas de coordenadas

Todas las superficies de las apis gráficas deben de tener un sistema de coordenadas, este se utiliza para saber en que parte se debe copiar una superficie a otra o que tamaño tiene una imagen que al fin y al cabo es lo que van a contener las superficies de nuestras aplicaciones.

El sistema de coordenadas tiene su origen en la esquina superior izquiera de la superficie, siendo ese pixel de la superficie la coordenada (0, 0) de la imagen.

Como vemos en la imagen tenemos dos ejes (x, y) siendo x el ancho de la superficie e y el alto. La imagen de arriba representa a cualquier superficie y como ya hemos dicho más de una vez una superficie es tanto una imagen como la misma pantalla.

Las superficies son rectangulares siempre

Es muy importante que se entienda que las superficies siempre son rectángulos. Y tu puedes decir, mentira, ¡El mismo Pacman es redondo! y yo te diré tu lo ves redondo, pero internamente no es más que un rectángulo que tiene un colo transparente (más adelante hablaremos del canal alpha, colorkey y demás).

Bien vamos a tratar con una superficie que represente una imagen, pongamos que tenemos esta imagen (No os riáis, no me llevo bien con el dibujo).

Está imagen podría ser la superficie de nuestro juego y tendría su coordenada (0, 0) en la parte superior derecha luego tendría un ancho y un elto en esta caso 98×103 por tanto el pixel inferior derecho tendría la coordenada (98, 103). Otras coordenadas son las superior derecha sería la (98, 0) y la inferior izquierda sería la (0, 103). Creo que se capta la idea.

Ahora supongamos que queremos hacer un blit de nuestra superficie a la superficie screen, en otras palabras, copiar nuestra imagen en la pantalla. ¿Dónde se copiaría), pues en la coordenada que le pasemos a nuestra función que se encargue de hacer el blit.

Supongamos que tenemos una  superficie screen de 320×240 y nuestra imagen y queremos copiarla en la coordenada (50, 47). Pues se copiará de la siguiente manera:

Como vemos la coordenada (0, 0) de la superficie origen se copia en la coordenada que elijamos de la superficie destino, es decir, la coordenada (0, 0) de nuestra superficie imagen la colocamos en la coordenada (50, 47) de la superficie de la pantalla. Por lo que para obtener la posición que ocupa el pixel inferior derecho de la imagen en la pantalla valdría una simple suma. (X+ANCHO_IMAGEN, Y+ALTO_IMAGEN), en nuestro caso sería (50+98, 47+103) que nos daría la coordenada del pixel final de la imagen.

Por lo general las bibliotecas gráficas existentes a parte del inicio se le puede indicar el final de lo que se quiere copar por lo que solo quedaría copiada esta área de la imagen. Vamos a hablar de los clippers.

Clippers

Lo que hace el clipper es definir el área de la superficie destino sobre el que podemos blittear. Todo lo que caiga fuera de ese área, no se dibuja.

El clipper de una superficie solo afecta a los blits que tengan como DESTINO a esa superficie. No afecta para nada al origen.

En la imagen de la izquierda dice “sin clipper”, pero eso no es completamente correcto. En realidad, siempre hay un clipper, sólo que por defecto su área abarca toda la superficie, dejando que bliteemos en todas partes.

La razón de que existan los clippers es sencillamente el evitar que al hacer un blit podamos escribir en zonas de memoria que no corresponden a la superficie. El rectángulo nunca puede extenderse más allá del limite de la superficie, así que ese problema desaparece automáticamente.

Pero además de eso, podemos darle más utilidades para optimizar el dibujado. Si sólo necesitamos actualizar una zona de la superficie destino, pero la región que estamos blitteando es enorme, usando un clipper nos evitamos escribir pixels que no necesitamos (o que no debemos, porque no queremos machacarlos).

Color Keys

Volvamos al problema que teníamos más arriba, donde decíamos que todos las superficies han de ser rectangulares, como el Pacman de más arriba. En realidad lo ideal sería que solo se dibujara nuestro sprite y no el área rosa de alrededor, para ello se usa el colorkey, esto consisten en definir un color de la imagen como transparente. Todo el color de una imagen marcado como colorkey se volverá transparente. Pongamos un ejemplo:

Como vemos el recuadro blanco queda muy mal, la solución es definir que en nuestra superficie de origen el colorkey se la imagen sería el blanco, por lo que nos quedaría:

Como vemos mucho mejor, pero no olvidemos dos cosas importantes.

  1. Aunque el rectángulo blanco sea transparente sigue estando ahí y la esquina superior izquieda de nuestra imagen sigue siendo la que era antes, aunque no se vea.
  2. El colorkey hace que TODOS los píxeles de ese color se vuelvan transparentes por lo que debes asegurarte de que el color que uses como colorkey no forma parte de la imagen. Se suelen usar colores poco comunes como el (255, 0, 255) que es el rosa chillón de arriba, pero si tu imagen tiene este color basta con usar otro.

Canal Alpha

Por último mencionar el canal Alpha, consiste en definir un grado de transparencia para la imagen.

No voy a explicar mucho más de el porque en apis 2D que no usen tratamiento por gráficos 3D como OpenGL o DirectX usar el canal alpha gasta muchos recursos pues no solo hay que leer la imagen de origen sino también el destino para la mezcla de colores haciendo que en ocasiones pueda ser un verdadero cuello de botella para el rendimiento.

Fuentes:
Autor: Autor: Sergio Hidalgo. serhid@wired-weasel.com
Fuente:http://www.wired-weasel.com/users/serhid/tutos/tut3.html

4 Comentarios en "Introducción a la programación gráfica 2D (III)"

  1. […] Controlar los conceptos básicos de la programación de juegos 2D. Parte 1, Parte 2 y Parte 3. […]

  2. Fede dice:

    Quería consultarte algo… cuando decís: “tendría su coordenada (0, 0) en la parte superior derecha”, ¿quisiste decir superior izquierda? Es que después, más abajo, escribiste “Otras coordenadas son las superior derecha sería la (98, 0)”, o sea que repetiste la coordenada superior derecha.

    ¡No lo tomes a mal! Sólo quiero dejar claro que no me parece correcta la información, está todo muy bien explicado y es de lectura fácil. ¡Saludos!

  3. […] Introducción a la programación gráfica 2D (III) […]

Deja un comentario