P R O G R A M A C I Ó N D E V I D E O J U E G O S C O N S D LAlgún avispado lector se preguntará qué ocurre si los campos w y h <strong>de</strong> los parámetrossrc<strong>de</strong>st y dstrect no coinci<strong>de</strong>n. Realmente no ocurre nada, ya que los campos w y h<strong>de</strong> dstrect no se utilizan. Por último, <strong>de</strong>cir que si la la copia tiene éxito la función<strong>de</strong>vuelve el valor 0, y –1 en caso <strong>con</strong>trario.Otra utilidad <strong>de</strong> la estructura <strong>SDL</strong>_Rect es la <strong>de</strong> dibujar rectángulos en la pantallamediante la función <strong>SDL</strong>_FillRect. Ilustrémoslo <strong>con</strong> un ejemplo:<strong>SDL</strong>_Rect <strong>de</strong>st;<strong>de</strong>st.x = 0;<strong>de</strong>st.y = 0;<strong>de</strong>st.w = screen->w;<strong>de</strong>st.h = screen->h;<strong>SDL</strong>_FillRect(screen,&<strong>de</strong>st,<strong>SDL</strong>_MapRGB(screen->format,0,0,0));Esta función dibuja un cuadrilátero en una superficie <strong>con</strong> el color indicado. En elejemplo se dibuja un rectángulo <strong>de</strong> color negro <strong>de</strong>l tamaño <strong>de</strong> la superficie (pantalla), o loque es lo mismo, borra la pantalla. El formato <strong>de</strong> la función es:int <strong>SDL</strong>_FillRect(<strong>SDL</strong>_Surface *dst, <strong>SDL</strong>_Rect *dstrect, Uint32 color);El primer parámetro es la superficie <strong>de</strong> <strong>de</strong>stino, el siguiente parámetro es <strong>de</strong> tipo<strong>SDL</strong>_Rect y <strong>de</strong>fine el rectángulo. Por último, hay que indicar el color <strong>de</strong> relleno. Un pocomás a<strong>de</strong>lante compren<strong>de</strong>remos el uso <strong>de</strong> <strong>SDL</strong>_MapRGB.Sigamos <strong>con</strong> la siguiente función:int <strong>SDL</strong>_Flip(<strong>SDL</strong>_Surface *screen);Si estamos usando doble buffer (como es el caso <strong>de</strong> nuestro ejemplo), esta funciónintercambia los buffers, es <strong>de</strong>cir, vuelca el <strong>con</strong>tenido <strong>de</strong>l buffer secundario al principal. Sitiene éxito <strong>de</strong>vuelve 0, si no, <strong>de</strong>vuelve –1. Si no usáramos doble buffer o nuestrohardware no lo soportara, tendríamos que usar <strong>SDL</strong>_UpdateRect(screen,0,0,0,0)en lugar <strong>de</strong> <strong>SDL</strong>_Flip(). El formato <strong>de</strong> esta función es:void <strong>SDL</strong>_UpdateRect(<strong>SDL</strong>_Surface *screen, Sint32 x, Sint32 y, Sint32 w,Sint32 h);Su misión es asegurar que el área que especifiquemos (sus parámetros <strong>de</strong>ben serteya familiares) sea actualizada.Como te veo <strong>con</strong> cara rara, quizás sea este el momento <strong>de</strong> explicar en qué <strong>con</strong>sisteeso <strong>de</strong>l doble buffer.Imagina que tienes que volcar a la pantalla los gráficos <strong>de</strong> tu juego. Primero pondríasel fondo (calculando previamente que porción <strong>de</strong>l fondo tienes que mostrar), mostraríaslas naves enemigas (calculando su posición previamente) y <strong>de</strong>spués dibujarías al héroe<strong>de</strong> tu juego. Entre el primer y el último gráfico que dibujas en pantalla pue<strong>de</strong> pasar untiempo bastante gran<strong>de</strong> (informáticamente hablando). Durante este tiempo, la imagen <strong>de</strong>lmonitor ha tenido tiempo <strong>de</strong> actualizarse varias veces (retrazo vertical).Desgraciadamente, cuando esto ocurre aparecen parpa<strong>de</strong>os y guiños (flicking)in<strong>de</strong>seados y muy molestos. Mediante la técnica <strong>de</strong>l doble buffer, todo el pintado se haceen una pantalla virtual, y sólo cuando está todo pintado, volcamos su <strong>con</strong>tenido a lapantalla real (flipping). Este proceso <strong>de</strong> volcado se hace a<strong>de</strong>más <strong>de</strong> forma sincronizada<strong>con</strong> el retrazo vertical <strong>de</strong>l monitor para evitar los parpa<strong>de</strong>os.Es importante (sobre todo en un lenguaje como C/C++) liberar los recursos que ya novamos a necesitar. En nuestro ejemplo usamos la función <strong>SDL</strong>_FreeSurface() paraliberar (borrar) la superficie que <strong>con</strong>tiene la imagen cargada. Su formato es:31
P R O G R A M A C I Ó N D E V I D E O J U E G O S C O N S D Lvoid <strong>SDL</strong>_FreeSurface(<strong>SDL</strong>_Surface *surface);La misión <strong>de</strong> las siguientes líneas es esperar la pulsación <strong>de</strong> una tecla cualquieraantes <strong>de</strong> acabar. Veremos más en profundidad su significado cuando tratemos loseventos.Efectos especiales: Transparencias y alpha-blendingEl hecho <strong>de</strong> que seamos capaces <strong>de</strong> mostrar el grafico <strong>de</strong> un avión en la pantalla es unpaso importante, pero seamos realistas: no es <strong>de</strong>masiado espectacular. De hecho, eserecuadro rojo alre<strong>de</strong>dor <strong>de</strong>l avión es bastante antiestético ¿no? Ciertamente sí. Alguien pue<strong>de</strong>haber ya pensado en una solución (salomónica, me atrevería a apuntar), que es hacer queese horrible recuadro rojo sea <strong>de</strong> color negro, al igual que el fondo. Realmente es unasolución, si te gustan los juegos <strong>con</strong> fondos <strong>de</strong> pantalla algo monótonos. Como siempre <strong>SDL</strong>viene al rescate. Echemos un vistazo a la siguiente función:int <strong>SDL</strong>_SetColorKey(<strong>SDL</strong>_Surface *surface, Uint32 flag, Uint32 key);Esta función nos permite <strong>de</strong>signar un color en la superficie, que pasamos como parámetro,y que tendrá el comportamiento <strong>de</strong> un color transparente. Es <strong>de</strong>cir, que no se pintará cuandohagamos el blitting. La función nos <strong>de</strong>vuelve 0 si todo fue bién y –1 en otro caso. El parámetroflag sólo pue<strong>de</strong> tomar tres valores posibles:• 0 para <strong>de</strong>sactivar una transparencia previamente activada.• <strong>SDL</strong>_SRCCOLORKEY para indicar que el tercer parámetro <strong>de</strong> la función correspon<strong>de</strong> alcolor que queremos que sea transparente y• <strong>SDL</strong>_RLEACCEL que permite usar codificación RLE en la superficie para acelerar elblitting.•Este último flag sólo pue<strong>de</strong> usarse en combinación <strong>con</strong> <strong>SDL</strong>_SRCCOLORKEY, es <strong>de</strong>cir, sólose permiten tres valores posibles: 0, <strong>SDL</strong>_SRCCOLORKEY, <strong>SDL</strong>_SRCCOLORKEY|<strong>SDL</strong>_RLEACCEL.El tercer parámetro es el color, que queremos que sea transparente. Hay que tener encuenta que el color ha <strong>de</strong> estar en el mismo formato <strong>de</strong> píxel (píxel format) que la superficie.Lo habitual es utilizar la función <strong>SDL</strong>_MapRGB para <strong>con</strong>seguir el valor <strong>de</strong>l color que buscamos.Veamos un ejemplo:<strong>SDL</strong>_SetColorKey(image, <strong>SDL</strong>_SRCCOLORKEY|<strong>SDL</strong>_RLEACCEL, <strong>SDL</strong>_MapRGB(image->format,255,0,0));Aña<strong>de</strong> esta línea al ejemplo anterior <strong>de</strong>spués <strong>de</strong> la carga <strong>de</strong>l gráfico. Si ejecutas ahora elprograma veras el avión sin ese feo marco rojo alre<strong>de</strong>dor.32