Jump to content
  • Advertisement
Sign in to follow this  
Ariste

Simple collision detection problem...

This topic is 4886 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey everyone. I just started out working with SDL yesterday and have been going through a few tutorials. The first simple program I am trying to write is one that just displays a ball that bounces around the screen. I took the exercise right off one of the tutorials on this site (http://www.gamedev.net/reference/programming/features/sdl2/page5.asp) and tried to make the program for myself. The only problem is that, no matter what I try to do, the collision detection doesn't work correctly. Even if I take the code directly from the tutorial and paste it into a new project it won't work correctly. The ball just flys right off the screen. Here's the code I've been using:
/*Global Variables*/
int xBallSpeed = 1;
int yBallSpeed = 2;
const int ScreenWidth = 1024;
const int ScreenHeight = 740;
/*End Global Variables*/



int main(int argc, char *argv[])
{
    /*Initialize SDL*/
    if (retValCheck(SDL_Init(SDL_INIT_VIDEO)) == 1) return 1;
    atexit(SDL_Quit);
    
    /*Create a surface for the screen and initialize it*/
    SDL_Surface* screen;
    screen = SDL_SetVideoMode(ScreenWidth, ScreenHeight, 32, SDL_HWSURFACE | SDL_ANYFORMAT);
    
    
    /*Create surface for the ball*/
    SDL_Surface* ball = SDL_LoadBMP("ball.bmp");
    
    
    //Create Event type
    SDL_Event event;
    
    //Create Src and Dest rectangles
    SDL_Rect rSrc, rDest;
    rSrc.w = ball->w;
    rSrc.h = ball->h;
    rSrc.x = 0;
    rSrc.y = 0;
    rDest = rSrc;
    
    
    /*Begin Drawing*/
    while(true)
    {
       //Check for events
       if(SDL_PollEvent(&event))
       {
         if (event.type == SDL_QUIT) break;
       }
       //Clear screen for redrawing...DOUBLEBUF is better?
       SDL_FillRect(screen, NULL, 0);
       
       //Blit ball to screen
       SDL_BlitSurface(ball, &rSrc, screen, &rDest);
       
       //Move the ball
       rDest.x += xBallSpeed;
       rDest.y += yBallSpeed;

       //Check for collision
       if (rDest.x == 0 || rDest.x == ScreenWidth - rDest.w)  xBallSpeed = -xBallSpeed;
       if (rDest.y == 0 || rDest.y == ScreenHeight - rDest.h) yBallSpeed = -yBallSpeed;
       //Update surface
       SDL_UpdateRect(screen, 0, 0, 0, 0);
    }
     
    
  
    return 0;
}




The strange thing is that if, in the collision detection part, I use the line
if (rDest.x == 0 || rDest.x == ScreenWidth - rDest.x)
instead of what's there (notice the use of the x coordinate rather than the width), and as long as the ball hits the side wall first (xBallSpeed is greater than yBallSpeed), the ball will bounce first before getting to the side wall and then will bounce off the bottom wall correctly. If, however, I invert the x and y ball speeds and the ball reaches the bottom wall before reaching the side wall, it will just slide off the screen. The same is true in the reverse (using y instead of h). So... any ideas? I know it's a simple problem, but I don't want to move on without understanding how to do such simple collision detection as this. Any advice would be appreciated. Thanks,

Share this post


Link to post
Share on other sites
Advertisement
I see that you're using 1 intead of 2 for the x speed of the ball. Try 2.

But that's still not a good solution. Don't use ==. The chances of the ball's coordinates matching EXACTLY 0 or x - screenwidth is pretty low if not using 2 for both the speeds. Instead use < and >. Also, just inverting the velocity isn't going to work very well either, because if you happen to move past a boundary very far you'll invert the speed, but the ball won't have time to move back into valid space before you check again, discover the ball is outside the boundary, and invert the speed again, resulting in a ball that sits there and vibrates. You'll want to take the velocity into account, like this:

if (x < 0 && speed_x < 0) speed_x = -speed_x;
if (x > screenwidth && speed_x > 0) speed_x = -speed_x;
// and same thing for Y

Share this post


Link to post
Share on other sites
Quote:
Original post by Lazy Foo
Well if those tutorials are giving you trouble you try out mine:

http://lazyfooproductions.com/SDL_tutorials/index.php

</spam>


Don't worry, I pimp my warez all the time.

:see sig:

Share this post


Link to post
Share on other sites
Awesome, thanks Brad. That helped a lot. Now if I can just get it to work with a Pong clone... I feel like such a newb here =P

Thanks for the links Foo, I'll definitely give them a look.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!