Thread: SDL not recognizing collisions

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

    SDL not recognizing collisions

    The only time it is stopping the character from going out of the screen is when it doesn't move from it's original x position it doesn't go left, and it doesn't let you shoot more then one time.
    here is my code
    Code:
    #include <SDL/SDL.h>
    #include <SDL/SDL_Image.h>
    #include <string>
    #include "class.h"
    
    using namespace std;
    
    SDL_Surface *screen = NULL;
    
    SDL_Rect space;
    
    SDL_Event event;
    
    bool quit = false;
    
    character person;
    bullet shoot;
    
    int collision_x(SDL_Rect A, SDL_Rect B){
        if(A.w == B.x){
            return 1;
        }
        if(A.x == B.w){
            return 2;
        }
        return 0;
    }
    
    int collision_y(SDL_Rect A, SDL_Rect B){
        if(A.y == B.h){
            return 1;
        }
        if(A.h == B.y){
            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;
                    case SDLK_RIGHT://
                    if(collision_x(person.coll, space) != 1){
                        person.xVel = 1;
                    }
                    break;
                    case SDLK_LEFT://
                    if(collision_x(person.coll, space) != 2){
                        person.xVel = -1;
                    }
                    break;
                    case SDLK_UP://
                    if(collision_y(person.coll, space) != 1){
                        person.yVel = -1;
                    }
                    break;
                    case SDLK_DOWN://
                    if(collision_y(person.coll, space) != 2){
                        person.yVel = 1;
                    }
                    break;
                    default: break;
            }
        }
        if(event.type == SDL_KEYUP){
                switch(event.key.keysym.sym){
                    case SDLK_RIGHT:person.xVel = 0; break;
                    case SDLK_LEFT:person.xVel = 0; break;
                    case SDLK_UP: person.yVel = 0; break;
                    case SDLK_DOWN:person.yVel = 0; break;
                    case SDLK_SPACE://
                    if(shoot.draw == false){
                        shoot.draw = true;
                        }
                        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;
        }
        SDL_WM_SetCaption("Shooter", NULL);
    
        space.x = 640;
        space.y = 480;
        space.w = 0;
        space.h = 0;
    
        return true;
    }
    
    void class_init(){
        //charecter init
        person.x = 0;
        person.y = 453;
        person.w = person.w;
        person.h = person.y + 28;
    
        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;
    
        //bullet init
        shoot.x = person.x + 19;
        shoot.y = person.y + 14;
        shoot.w = shoot.x + 7;
        shoot.h = shoot.y + 3;
    
        shoot.coll.x = shoot.x;
        shoot.coll.y = shoot.y;
        shoot.coll.w = shoot.w;
        shoot.coll.h = shoot.h;
    
        shoot.draw = false;
    
        shoot.bullet = NULL;
    }
    
    
    int main(int argc, char *argv[]){
    
        if(Init() == false){
            return 1;
        }
        class_init();
        person.person = load_image("person.png");
        shoot.bullet = load_image("bullet.png");
    
        while(quit == false){
            SDL_FillRect(screen, &screen->clip_rect, SDL_MapRGB(screen->format, 0x237, 0x20, 0x48));
    
            person.w = person.x + 19;
            person.h = person.y + 28;
            person.coll.x = person.x;
            person.coll.y = person.y;
            person.coll.w = person.w;
            person.coll.h = person.h;
            handle_events();
    
            person.x += person.xVel;
            person.y += person.yVel;
    
            apply_surface(person.x, person.y, person.person, screen);
            if(shoot.draw == false){
                shoot.draw = false;
                shoot.x = person.x + 19;
                shoot.y = person.y + 14;
                shoot.w = shoot.x + 7;
                shoot.h = shoot.y + 3;
    
                shoot.coll.x = shoot.x;
                shoot.coll.y = shoot.y;
                shoot.coll.w = shoot.w;
                shoot.coll.h = shoot.h;
            }
            if(shoot.draw == true){
                apply_surface(shoot.x, shoot.y, shoot.bullet, screen);
                shoot.x += 3;
                if(collision_x(shoot.coll, space) == 1){
                shoot.draw = false;
                shoot.x = person.x + 19;
                shoot.y = person.y + 11;
                shoot.w = shoot.x + 7;
                shoot.h = shoot.y + 3;
    
                shoot.coll.x = shoot.x;
                shoot.coll.y = shoot.y;
                shoot.coll.w = shoot.w;
                shoot.coll.h = shoot.h;
                }
            }
    
            SDL_Delay(1000/100);
    
            SDL_Flip(screen);
        }
    
        clean_up();
        return 0;
    }

  2. #2
    Just a pushpin. bernt's Avatar
    Join Date
    May 2009
    Posts
    426
    I'm not entirely sure what the problem is, much less what's causing it, but I'd like to point out that this line looks awfully suspicious:
    Code:
    void class_init(){
        //charecter init
        person.x = 0;
        person.y = 453;
        person.w = person.w;
        person.h = person.y + 28;
        ...
    Consider this post signed

  3. #3
    Registered User
    Join Date
    Nov 2009
    Posts
    151
    my problem is that you could can go through the sides of the game window event though it the collision_x and collision_y should stop it from doing so.

  4. #4
    Sweet
    Join Date
    Aug 2002
    Location
    Tucson, Arizona
    Posts
    1,820
    Your logic is a bit flawed.

    You are just checked part of the rectangle which doesn't give you what you are looking for.
    Code:
    int collision_x(SDL_Rect A, SDL_Rect B){
        if(A.w == B.x){
            return 1;
        }
        if(A.x == B.w){
            return 2;
        }
        return 0;
    }
    
    int collision_y(SDL_Rect A, SDL_Rect B){
        if(A.y == B.h){
            return 1;
        }
        if(A.h == B.y){
            return 2;
        }
        return 0;
    }
    Should be
    Code:
    int collision_x(SDL_Rect A, SDL_Rect B){
        int right = A.w + A.x;
        if(A.x <= B.x){
            return 1;
        }
        if(right >= B.w){
            return 2;
        }
        return 0;
    }
    
    int collision_y(SDL_Rect A, SDL_Rect B){
       int bottom = A.y + A.Height;
        if(bottom >= B.h){
            return 1;
        }
        if(A.y <= B.y){
            return 2;
        }
        return 0;
    }
    This isn't the best method. But I am assuming B represents the screens rect, where w = x + w, because x = 0(Same logic applies for y and height)
    Woop?

  5. #5
    Registered User
    Join Date
    Nov 2009
    Posts
    151
    well now, the only direction it could move is left and down, I'm currently trying some things out, but if you know whats wrong, tell me.
    Thanks.

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. Problems compiling this SDL app
    By Rider in forum C++ Programming
    Replies: 3
    Last Post: 03-27-2007, 12:22 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