SDL Simple 2d Colision

Ok I am trying to make a colision between my image and the rect but its not working so well, i do not know how to get the current position of the red rectangle.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
#include <SDL.h>

int main(int argc, char *argv[])
{
    SDL_Init(SDL_INIT_EVERYTHING);

    //Setting icon and caption of the window
    SDL_WM_SetCaption("Simple Game", "Icon");
    SDL_WM_SetIcon(SDL_LoadBMP("Icon.bmp"), NULL);

    //Loading and setting up Image, Screen and Icon
    SDL_Surface *image;
    image = SDL_LoadBMP("Test.bmp");

    SDL_Surface *screen;
    screen = SDL_SetVideoMode(800, 600, 32, SDL_SWSURFACE);

    SDL_Surface *icon;
    icon = SDL_LoadBMP("Icon.bmp");


    //Check if game is running, set FPS to 400
    //and setting gravity
    bool running = true;
    int gravity = 1;
    const int FPS = 400;
    Uint32 start;

    //Create Rectangle
    SDL_Rect rect;
    rect.x = 400;
    rect.y = 500;
    rect.w = 32;
    rect.h = 32;

    //Key States, screen and rectangle colors
    Uint8 *keyStates = SDL_GetKeyState(0);
    Uint32 RectColor = SDL_MapRGB(screen->format, 234, 0, 45);
    Uint32 ScreenColor = SDL_MapRGB(screen->format, 25, 23, 90);

    //Offsetting the bmp image
    SDL_Rect offset;
    offset.x = 0;
    offset.y = 570;

    //Main Game Loop
    while(running)
    {
        start = SDL_GetTicks();
        SDL_Event event;
        while(SDL_PollEvent(&event))
        {
            switch(event.type)
            {
                case SDL_QUIT:
                    running = false;
                    break;
            }
        }

        //WASD Key Movement
        if(keyStates[SDLK_w])
        {
            //offset.y -= 1;
        }
        if(keyStates[SDLK_a])
        {
            offset.x -= 1;
        }
        if(keyStates[SDLK_s])
        {
            //offset.y += 1;
        }
        if(keyStates[SDLK_d])
        {
            offset.x += 1;
        }

        //
        if((keyStates[SDLK_s]) && (offset.y == 570))
        {
            offset.y -= 1;
        }
        if((keyStates[SDLK_d]) && (offset.x == 770))
        {
            offset.x -= 1;
        }
        if(offset.y == rect.y)
        {
            offset.x -= 1;
        }

        //Jump Controls
        if(keyStates[SDLK_SPACE])
        {
            offset.y -= 2;
        }
		if(offset.y < 570)
		{
            offset.y += gravity;
		}
		if(offset.y < 500)
		{
		    offset.y += gravity;
		    keyStates[SDLK_SPACE] = SDL_RELEASED;
		}

		//Colision
        if((offset.y == rect.h) || (offset.y == rect.w))
        {
            offset.x -= 0;
        }
        if((offset.x == rect.h) || (offset.x == rect.w))
        {
            offset.y += 0;
        }

        //We are blitting image, NULL, telling what we are blitting image to
        SDL_FillRect(screen, NULL, ScreenColor);
        SDL_FillRect(screen, &rect, RectColor);
        SDL_BlitSurface(image, NULL, screen, &offset);
        SDL_Flip(screen);

        //Setting FPS
        if(1000/FPS>SDL_GetTicks()-start)
        {
            SDL_Delay(1000/FPS-(SDL_GetTicks()-start));
        }
    }

    //Delete image
    SDL_FreeSurface(image);
    SDL_FreeSurface(screen);
    SDL_Quit();
}
I'm working on a 2D game with SDL right now as well. The way I understand it is that when you apply the image you also apply an SDL_Rect at the current position(and size) of the image. Then in your game loop, the image and rect coords are modified simultaneously so they follow each other. You detect the collision by comparing the values of the image rectangle and the red rectangle you're drawing to the screen.

If I'm reading this right.. the second argument of SDL_FillRect() dictates the offset of the rect you're drawing relative to the top-left of the screen. So, modify and track that argument and you should be good to go.
Last edited on
Can you show me with code what i need to do please? Im a visual learner
Okay. Forewarning I have not compiled this code yet as I'm about to go out. But I think this shows you the basic idea of what's happening. You have two rectangles; the red one, and another which follows the image. You compare the two rectangles together to see if a collision occurred. If it has, you reduce the X or Y velocities to compensate for the increase upon input.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#include "SDL.h"
#include "SDL/SDL_image.h"
#include <string>
using namespace std;

void applySurface(int x, int y, SDL_Surface *source, SDL_Surface *destination, SDL_Rect &clip);
SDL_Surface *loadImage(string filename);
bool init();
bool loadFiles();
bool cleanUp();

const int scrWidth = 640;
const int scrHeight = 480;
const int scrBPP = 32; 

SDL_Surface *screen = NULL;
SDL_Surface *background = NULL;
SDL_Surface *image = NULL;
SDL_Rect redRect;
SDL_Rect imageRect;
Uint32 RectColor = SDL_MapRGB(screen->format, 234, 0, 45);

SDL_Event event;

int main(int argc, char **argv)
{
  bool quit = false;
  if(init()==false){return 1;}
  if(loadFiles()==false){return 1;}
  //To move the rectangle on the screen.
  int xVel = 10; yVel = 10; 
  //Tracks the position of the image rectangle following the image. 
  int imageX = 10; imageY = 10; 
  //This stuff can go anywhere, but for time's sake I'm putting it here.
  redRect.x = 320;
  redRect.y = 240;
  redRect.w = 100;
  redRect.h = 100;
  imageRect.w = 50;
  imageRect.h = 50;

  while(quit==false)
  {
    while(SDL_PollEvent(&event))
    {
    if(event.type == SDL_QUIT)
    { quit = true; }
    if(event.type==SDL_KEYDOWN)
    {
     switch(event.key.keysym.sym)
     {
       case SDLK_w: imageY -= yVel; break;
       case SDLK_s: imageY += yVel; break;
       case SDLK_a: imageX -= xVel; break;
       case SDLK_d: imageX += xVel; break;
     }
    }
    if(event.type==SDLK_KEYUP)
    {
     switch(event.key.keysym.sym)
     {
       case SDLK_w: imageY += yVel; break;
       case SDLK_s: imageY -= yVel; break;
       case SDLK_a: imageX += xVel; break;
       case SDLK_d: imageX -= xVel; break;
     }
    }
    //Updates the image rect to the current image position.
   //This way we can detect collisions. 
    imageRect.x = imageX;
    imageRect.y = imageY;

    //Check for X collisions on right side of red rect.
    if((imageRect.x+imageRect.w)==redRect.x)
    { imageX-=xVel; }

    //Check for X collision on left side of red rect. 
    if((redRect.x+redRect.w)==imageRect.x)
    { imageX+=xVel; }

    //Y collision on bottom of box.
    if((imageRect.y+imageRect.h)==redRect.y)
    { imageY+=yVel; }

    //Y collision on top of box. 
    if((redRect.y+=redRect.h)==imageRect.y)
    { imageY-=yVel; }

    applySurface(0,0,background,screen);
    applySurface(imageX,imageY,image,screen);
    SDL_FillRect(screen,&redRect,RectColor); 
  }
  cleanUp();
return 0;
}

void applySurface(int x,int y,SDL_Surface *source,SDL_Surface *destination,SDL_Rect *clip)
{
 SDL_Rect offset;
 offset.x = x;
 offset.y = y;
 SDL_BlitSurface(source,clip,destination,&offset);
}
SDL_Surface *loadImage(string filename)
{
  SDL_Surface *loadedImage = NULL;
  SDL_Surface *optimizedImage = NULL;
  loadedImage = IMG_Load (filename.c_str());
  if(loadedImage!=NULL) {
    optimizedImage = SDL_DisplayFormat(loadedImage);
    SDL_FreeSurface(loadedImage);
  }
  if(optimizedImage != NULL) {
    Uint32 colorKey = SDL_MapRGB(optimizedImage->format,0xFF,0xFF,0xFF);
    SDL_SetColorKey(optimizedImage,SDL_SRCCOLORKEY,colorKey);
   return optimizedImage; 
  }
}
bool init()
{
  if(SDL_Init(SDL_INIT_EVERYTHING)==-1) {return false;}
  screen = SDL_SetVideoMode(scrWidth,scrHeight,scrBPP,SDL_SWSURFACE);
  if(screen==NULL){return false;}
  SDL_WM_SetCaption(title.c_str(),NULL);
 return true;
}
void cleanUp()
{
  SDL_FreeSurface(background);
  SDL_FreeSurface(image);
  SDL_Quit();

}
bool loadFiles()
{
  background = loadImage("background.bmp");
  image = loadImage("image.bmp");
  if((background==NULL)||(image==NULL))
  { return false; }
 return true;
}
Topic archived. No new replies allowed.