Thread: SDL movement

  1. #1
    Registered User
    Join Date
    Nov 2009
    Posts
    151

    SDL movement

    This is a very weird problem. One thing is that you have to hit the key a while for the sprite to move, and when you release the key it continues to move int that direction.

    here is my code
    Code:
    #include <SDL/SDL.h>
    #include <SDL/SDL_Image.h>
    #include <string>
    
    using namespace std;
    
    SDL_Surface *screen = NULL;
    
    SDL_Event event;
    
    bool quit = false;
    
    class character{
        public:
        void handle_events();
    
        SDL_Surface *person;
    
        int x;
        int y;
        int h;
        int w;
    
        SDL_Rect coll;
    
        int xVel;
        int yVel;
    
        private:
        int collision_x();
        int collision_y();
    };
    
    character person;
    
    int character::collision_x(){
        if(coll.w == 640){
            return 1;
        }
        if(coll.x == 0){
            return 2;
        }
        return 0;
    }
    
    int character::collision_y(){
        if(coll.y == 0){
            return 1;
        }
        if(coll.h == 480){
            return 2;
        }
        return 0;
    }
    
    void handle_events(){
        if(SDL_PollEvent(&event)){
            if(event.type == SDL_QUIT){
                quit = true;
            }
            if(event.type == SDL_KEYDOWN){
                switch(event.key.keysym.sym){
                    case SDLK_ESCAPE: quit = true; break;
                    default: break;
                }
            }
        }
    }
    void character::handle_events(){
        if(SDL_PollEvent(&event)){
            if(event.type == SDL_KEYDOWN){
                switch(event.key.keysym.sym){
                    case SDLK_RIGHT://
                    if(collision_x() != 1){
                        xVel = 1;
                    }
                    break;
                    case SDLK_LEFT://
                    if(collision_x() != 2){
                        xVel = -1;
                    }
                    break;
                    case SDLK_UP://
                    if(collision_y() != 1){
                        yVel = -1;
                    }
                    break;
                    case SDLK_DOWN://
                    if(collision_y() != 2){
                        yVel = 1;
                    }
                    break;
                    default: break;
                }
            }
            if(event.type == SDL_KEYUP){
                switch(event.key.keysym.sym){
                    case SDLK_RIGHT:xVel = 0; break;
                    case SDLK_LEFT:xVel = 0; break;
                    case SDLK_UP: yVel = 0; break;
                    case SDLK_DOWN:yVel = 0; break;
                    default: break;
                }
            }
    
        }
    }
    
    void apply_surface(int X, int Y, SDL_Surface *source, SDL_Surface *destination){
        SDL_Rect pos;
        pos.x = X;
        pos.y = Y;
    
        SDL_BlitSurface(source, NULL, screen, &pos);
    }
    
    SDL_Surface *load_image(string filename){
        SDL_Surface *surface = NULL;
        SDL_Surface *optSurface = NULL;
    
        surface = IMG_Load(filename.c_str());
    
        if(surface != NULL){
            optSurface = SDL_DisplayFormat(surface);
            SDL_FreeSurface(surface);
            if(optSurface != NULL){
            SDL_SetColorKey( optSurface, SDL_SRCCOLORKEY, SDL_MapRGB( optSurface->format, 0, 0xFF, 0xFF ) );
            }
        }
        return optSurface;
    }
    
    void clean_up(){
        SDL_FreeSurface(person.person);
    
        SDL_Quit;
    }
    
    bool Init(){
        if(SDL_Init(SDL_INIT_EVERYTHING) == -1){
            return false;
        }
    
        screen = SDL_SetVideoMode(640, 480, 32, SDL_SWSURFACE);
    
        if(screen == NULL){
            return 0;
        }
        person.x = 0;
        person.y = 448;
        person.w = person.x + 32;
        person.h = person.y + 32;
    
        person.coll.x = person.x;
        person.coll.y = person.y;
        person.coll.w = person.w;
        person.coll.h = person.h;
    
        person.xVel = 0;
        person.yVel = 0;
    
        person.person = NULL;
    
        return true;
    }
    
    int main(int argc, char *argv[]){
    
        if(Init() == false){
            return 1;
        }
        person.person = load_image("person.png");
    
        while(quit == false){
            SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0x237, 0x20, 0x48));
    
            handle_events();
            person.handle_events();
    
            person.x += person.xVel;
            person.y += person.yVel;
            person.w = person.x + 32;
            person.h = person.y + 32;
    
            apply_surface(person.x, person.y, person.person, screen);
    
            SDL_Delay(1000/50);
    
            SDL_Flip(screen);
        }
    
        clean_up();
        return 0;
    }

  2. #2
    Registered User
    Join Date
    Aug 2005
    Posts
    266
    the problem is probably a mix between the SDL_Delay + if( Poll queue )

    try evaluating every single event during the handle events method by using while ( poll queue ) instead of if , message back if it worked

  3. #3
    Registered User
    Join Date
    Nov 2009
    Posts
    151
    still the same problem

  4. #4
    Registered User
    Join Date
    Nov 2007
    Posts
    46
    One thing is that you have to hit the key a while for the sprite to move
    I think that's because you're polling the event from the event queue in the global function handle_events function, then you poll it again in character::handle_event. This means it has to wait till the system decides that it should repeat the "key down" event for the keyboard.

    The second problem could come from the first problem, because the "key up" event will never be repeated, and so character::handle_event() will most likely never get to see an SDL_KEYUP event.

    To solve this, you could create some "object" base class and derive character, and all other objects that needs event handling, from that, keep a list of them, and then dispatch events to all the individual classes. That, or simply just store the event structure and return it from the global handle_events, then pass it to the member handle_events function and use that instead.

    The suggestion might be a bit unclear, but that's the best I can do at this moment.

  5. #5
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    Post the latest code.
    Woop?

  6. #6
    Registered User
    Join Date
    Nov 2009
    Posts
    151
    I understood what you were saying JacobN, i just took the contents out of chararacter::handle_events into the regular handle events and it worked.
    Last edited by bijan311; 05-24-2010 at 05:40 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. A little class problem
    By bijan311 in forum C++ Programming
    Replies: 12
    Last Post: 05-23-2010, 11:42 AM
  2. SDL project setup
    By rogster001 in forum C Programming
    Replies: 22
    Last Post: 08-28-2009, 08:05 AM
  3. SDL movement
    By zergdeath1 in forum C++ Programming
    Replies: 9
    Last Post: 11-20-2004, 11:42 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