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;
}

