Unos pocos códigos para estudiar y ver su funcionamiento, copiados basados en el tutorial con el que llevamos estos días.
En este caso son eventos de teclado y ratón. Incluyendo un cambio de cursor del ratón, el cual salió muy raro y no sé si es que está mal el código que había en el tutorial o mi ordenador lo ve raro.
Este código incluye capturar eventos de teclado, usando las flechas para mover el personaje por la pantalla y activando la repetición de teclas.
Repetición de teclas: Pulsa para ver/ocultar el código
#include <SDL/SDL.h> #include <iostream> using namespace std; int main(){ //genero pantallas SDL_Surface *pantalla, *imagen; //guardo evento SDL_Event evento; //variable recuadro para la imagen a cargar SDL_Rect posicion; //iniciar SDL if(SDL_Init(SDL_INIT_VIDEO)<0){ cerr << "No se pudo inicializar SDL: " << SDL_GetError() << endl; exit(1); } //cierre.. atexit(SDL_Quit); //comprobar disponibilidad video if(SDL_VideoModeOK(640,480,24, SDL_HWSURFACE|SDL_DOUBLEBUF)==0){ cerr << "Modo de video no soportado: " << SDL_GetError() << endl; exit(1); } //iniciamos video pantalla=SDL_SetVideoMode(640,480,24,SDL_HWSURFACE|SDL_DOUBLEBUF); //comprobamos errores if(pantalla==NULL){ cerr << "Error de pantalla: " << SDL_GetError() << endl; exit(1); } //cargamos la imagen imagen=SDL_LoadBMP("barco.bmp"); if(imagen==NULL){ cerr << "Error cargando imagen: " << SDL_GetError() << endl; exit(1); } //establezco donde copiarlo posicion.x=100; posicion.y=0; posicion.h=imagen->h; posicion.w=imagen->w; //copiamos la imagen SDL_BlitSurface(imagen, NULL, pantalla, &posicion); //mostramos SDL_Flip(pantalla); //liberamos la imagen //SDL_FreeSurface(imagen); int repeat = SDL_EnableKeyRepeat(1, SDL_DEFAULT_REPEAT_INTERVAL); if (repeat < 0) { cerr << "No se pudo establecer el modo repetición: "<< SDL_GetError() << endl; }else{ cout << "activado repeticón de tecla" << endl; } //movemos la imagen while ( true ) { // o bien for( ; ; ) while (SDL_PollEvent(&evento)) { if (evento.type == SDL_KEYDOWN) { switch (evento.key.keysym.sym) { case SDLK_UP: posicion.y -= 4; if (posicion.y < 0) posicion.y = 0; break ; case SDLK_DOWN: posicion.y += 4; if (posicion.y > 480 - posicion.h) posicion.y = 480 - posicion.h; break ; case SDLK_RIGHT: posicion.x += 4; if (posicion.x > 640 - posicion.w) posicion.x = 640 -posicion.w; break ; case SDLK_LEFT: posicion.x -= 4; if (posicion.x < 0) posicion.x = 0; break ; case SDLK_ESCAPE: SDL_FreeSurface(imagen); return 0; case SDLK_f: SDL_WM_ToggleFullScreen(pantalla); break ; default : cout << "Ha pulsado otra tecla" << endl; } } // Limpiamos la pantalla SDL_FillRect(pantalla, NULL, 0); // Cambiamos la posición del personaje SDL_BlitSurface(imagen, NULL, pantalla, &posicion); // Actualizamos la pantalla principal SDL_Flip(pantalla); if (evento.type == SDL_QUIT) { SDL_FreeSurface(imagen); return 0; } } } }
Estos tres códigos van juntos y es el código referente al ratón, en el que se pueden ver por consola las coordenadas del ratón, con click izquierdo se cambia de cursor, click derecho oculta/muestra el cursor y el botón central resetea dejando el cursor por defecto y en el centro.
cursor.h: Pulsa para ver/ocultar el código
// Listado: cursor.h // // Funciones para personalizar el cursor mediante una imagen XPM // #ifndef _CURSOR_H_ #define _CURSOR_H_ #include <SDL/SDL.h> // Tamaño del apuntador o cursor const int TAMANO = 32; // Pasamos una matriz con una imagen XPM y nos devuelve // un cursor que utilizar con SDL SDL_Cursor *Cursor_personalizado_XPM( const char *matriz[]); #endif
cursor.cpp: Pulsa para ver/ocultar el código
// Listado: cursor.cpp // // Implementación #include <iostream> #include "cursor.h" SDL_Cursor *Cursor_personalizado_XPM( const char *matriz[]){ // Variables auxiliares int i, fila, col; Uint8 data[4 * TAMANO]; // (h * w / 8) Uint8 mask[4 * TAMANO]; //int hot_x, hot_y; i = -1; // Recorremos toda la matriz for ( fila = 0; fila < TAMANO; ++fila ) { for ( col = 0; col < TAMANO; ++col ) { // Si no es múltiplo de 8, desplazamos if ( col % 8 ) { data[i] <<= 1; mask[i] <<= 1; } else { ++i; data[i] = mask[i] = 0; } switch (matriz[4 + fila][col]) { case 'X': data[i] |= 0x01; mask[i] |= 0x01; break; case '.': mask[i] |= 0x01; break ; case ' ': break; } } } return SDL_CreateCursor(data, mask, TAMANO, TAMANO, 15, 15); }
main.cpp: Pulsa para ver/ocultar el código
// Listado 6 - Eventos // // Listado: main.cpp // Programa de pruebas. Eventos de ratón. Personalización del cursor // Este programa prueba diferentes funciones // referentes al manejo del ratón #include <iostream> #include <iomanip> #include <SDL/SDL.h> #include "cursor.h" using namespace std; int main(){ // Iniciamos el subsistema de video if (SDL_Init(SDL_INIT_VIDEO) < 0) { cerr << "No se pudo iniciar SDL: " << SDL_GetError() << endl; exit(1); } atexit(SDL_Quit); // Comprobamos que sea compatible el modo de video if (SDL_VideoModeOK(640, 480, 24, SDL_HWSURFACE|SDL_DOUBLEBUF) == 0) { cerr << "Modo no soportado: " << SDL_GetError() << endl; exit(1); } // Establecemos el modo de video SDL_Surface *pantalla; pantalla = SDL_SetVideoMode(640, 480, 24, SDL_HWSURFACE|SDL_DOUBLEBUF); if (pantalla == NULL) { cerr << "No se pudo establecer el modo de video: " << SDL_GetError() << endl; exit(1); } // Imagen en XPM para personalizar el cursor const char *punto_mira[] = { // ancho alto num_colors bytes_per_pixel */ " 32 32 3 1", // definición de los colores ". c #000000" "X c #ffffff", " c None", // píxels " ", //1 " ", " ", " ", " ", //5 " ", " ", " XXXXXX ", " XXXX X XXXX ", " XXX XXX ", //10 " XX XX ", " X X X ", " X X X ", " X X X ", " XX XXXXXXXXXXX XX ", //15 " X X X ", " X X X ", " X X X ", " X X X ", " XX XX ", //20 " XXX XXX ", " XXXX X XXXX ", " XXXXXX ", " ", " ", //25 " ", " ", " ", " ", " ", // 30 " ", " ", // 32 "0,0" }; // Rellenamos la pantalla de un color diferente al negro Uint32 color = SDL_MapRGB(pantalla->format, 25, 100, 155); // Sólo en el rango que vamos a permitir para el ratón SDL_Rect delimitador; delimitador.x=100; delimitador.y=100; delimitador.w=440; delimitador.h=280; SDL_FillRect(pantalla, &delimitador, color); // Actualizamos la pantalla SDL_Flip(pantalla); // Guardamos el cursor original SDL_Cursor *original = SDL_GetCursor(); SDL_Event evento; // Bucle "infinito" int ocultar=0; for ( ; ; ) { while (SDL_PollEvent(&evento)) { if (evento.type == SDL_KEYDOWN) { if (evento.key.keysym.sym == SDLK_ESCAPE) { SDL_FreeCursor(original); } return 0; } if (evento.type == SDL_QUIT){ return 0; } // Movemos el ratón if (evento.type == SDL_MOUSEMOTION){ if (evento.motion.x > 540 || evento.motion.x < 100 || evento.motion.y > 380 || evento.motion.y < 100 ) { // Si se sale de este rango // Vuelve dentro de él cout << "Te has salido del rectángulo azul" << endl; SDL_WarpMouse(250, 200); } cout << "X: " << setw(3) << evento.motion.x << " - Y: " << setw(3) << evento.motion.y << endl; } // Pulsamos un botón del ratón if (evento.type == SDL_MOUSEBUTTONDOWN) { if (evento.button.button == 1) { cout << "X: " << setw(3) << evento.button.x << " - Y: " << setw(3) << evento.button.y << " Botón izquierdo pulsado, cursor personalizado" << endl; // Personalizamos el cursor SDL_Cursor *apuntador; apuntador = Cursor_personalizado_XPM(punto_mira); // Lo establecemos SDL_SetCursor(apuntador); // Nos aseguramos de que se muestra SDL_ShowCursor(1); } else if (evento.button.button == 2) { // Mostramos el cursor SDL_ShowCursor(1); // Reestablecemos el original SDL_SetCursor(original); cout << "Botón central, vuelta al cursor original" << endl; } else { // Ocultamos el cursor SDL_ShowCursor(ocultar); ocultar=!ocultar; } } } } cout << "Botón derecho pulsado, se oculta el cursor" << endl; return 0; }