Thread: SDL + Keys

  1. #16
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    SDL_FillRect() with a NULL parameter for the rect does what you are looking for: http://docs.mandragor.org/files/Comm...lfillrect.html
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  2. #17
    Registered User
    Join Date
    Jan 2007
    Posts
    188
    Yeeeah! Now almost all works...

    But if the user holds down a key, it stops after 1 step and if the user aint pressing any key, i wanna show piece.bmp!

    Code:
    Code:
    //The headers
    #include "SDL/SDL.h"
    #include <string>
    #include <iostream>
    
    using namespace std;
    
    //Screen attributes
    const int SCREEN_WIDTH = 640;
    const int SCREEN_HEIGHT = 480;
    const int SCREEN_BPP = 32;
    
    //The surfaces
    SDL_Surface *background = NULL;
    SDL_Surface *screen = NULL;
    SDL_Surface *piece = NULL;
    
    //The event structure
    SDL_Event event;
    
    SDL_Surface *load_image( std::string filename ) 
    {
        //The image that's loaded
        SDL_Surface* loadedImage = NULL;
        
        //The optimized surface that will be used
        SDL_Surface* optimizedImage = NULL;
        
        //Load the image
        loadedImage = SDL_LoadBMP( filename.c_str() );
        
        //If the image loaded
        if( loadedImage != NULL )
        {
            //Create an optimized surface
            optimizedImage = SDL_DisplayFormat( loadedImage );
            
            //Free the old surface
            SDL_FreeSurface( loadedImage );
        }
        
        //Return the optimized surface
        return optimizedImage;
    }
    
    SDL_Surface *apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
    {
        //Holds offsets
        SDL_Rect offset;
        
        //Get offsets
        offset.x = x;
        offset.y = y;
        
        //Blit
        SDL_BlitSurface( source, clip, destination, &offset );
        
        return 0;
    }
    
    bool init()
    {
        //Initialize all SDL subsystems
        if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
        {
            return false;    
        }
        
        //Set up the screen
        screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
        
        //If there was in error in setting up the screen
        if( screen == NULL )
        {
            return false;    
        }
        
        //Set the window caption
        SDL_WM_SetCaption( "Walk-around-game", NULL );
        
        //If everything initialized fine
        return true;
    }
    
    bool load_files()
    {
        //Load the background image
        background = load_image( "bg.bmp" );
        piece = load_image( "piece.bmp" );
        
        //If there was a problem in loading the background
        if( background == NULL )
        {
            return false;    
        }
        
        //If there was a problem in loading the background
        if( piece == NULL )
        {
            return false;    
        }
        
        //If everything loaded fine
        return true;
    }
    
    int clean_up()
    {
        //Free the surfaces
        SDL_FreeSurface( background );
        SDL_FreeSurface( piece );
        
        //Quit SDL
        SDL_Quit();
        
        return 0;
    }
    
    int main( int argc, char* args[] )
    {
        int x = 50;
        int y = 50;
        
        //Quit flag
        bool quit = false;
        
        //Initialize
        if( init() == false )
        {
            return 1;
        }
        
        //Load the files
        if( load_files() == false )
        {
            return 1;
        }
        
        //Apply the piece
        apply_surface( x, y, piece, screen );
        
        //Apply the background
        apply_surface( 0, 0, background, screen );
        
        //While the user hasn't quit
        while( quit == false )
        {
            //If there's an event to handle
            if( SDL_PollEvent( &event ) )
            {
                //If a key was pressed
                if( event.type == SDL_KEYDOWN )
                {
                    //Set the proper holder surface
                    switch( event.key.keysym.sym )
                    {
                        case SDLK_UP: 
                             x = x - 10; 
                             SDL_FillRect( screen, NULL, NULL); 
                             apply_surface( 0, 0, background, screen );
                             piece = load_image( "piece-up.bmp" ); 
                             apply_surface( y, x, piece, screen ); 
                             break;
                             
                        case SDLK_DOWN: 
                             x = x + 10; 
                             SDL_FillRect( screen, NULL, NULL ); 
                             apply_surface( 0, 0, background, screen );
                             piece = load_image( "piece-down.bmp" ); 
                             apply_surface( y, x, piece, screen ); 
                             break;
                             
                        case SDLK_LEFT: 
                             y = y - 10; 
                             SDL_FillRect( screen, NULL, NULL ); 
                             apply_surface( 0, 0, background, screen );
                             piece = load_image( "piece-left.bmp" ); 
                             apply_surface( y, x, piece, screen ); 
                             break;
                             
                        case SDLK_RIGHT:
                             y = y + 10; 
                             SDL_FillRect( screen, NULL, NULL ); 
                             apply_surface( 0, 0, background, screen );
                             piece = load_image( "piece-right.bmp" ); 
                             apply_surface( y, x, piece, screen ); 
                             break;
                             
                        case SDLK_ESCAPE: 
                             quit = true; 
                             break;    
                    }
                } 
                
                }    
                //If the user has Xed out the window
                else if( event.type == SDL_QUIT )
                {
                    //Quit the program
                    quit = true;
                }
        
            //Update the screen
            if( SDL_Flip( screen ) == -1 )
            {
                return 1;    
            }
        }
            
            
        //Clean up
        clean_up();
        
        return 0;    
    }
    Please help me!
    Last edited by Livijn; 05-07-2007 at 12:52 AM.

  3. #18
    Registered User
    Join Date
    Jan 2007
    Posts
    188
    Pllllllllease..... :P

  4. #19
    Registered User
    Join Date
    Jan 2007
    Posts
    188
    I've added and changed some code... I tried to get the non-press?-show-piece.png-thing, but it fails. So i need help please. And 1 more thing, when i compile and drive it works but if i double-click at the .exe file on my hardrive, it doesn't. It pops up and closes.

    Code:
    //The headers
    #include "SDL/SDL.h"
    #include "SDL/SDL_image.h"
    #include <string>
    #include <iostream>
    
    using namespace std;
    
    //Screen attributes
    const int SCREEN_WIDTH = 640;
    const int SCREEN_HEIGHT = 480;
    const int SCREEN_BPP = 32;
    
    //The surfaces
    SDL_Surface *background = NULL;
    SDL_Surface *screen = NULL;
    SDL_Surface *piece = NULL;
    
    //The event structure
    SDL_Event event;
    
    SDL_Surface *load_image( std::string filename ) 
    {
        //The image that's loaded
        SDL_Surface* loadedImage = NULL;
        
        //The optimized surface that will be used
        SDL_Surface* optimizedImage = NULL;
        
        //Load the image
        loadedImage = IMG_Load( filename.c_str() );
        
        //If the image loaded
        if( loadedImage != NULL )
        {
            //Create an optimized surface
            optimizedImage = SDL_DisplayFormat( loadedImage );
            
            //Free the old surface
            SDL_FreeSurface( loadedImage );
            
            
            //If the image was optimized just fine
            if( optimizedImage != NULL )
            {
                //Map the color key
                Uint32 colorkey = SDL_MapRGB( optimizedImage->format, 0xFA, 0xF9, 0x7C );
                
                //Set all pixels of color R 0, G 0xFF, B 0xFF to be transparent
                SDL_SetColorKey( optimizedImage, SDL_RLEACCEL | SDL_SRCCOLORKEY, colorkey );
            }
        }
        
        //Return the optimized surface
        return optimizedImage;
    }
    
    SDL_Surface *apply_surface( int x, int y, SDL_Surface* source, SDL_Surface* destination, SDL_Rect* clip = NULL )
    {
        //Holds offsets
        SDL_Rect offset;
        
        //Get offsets
        offset.x = x;
        offset.y = y;
        
        //Blit
        SDL_BlitSurface( source, clip, destination, &offset );
        
        return 0;
    }
    
    bool init()
    {
        //Initialize all SDL subsystems
        if( SDL_Init( SDL_INIT_EVERYTHING ) == -1 )
        {
            return false;    
        }
        
        //Set up the screen
        screen = SDL_SetVideoMode( SCREEN_WIDTH, SCREEN_HEIGHT, SCREEN_BPP, SDL_SWSURFACE );
        
        //If there was in error in setting up the screen
        if( screen == NULL )
        {
            return false;    
        }
        
        //Set the window caption
        SDL_WM_SetCaption( "Walk-around-game", NULL );
        
        //If everything initialized fine
        return true;
    }
    
    bool load_files()
    {
        //Load the background image
        background = load_image( "bg.jpg" );
        piece = load_image( "howto.png" );
        
        //If there was a problem in loading the background
        if( background == NULL )
        {
            return false;    
        }
        
        //If there was a problem in loading the background
        if( piece == NULL )
        {
            return false;    
        }
        
        //If everything loaded fine
        return true;
    }
    
    int clean_up()
    {
        //Free the surfaces
        SDL_FreeSurface( background );
        SDL_FreeSurface( piece );
        
        //Quit SDL
        SDL_Quit();
        
        return 0;
    }
    
    int main( int argc, char* args[] )
    {
        //The pieces coordinates
        int x = 200;
        int y = 200;
        
        //Keydown flag
        bool keydown = false;
        
        //Quit flag
        bool quit = false;
        
        //Initialize
        if( init() == false )
        {
            return 1;
        }
        
        //Load the files
        if( load_files() == false )
        {
            return 1;
        }
        
        //Apply the background
        apply_surface( 0, 0, background, screen );
        
        //Apply the piece
        apply_surface( 70, 178, piece, screen );
        
        //While the user hasn't quit
        while( quit == false )
        {
            //If there's an event to handle
            if( SDL_PollEvent( &event ) )
            {
                //If a key was pressed
                if( event.type == SDL_KEYDOWN )
                {
                    //Set the proper holder surface
                    switch( event.key.keysym.sym )
                    {                       
                        case SDLK_LEFT: 
                             x = x - 10; 
                             SDL_FillRect( screen, NULL, NULL ); 
                             apply_surface( 0, 0, background, screen );
                             piece = load_image( "piece-left.png" ); 
                             apply_surface( x, y, piece, screen ); 
                             break;
                             
                        case SDLK_RIGHT:
                             x = x + 10; 
                             SDL_FillRect( screen, NULL, NULL ); 
                             apply_surface( 0, 0, background, screen );
                             piece = load_image( "piece-right.png" ); 
                             apply_surface( x, y, piece, screen ); 
                             break;
                             
                        case SDLK_ESCAPE: 
                             quit = true; 
                             break;    
                    }
                } 
                
                }    
                //If the user has Xed out the window
                else if( event.type == SDL_QUIT )
                {
                    //Quit the program
                    quit = true;
                }
        
            //Update the screen
            if( SDL_Flip( screen ) == -1 )
            {
                return 1;    
            }
        }
            
            
        //Clean up
        clean_up();
        
        return 0;    
    }
    Help me! I would be glad even for the smallest notice!

  5. #20
    Registered User
    Join Date
    May 2007
    Location
    Tanzania
    Posts
    1
    I'm not quite sure what you mean in your most recent post when you say "but it fails". For the issue of only moving once when you press a key, my understanding (I'm new to C++ and SDL too) is that SDL only generates events when a key changes state.

    So when you press a key down, one event is generated. Another event will not be generated for that key until it is released again - even if you hold the key for an hour there will be no more events until it it released.

    What is the solution for this? You need to use a flag variable to determine whether the key is currently pressed down or not. When you detect a key press, make this value true. When you detect a key release, make it false. Then in a separate part of your code you can check if that flag value is true, and if it is, perform your moves.
    Last edited by tiktok; 05-08-2007 at 02:50 AM.

  6. #21
    Registered User
    Join Date
    Jan 2007
    Posts
    188
    Yeah! I solved one problem or two now! Hold down the key, won't work. Why?!

    Code:
        //While the user hasn't quit
        while( quit == false )
        {  
            //If there's an event to handle
            if( SDL_PollEvent( &event ) )
            {
                //If a key was pressed
                if( event.type == SDL_KEYDOWN )
                {
                    //Set the proper holder surface
                    switch( event.key.keysym.sym )
                    {                       
                        case SDLK_LEFT: 
                             left = true;
                             break;
                             
                        case SDLK_RIGHT:
                             right = true;
                             break;
                             
                        case SDLK_ESCAPE: 
                             quit = true; 
                             break;    
                    }
                } 
                
                //Check if the right is pressed
                while (right == true)
                {
                             x = x + 10; 
                             SDL_FillRect( screen, NULL, NULL ); 
                             apply_surface( 0, 0, background, screen );
                             piece = load_image( "piece-right.png" ); 
                             apply_surface( x, y, piece, screen ); 
                }
                
                //Check if the left is pressed
                while (left == true)
                {
                             x = x - 10; 
                             SDL_FillRect( screen, NULL, NULL ); 
                             apply_surface( 0, 0, background, screen );
                             piece = load_image( "piece-left.png" ); 
                             apply_surface( x, y, piece, screen ); 
                }
                
                }    
                //If the user has Xed out the window
                else if( event.type == SDL_QUIT )
                {
                    //Quit the program
                    quit = true;
                }
        
            //Update the screen
            if( SDL_Flip( screen ) == -1 )
            {
                return 1;    
            }
        }
    This is a part of the code. Why does it fail? The thing that happen is that nothing happens. When i press a key, i want howto.png to disappear. I know how to do this, but nothing happens. Please explain why1
    Last edited by Livijn; 05-08-2007 at 01:26 PM.

  7. #22
    Registered User
    Join Date
    Jan 2007
    Posts
    188
    Changed my problem

  8. #23
    Frequently Quite Prolix dwks's Avatar
    Join Date
    Apr 2005
    Location
    Canada
    Posts
    8,057
    When i press a key, i want howto.png to disappear.
    In order to do this, you need to paint over the area where howto.png was located with SDL_FillRect(), and then call SDL_UpdateRect() to make the changes visible (after making any other changes you might want to the screen). I don't see any calls to SDL_UpdateRect() in your code, but perhaps I'm missing something. (Or perhaps SDL_Flip() works as well, I don't know.)
    dwk

    Seek and ye shall find. quaere et invenies.

    "Simplicity does not precede complexity, but follows it." -- Alan Perlis
    "Testing can only prove the presence of bugs, not their absence." -- Edsger Dijkstra
    "The only real mistake is the one from which we learn nothing." -- John Powell


    Other boards: DaniWeb, TPS
    Unofficial Wiki FAQ: cpwiki.sf.net

    My website: http://dwks.theprogrammingsite.com/
    Projects: codeform, xuni, atlantis, nort, etc.

  9. #24
    Registered User
    Join Date
    Jan 2007
    Posts
    31
    ok i dont think this will help much but lazyfoo has some great sdl tutorials ill find the link and post it but if u cant wait for that just google lazyfoo it goes through most of the sdl routines u would need i think your problem might be thw while loops try this?
    Code:
      //Check if the right is pressed
                if (right == true)
                {
                             x = x + 10; 
                             SDL_FillRect( screen, NULL, NULL ); 
                             apply_surface( 0, 0, background, screen );
                             piece = load_image( "piece-right.png" ); 
                             apply_surface( x, y, piece, screen ); 
                }
    this way it will loop past this every time instead of relooping just this part
    so every time it loops past it will x+= 10;
    at least i think it will

  10. #25
    Registered User
    Join Date
    Jan 2007
    Posts
    31
    im not 100% because i havent used sdl or programmed in a while now but
    i think sdl_flip() acts as a buffer and stores the next screen ready to display
    so if u load a black white screen onto the screen
    Code:
          applysurface(0,0,blankscreen,screen);
    blankscreen being a white screen the same size as the (screen)

    then when u flip it will be blank

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Simulate Keys with a Keyboard Hook
    By guitarist809 in forum Windows Programming
    Replies: 3
    Last Post: 11-14-2008, 08:14 PM
  2. Problems compiling this SDL app
    By Rider in forum C++ Programming
    Replies: 3
    Last Post: 03-27-2007, 12:22 PM
  3. SDL and MinGW Studio
    By Vicious in forum Tech Board
    Replies: 0
    Last Post: 07-30-2004, 09:59 PM
  4. SDL and Windows
    By nickname_changed in forum Windows Programming
    Replies: 14
    Last Post: 10-24-2003, 12:19 AM
  5. sdl in c++
    By Klinerr1 in forum C++ Programming
    Replies: 8
    Last Post: 07-07-2002, 07:46 AM