Categorías: Tutoriales

Curso programación de videojuegos con SDL – Cargando imágenes con SDL

Ya hemos visto cómo cargar una ventana simple con SDL y ponerle título. No está mal para comenzar, pero estaréis deseando hacer algo más. Lo siguiente que haremos será cargar una imagen en pantalla operación que se repite multitud de veces en cualquier juego a la hora de cargar tanto fondos, como personajes.

Para carga una imagen haremos lo siguiente:

  1. Declaramos un puntero a una variable del tipo SDL_Surface: SDL_Surface *jugador;
  2. Declaramos una variable del tipo SDL_Rect:SDL_Rect posicion;
  3. Cargamos el mapa de bits: jugador=SDL_LoadBMP(“avion.bmp”);
  4. Asignamos la posición, mediante sus coordenadas X e Y:
    posicion.x=320;
    posicion.y=400;
  5. Acoplamos la imágen al “screen”: SDL_BlitSurface(jugador, NULL, screen, &posicion);
  • jugador: superficie (SDL_Surface) que queremos insertar o de orígen.
  • NULL: indica que queremos insertar toda la imagen.
  • screen: superficie dónde se va a insertar.
  • posicion: la posición dónde se colocará.

Ya tenemos la imagen cargada. El problema de cargarla de esta manera es que no tenemos transparencias y tendríamos la imagen nuestra, avión sobre fondo blanco, apareciendo sobre el fondo, azul (imitando al mar), por lo que alrededor del avión quedaría un recuadro blanco que sin duda quedaría muy mal. Para eliminar este fondo blanco y hacer que SDL lo cargue transparente hacemos lo siguiente:

  1. Definimos una máscara con el color RGB del color a hacer transparente. En este caso el blanco, RGB(255,255,255): #define MASK 255, 255, 255
  2. Hacemos transparentes los píxeles blancos: SDL_SetColorKey (jugador, SDL_SRCCOLORKEY, SDL_MapRGB (jugador->format, MASK));
  • jugador: la superficie en la que aplicar el efecto.
  • SDL_SRCCOLORKEY: Indicar hacer transparencia.
  • SDL_MapRGB jugador->format: formato de la imagen
  • SDL_MapRGB MASK: máscara, en realidad son tres parámetros, (r,g,b).

De esta manera conseguimos un resultado así:

Veamos el código al completo:

#include <stdio.h>
#include <stdlib.h>
#include <SDL.h>
#define MASK 255, 255, 255

int main()
{
SDL_Surface *screen;
SDL_Surface *fondo;
SDL_Surface *jugador;
SDL_Event event;
int terminar=0;
SDL_Rect posicion;
int i, j;

if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
 printf("No se pudo inicializar SDL: %s\n",
 SDL_GetError());
 exit(1);
} 

fondo = SDL_LoadBMP("fondo.bmp");
jugador = SDL_LoadBMP("avion.bmp");
SDL_SetColorKey (jugador, SDL_SRCCOLORKEY,
  SDL_MapRGB (jugador->format, MASK));

screen = SDL_SetVideoMode( 640, 480, 16, SDL_HWSURFACE );

if( screen == NULL )
{
printf( "Error al entrar a modo grafico: %s\n", SDL_GetError() );
SDL_Quit();
return -1;
}

SDL_WM_SetCaption( "Moviendo nuestro avion", " Moviendo nuestro avion" );

for (i=0; i<10; i++)   
  for (j=0; j<10; j++)
  {
    posicion.x=64*i;
    posicion.y=48*j;
    SDL_BlitSurface(fondo, NULL, screen, &posicion);   
  }

posicion.x=320;
posicion.y=400;
SDL_BlitSurface(jugador, NULL, screen, &posicion);

SDL_Flip(screen);

while(terminar == 0)
{
  while ( SDL_PollEvent(&event) )
  {
    if ( event.type == SDL_KEYUP )
      terminar = 1;
  }
}

SDL_Quit();
return 0;
}
F. Javier Carazo Gil

Cofundador de CODECTION, empresa especializada en WordPress, autor de un libro sobre WordPress (el primero en español) y multitud de artículos (en medios físicos y virtuales) sobre el tema. Participa en la comunidad WordPress de forma activa siendo parte del equipo organizador de la WordPress Meetup de Córdoba, dando charlas en diferentes WordCamp y siendo autor y coautor de multitud de plugins libres y premium para WordPress de gran éxito.

Ver comentarios

  • Hay errores en el código, imagino que al copiar && pegar, en el for justo después de poner el título de la ventana.

  • @Rafael del Castillo: Rafael, todo un honor que siga el curso.

    El problema de siempre, a pesar de usar la etiqueta "pre" sigo con el problema de usar < y > para el HTML.

    Un saludo y en breve, nuevas entregas, la próxima será: moviendo nuestro avión por la pantalla.

  • Hay que tener un poco de cuidado en llamar a la imagen jugador como avion.bmp, ya que si por inercia la llamas jugador.bmp pues dara una violacion de segmento

  • Hola, en primer lugar dar las gracias por este curso porque me parece muy interesante. Estoy intentando hacer lo que has explicado pero no sé porqué no me funciona lo de la máscara y me carga el avión en pantalla pero con el fondo blanco. ¿dónde puede estar el error? He comprobado con el Gimp que los píxeles son blancos (color ffffff), pero nada, sigue igual...

    Gracias.

    Diego.

  • @Diego: Sinceramente, si tienes bien la máscara y es FFF el color del píxel, no sé por qué te funciona.

    ¿Alguien puede echar una mano?

  • Hola, ya lo he solucionado resulta que al guardar la imagen con el Gimp, en las opciones de color estaba a 32 bits (A8 R8 G8 B8) en vez de a 24 bits (R8 G8 B8). Una vez que lo pasé a 24 bits ya funciona correctamente!

    Muchas gracias.

Entradas recientes

432 CVEs

5 días hace

Anti-IA

2 semanas hace

Memoria

3 semanas hace

Mal uso

4 semanas hace

Precio de la RAM

1 mes hace

AUR

1 mes hace