• Publicidad

Cómo hacer colisiones con SDL

Todo lo relacionado con lenguajes de programación distintos de Perl: PHP, Java, C++, Ruby, Python, etc.

Cómo hacer colisiones con SDL

Notapor mcmakia696 » 2012-02-05 13:20 @597

¡Hola!

Tengo un problema con un programa y me dijeron que en este foro me podían ayudar. Estoy programando juegos con la librería SDL con C++, pero no avanzo mucho porque apenas soy principiante con esta librería.

El problema que tengo es que quiero hacer colisionar dos cuadrados; uno amarillo que es el "PJ" el cual puedo mover por la pantalla y otro gris que está fijo en las coordenadas (1300,1500) todo funciona bien pero no logro hacer que los dos objetos colisionen. Cuando activo el código el PJ se queda quieto y no va a ningún lado. ¿Podría alguien ayudarme?

Aquí les dejo el código y un enlace donde pueden descargar los recursos que utiliza el programa:

*NOTA: el fragmento de código está comentado y está ubicado en la definición de la función "MOVER()" de la clase "PJ_CLASE".

https://rapidshare.com/files/2681080489/PJ.rar

Sintáxis: [ Descargar ] [ Ocultar ]
Using cpp Syntax Highlighting
  1. #include <SDL.h>
  2. #include <SDL_image.h>
  3. #include <string>
  4.  
  5.  
  6. const int PANTALLA_ANCHO = 800;
  7. const int PANTALLA_ALTO = 600;
  8. const int PANTALLA_BPP = 32;
  9. const int PJ_ANCHO = 90;
  10. const int PJ_ALTO = 115;
  11. const int NIVEL_ANCHO = 3000;
  12. const int NIVEL_ALTO = 3000;
  13. int var1 = 8;
  14. bool FIN = false;
  15.  
  16. SDL_Surface *PANTALLA = NULL;
  17. SDL_Surface *PJ = NULL;
  18. SDL_Surface *TERRENO = NULL;
  19. SDL_Rect CAMARA = { 0, 0, PANTALLA_ANCHO, PANTALLA_ALTO };
  20. SDL_Rect XXXR;
  21. SDL_Event EVENTO;
  22.  
  23. bool COLISION( SDL_Rect A, SDL_Rect B )
  24. {
  25.     //LOS LADOS DE LOS RECTANGULOS
  26.     int leftA, leftB;
  27.     int rightA, rightB;
  28.     int topA, topB;
  29.     int bottomA, bottomB;
  30.  
  31.     //CALCULAR LOS LADOS DE LA RECTA A
  32.     leftA = A.x;
  33.     rightA = A.x + A.w;
  34.     topA = A.y;
  35.     bottomA = A.y + A.h;
  36.  
  37.     //CALCULAR LOS LADOS DE LA RECTA B
  38.     leftB = B.x;
  39.     rightB = B.x + B.w;
  40.     topB = B.y;
  41.     bottomB = B.y + B.h;
  42.  
  43.     //SI ALGUNO DE LOS LADOS DESDE A ESTAN FUERA DE B
  44.     if( bottomA <= topB ){ return false; }
  45.  
  46.    if( topA >= bottomB ){ return false; }
  47.  
  48.     if( rightA <= leftB ){ return false; }
  49.  
  50.     if( leftA >= rightB ){ return false; }
  51.  
  52.     //SI NINGUNO DE LOS LADOS DESDE A ESTAN FUERA DE B
  53.     return true;
  54. }
  55.  
  56. class PJ_CLASE
  57. {
  58.     private:
  59.     //The X and Y offsets of the dot
  60.    SDL_Rect RECTA;
  61.    int x, y;
  62.  
  63.     //The velocity of the dot
  64.     int VELX, VELY;
  65.  
  66.     public:
  67.     //Initializes the variables
  68.     PJ_CLASE();
  69.  
  70.     //Takes key presses and adjusts the dot's velocity
  71.     void TECLADO();
  72.  
  73.     //Moves the dot
  74.     void MOVER();
  75.  
  76.     //Shows the dot on the screen
  77.     void MOSTRAR();
  78.  
  79.     //Sets the camera over the dot
  80.     void CAMARA_C();
  81. };
  82.  
  83.  
  84.  
  85.  
  86. SDL_Surface *CARGAR( std::string filename )
  87. {
  88.     //The image that's loaded
  89.     SDL_Surface* IMG_C = NULL;
  90.  
  91.     //The optimized surface that will be used
  92.     SDL_Surface* IMG_OPT = NULL;
  93.  
  94.     //Load the image
  95.     IMG_C = IMG_Load( filename.c_str() );
  96.  
  97.     //If the image loaded
  98.     if( IMG_C != NULL )
  99.     {
  100.         //Create an optimized surface
  101.         IMG_OPT = SDL_DisplayFormat( IMG_C );
  102.  
  103.         //Free the old surface
  104.         SDL_FreeSurface( IMG_C );
  105.  
  106.         //If the surface was optimized
  107.         if( IMG_OPT != NULL )
  108.         {
  109.             //Color key surface
  110.             SDL_SetColorKey( IMG_OPT, SDL_SRCCOLORKEY, SDL_MapRGB( IMG_OPT->format, 0, 0xFF, 0xFF ) );
  111.         }
  112.     }
  113.  
  114.     //Return the optimized surface
  115.     return IMG_OPT;
  116. }
  117.  
  118. void DIBUJAR( int x, int y, SDL_Surface* ORIGEN, SDL_Surface* DESTINO, SDL_Rect* CLIP = NULL )
  119. {
  120.     //Holds offsets
  121.     SDL_Rect RECTANGULO;
  122.  
  123.     //Get offsets
  124.     RECTANGULO.x = x;
  125.     RECTANGULO.y = y;
  126.    RECTANGULO.w = ORIGEN->w;
  127.    RECTANGULO.h = ORIGEN->h;
  128.  
  129.     //Blit
  130.     SDL_BlitSurface( ORIGEN, CLIP, DESTINO, &RECTANGULO );
  131. }
  132.  
  133. bool INICIAR()
  134. {
  135.     //Initialize all SDL subsystems
  136.     if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
  137.     {
  138.         return false;
  139.     }
  140.  
  141.     //Set up the screen
  142.     PANTALLA = SDL_SetVideoMode( PANTALLA_ANCHO, PANTALLA_ALTO, PANTALLA_BPP, SDL_SWSURFACE );
  143.  
  144.     //If there was an error in setting up the screen
  145.     if( PANTALLA == NULL )
  146.     {
  147.         return false;
  148.     }
  149.  
  150.     //Set the window caption
  151.     SDL_WM_SetCaption( "Movimiento De PJ", NULL );
  152.  
  153.     //If everything initialized fine
  154.     return true;
  155. }
  156.  
  157. bool CARGAR_ARCHIVOS()
  158. {
  159.     //Load the dot image
  160.     PJ = CARGAR( "pj_1.bmp" );
  161.    TERRENO = CARGAR( "terreno.bmp" );
  162.    
  163.    
  164.    
  165.  
  166.     //If there was a problem in loading the dot
  167.     if( PJ == NULL )
  168.     {
  169.         return false;
  170.     }
  171.  
  172.     //If there was a problem in loading the background
  173.     if( TERRENO == NULL )
  174.     {
  175.         return false;
  176.     }
  177.  
  178.     //If everything loaded fine
  179.     return true;
  180. }
  181.  
  182. void LIMPIAR_ARCHIVOS()
  183. {
  184.     //Free the surfaces
  185.     SDL_FreeSurface( PJ );
  186.     SDL_FreeSurface( TERRENO );
  187.    
  188.  
  189.  
  190.     //Quit SDL
  191.     SDL_Quit();
  192. }
  193.  
  194. PJ_CLASE::PJ_CLASE()
  195. {
  196.     //Initialize the offsets
  197.     RECTA.x = 0;
  198.     RECTA.y = 0;
  199.  
  200.     //Initialize the velocity
  201.     VELX = 0;
  202.     VELY = 0;
  203. }
  204.  
  205. void PJ_CLASE::TECLADO()
  206. {
  207.     //If a key was pressed
  208.     if( EVENTO.type == SDL_KEYDOWN )
  209.     {
  210.         //Adjust the velocity
  211.         switch( EVENTO.key.keysym.sym )
  212.         {
  213.             case SDLK_UP: VELY -= var1; break;
  214.             case SDLK_DOWN: VELY += var1; break;
  215.             case SDLK_LEFT: VELX -= var1; break;
  216.             case SDLK_RIGHT: VELX += var1; break;
  217.          case SDLK_a: RECTA.x=1300; RECTA.y=1500; break;
  218.         }
  219.     }
  220.     //If a key was released
  221.     else if( EVENTO.type == SDL_KEYUP )
  222.     {
  223.         //Adjust the velocity
  224.         switch( EVENTO.key.keysym.sym )
  225.         {
  226.             case SDLK_UP: VELY += var1; break;
  227.             case SDLK_DOWN: VELY -= var1; break;
  228.             case SDLK_LEFT: VELX += var1; break;
  229.             case SDLK_RIGHT: VELX -= var1; break;
  230.         }
  231.     }
  232.    if(EVENTO.key.keysym.sym == SDLK_ESCAPE){ FIN = true; }
  233. }
  234.  
  235. void PJ_CLASE::MOVER()
  236. {
  237.     RECTA.x += VELX;
  238.    RECTA.y+= VELY;
  239.    
  240.    if( RECTA.x < 0 ){ RECTA.x = RECTA.x -= VELX; }
  241.    if( RECTA.y < 0 ){ RECTA.y = RECTA.y-= VELY; }
  242.    if( RECTA.x +90  > 3000 ){ RECTA.x -= VELX; }
  243.    if( RECTA.y +115 > 3000 ){ RECTA.y-= VELY; }
  244.  
  245.    /*if( COLISION( RECTA,XXXR) ){ RECTA.x -= VELX;}
  246.    if( COLISION( RECTA,XXXR) ){ RECTA.y -= VELY;}*/
  247.  
  248.  
  249.    
  250.  
  251. }
  252.  
  253. void PJ_CLASE::MOSTRAR()
  254. {
  255.     //Show the dot
  256.     DIBUJAR( RECTA.x - CAMARA.x, RECTA.y - CAMARA.y, PJ, PANTALLA );
  257.    
  258. }
  259.  
  260. void PJ_CLASE::CAMARA_C()
  261. {
  262.    
  263.  
  264.    CAMARA.x = ( RECTA.x + PJ_ANCHO /2 ) - PANTALLA_ANCHO /2;
  265.     CAMARA.y = ( RECTA.y + PJ_ALTO /2 ) - PANTALLA_ALTO /2;
  266.  
  267.    if( CAMARA.x < 0 ){ CAMARA.x = 0; }
  268.     if( CAMARA.y < 0 ){ CAMARA.y = 0; }
  269.     if( CAMARA.x > 3000 - CAMARA.w ){ CAMARA.x = 3000 - CAMARA.w; }
  270.     if( CAMARA.y > 3000 - CAMARA.h ){CAMARA.y = 3000 - CAMARA.h; }
  271.  
  272.    
  273. }
  274.  
  275.  
  276. int main( int argc, char* args[] )
  277. {
  278.     //Quit flag
  279.  
  280.        
  281.    
  282.  
  283.     //The dot
  284.     PJ_CLASE MAKIA;
  285.  
  286.     //The frame rate regulator
  287.    
  288.  
  289.     //Initialize
  290.     if( INICIAR() == false )
  291.     {
  292.         return 1;
  293.     }
  294.  
  295.     //Load the files
  296.     if( CARGAR_ARCHIVOS() == false )
  297.     {
  298.         return 1;
  299.     }
  300.  
  301.    XXXR.x=1500;
  302.    XXXR.y=1500;
  303.    XXXR.w=150;
  304.    XXXR.h=150;
  305.  
  306.     //While the user hasn't quit
  307.     while( FIN == false )
  308.     {
  309.         //Start the frame timer
  310.        
  311.  
  312.         //While there's events to handle
  313.         while( SDL_PollEvent( &EVENTO ) )
  314.         {
  315.             //Handle events for the dot
  316.             MAKIA.TECLADO();
  317.  
  318.          
  319.          
  320.  
  321.             //If the user has Xed out the window
  322.             if( EVENTO.type == SDL_QUIT )
  323.             {
  324.                 //Quit the program
  325.                 FIN = true;
  326.             }
  327.              
  328.         }
  329.  
  330.         //Move the dot
  331.         MAKIA.MOVER();
  332.  
  333.         //Set the camera
  334.         MAKIA.CAMARA_C();
  335.  
  336.         //Show the background
  337.  
  338.         DIBUJAR( 0, 0, TERRENO, PANTALLA, &CAMARA );
  339.       SDL_FillRect( TERRENO, &XXXR, SDL_MapRGB( TERRENO->format, 0x77, 0x77, 0x77 ) );
  340.        
  341.         MAKIA.MOSTRAR();
  342.  
  343.  
  344.         //Update the screen
  345.         if( SDL_Flip( PANTALLA ) == -1 )
  346.         {
  347.             return 1;
  348.         }
  349.  
  350.         //Cap the frame rate
  351.        
  352.     }
  353.  
  354.     //Clean up
  355.     LIMPIAR_ARCHIVOS();
  356.  
  357.     return 0;
  358. }
  359.  
Coloreado en 0.006 segundos, usando GeSHi 1.0.8.4
mcmakia696
Perlero nuevo
Perlero nuevo
 
Mensajes: 1
Registrado: 2012-02-05 13:04 @586

Publicidad

Re: Cómo hacer colisiones con SDL

Notapor explorer » 2012-02-06 21:29 @937

Bienvenido a los foros de Perl en español, mcmakia696.

No he encontrado el fallo en el código (mi conocimiento de C++ es casi nulo, además de que se me ha olvidado lo poco que sabía :) )

Pero sí que hay ejemplos parecidos a lo que quieres hacer, como este tutorial.
JF^D Perl programming & Raku programming. Grupo en Telegram: https://t.me/Perl_ES
Avatar de Usuario
explorer
Administrador
Administrador
 
Mensajes: 14480
Registrado: 2005-07-24 18:12 @800
Ubicación: Valladolid, España


Volver a Programación en general

¿Quién está conectado?

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

cron