Códigos SDL - eventos básicos teclado y ratón

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

Etiquetas: ,,,,. Guarda el enlace permanente.

Deja un comentario ^^