Poner como transparente color pixel inferior izquierdo image

Tratamos sobre el manejo de APIs frecuentemente utilizadas en el desarrollo de videojuegos, como SDL, pygame o SFML.

Poner como transparente color pixel inferior izquierdo image

Notapor astut » Jue Abr 12, 2007 7:39 am

Hola, me gustaria saber como poner como color transparente en una imagen el ultimo pixel inferior izquierdo de la imagen por ejemplo, ¿como se haria?, gracias (ya conozco la funcion SetColorKey)
astut
 
Mensajes: 7
Registrado: Vie Mar 16, 2007 9:20 am

Notapor Geo » Jue Abr 12, 2007 4:56 pm

Supongo que simplemente debes obtener el color de dicho pixel, entonces, cargas la imagen:
Código: Seleccionar todo
SDL_Surface* imagen = SDL_LoadBMP( "imagen.bmp" );

Obtienes el color del pixel de la esq. inf. izq., y lo asignas como el transparente:
Código: Seleccionar todo
Uint32 key = getpixel( imagen, 0, imagen->h );
SDL_SetColorKey( imagen, SDL_SRCCOLORKEY, key );


Donde la función getpixel es:
Código: Seleccionar todo
// Nota, código obtenido del wiki de SDL
// http://www.libsdl.org/cgi/docwiki.cgi/Pixel_20Access
Uint32 getpixel(SDL_Surface *surface, int x, int y)
{
    int bpp = surface->format->BytesPerPixel;
    /* Here p is the address to the pixel we want to retrieve */
    Uint8 *p = (Uint8 *)surface->pixels + y * surface->pitch + x * bpp;

    switch(bpp) {
    case 1:
        return *p;

    case 2:
        return *(Uint16 *)p;

    case 3:
        if(SDL_BYTEORDER == SDL_BIG_ENDIAN)
            return p[0] << 16 | p[1] << 8 | p[2];
        else
            return p[0] | p[1] << 8 | p[2] << 16;

    case 4:
        return *(Uint32 *)p;

    default:
        return 0;       /* shouldn't happen, but avoids warnings */
    }
}

----------------------
Pequeña correción, al leer el pixel de la esquina hay que restar 1 a surface->h:
Código: Seleccionar todo
Uint32 key = getpixel( imagen, 0, imagen->h - 1 );
SDL_SetColorKey( imagen, SDL_SRCCOLORKEY, key );


Suerte.
La imaginación es el límite.
Visita mi blog en inglés o en español.
Geo
 
Mensajes: 244
Registrado: Jue Ago 10, 2006 3:51 am
Ubicación: México

Notapor astut » Vie Abr 13, 2007 10:50 am

Muchas gracias funciona a la perfeccion!, otra duda que tengo, cuando dibujo la imagen y cambio sus propiedades x e y (la muevo a otro lugar) la imagen no se borra, es decir, la imagen esta en las coordenadas 200,300 la muevo a las coordenadas 600,700 y sige estando en la coordenada 200,300 aunque tambien ha aparecido 600,700 lo explico asi para que no haya ni una sola confusion xD, uso SDL_Flip() pero sige igual (flip lo uso para actualizar la ventana)
Gracias y saludos!
PD: Otra pregunta, cual es el evento para que mientras este pulsando una tecla ocurra algo?, uso lo siguiente para cuando presione una tecla ocurra algo:
Código: Seleccionar todo
while (SDL_PollEvent(&evento))
  {
   if (evento.type== SDL_KEYDOWN)
   {
    switch (evento.key.keysym.sym)
    {
     case SDLK_ESCAPE: bucle= false; break;
     case SDLK_p: avion.CfgPosicion(0,0); break;
     case SDLK_m: avion.Mover(3,0); break;
     case SDLK_a: avion.CfgAlpha(12,1); break;
    }
   }
  }

Pero lo que pretendo es "mientras" la tecla este presionada ocurra algo, gracias!
astut
 
Mensajes: 7
Registrado: Vie Mar 16, 2007 9:20 am

Notapor rcaf » Sab Abr 14, 2007 1:54 am

Primero, para que no quede rastro del sprite al moverlo, debes limpiar la superficie en donde estés dibujando los sprites, es decir, deberías "blitear" un fondo, o mapa antes de dibujar los otros elementos, o simplemente borrar todo el framebuffer con un color determinado (color negro).

Por ejemplo yo hice una función Clear para solucionar este problema y consiste en dibujar un rectángulo relleno de un color x, del tamaño de la ventana:

Código: Seleccionar todo
void Clear(SDL_Surface *surface, Uint32 color)
{
    SDL_Rect rect={0, 0, surface->w, surface->h};

    SDL_FillRect(surface, &rect, color);
}


Y ahora si quiero limpiar la pantalla, antes de dibujar cualquier cosa, haría lo siguiente:

Código: Seleccionar todo
// Color negro para el fondo
Uint32 color=SDL_MapRGB(screen->format, 0, 0, 0);

// Limpia la pantalla, suponemos que screen es la surface
// que nos retornó SDL_SetVideoMode
Clear(screen, color);



Sobre la segunda pregunta, cuando presionas una tecla y la sueltas ocurrirán los sucesos que están en tu código, la forma está correcta.

Cada vez que presiones la tecla 'm' el avión se moverá 3 pixeles hacia la derecha (supongo que así funciona tu código).

También podrías utilizar la función SDL_GetKeyState, para obtener el estado completo del teclado, por ejemplo:

Código: Seleccionar todo
Uint8 *keyboard=SDL_GetKeyState(0);

if (keyboard[SDLK_RIGHT])
  avion.Mover(3,0);



Si mantienes presionado el cursor derecho, la nave se seguirá moviéndo en ese sentido hasta que la sueltes u ocurra algún evento que hayas programado (colisión con algún objeto, limite de la pantalla, etc.).

Saludos!
Roberto Albornoz Figueroa
Mi Blog
Wiki
Avatar de Usuario
rcaf
 
Mensajes: 71
Registrado: Jue Ago 10, 2006 4:35 am
Ubicación: Concepción, Octava Región. Chile

Notapor astut » Sab Abr 14, 2007 9:16 am

Muchas gracias por tus enseñanzas todo perfecto =)
Preguntare aqui cuando tenga dudas ^^
astut
 
Mensajes: 7
Registrado: Vie Mar 16, 2007 9:20 am


Volver a Sobre las bibliotecas multimedia

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 2 invitados

cron