I have a set of random x and y co-ordinate values generated and have stored them to a multimap and then have copied the list of x co-ordinate values to a vector x and the list of y co-ordinate values to a vector y and then have passed them in the function iteratively
bool Sprite::collisionExists( int x, int y, SDL_Rect b )
and I pass it in mycheckCollisions()
function in an if statement like this
collisionExists( x[k],y[l],sprite)
where sprite is the SDL_Rect type I created in that function.
I have a tile map created filled with rocks where I want the sprite to move around in the map but not being able to go forward if a rock is in the next tile.
The problem I am facing is that I can't seem to detect any collision when I created a vector and compared each value whereas before when it tested it with only two images the code worked perfectly.
Here is the code where I randomly insert the x and y co-ordinate values for the tiled map
//randomly set positions of the rocks
void setRandomRockPositions()
{
for(int i=0;i<40;i++)
{
int x,y;
int minX=3;
int maxX=8;
x=roll(minX,maxX);
int minY=1;
int maxY=9;
y=roll(minY,maxY);
//if x and y are not the location for the house tile, add a rock
if((x!=9 && y!=5))
{
rocks.insert(std::pair<int, int>(x, y));
}
}
}
Some variables and constant declarations
//Screen attributes
const int SCREEN_WIDTH = 1024;
const int SCREEN_HEIGHT = 728;
// Scaling the tiles to be 80x80
const int TILE_SIZE = 80;
std::multimap<int, int> rocks;
static const int SPRITE_WIDTH = 104;
static const int SPRITE_HEIGHT = 96;
The code for detecting collision between the sprite and rocks
bool Sprite::checkCollisions()
{
SDL_Rect sprite;
sprite.x= mPosX;
sprite.y=mPosY;
sprite.w=SPRITE_WIDTH;
sprite.h=SPRITE_HEIGHT;
std::vector<int> x(rocks.size());
std::vector<int> y(rocks.size());
std::multimap<int,int>::iterator it=rocks.begin();
while(it!=rocks.end())
{
for(int i=0;i<rocks.size();i++)
{
x[i]= (*it).first;
++it;
}
}
std::multimap<int,int>::iterator it2=rocks.begin();
while(it2!=rocks.end())
{
for(int j=0;j<rocks.size();j++)
{
y[j]=(*it2).second;
++it2;
}
}
for(int k=0;k<rocks.size();k++)
{
for(int l=0; l<rocks.size();l++)
{
if(collisionExists( x[k],y[l],sprite))
{
return true;
std::cout<<"Collision Detected!"<<std::endl;
}
}
}
return false;
}
The basic detection collision code
bool Sprite::collisionExists( int x, int y, SDL_Rect b )
{
//The sides of the rectangles
int leftA, leftB;
int rightA, rightB;
int topA, topB;
int bottomA, bottomB;
//Calculate the sides of rect A
leftA = x;
rightA = x + SPRITE_WIDTH;
topA = y;
bottomA = y + SPRITE_HEIGHT;
//Calculate the sides of rect B
leftB = b.x;
rightB = b.x + b.w;
topB = b.y;
bottomB = b.y + b.h;
//If any of the sides from A are outside of B
if( bottomA <= topB)//-50 )
{
return false;
}
if( topA >= bottomB)//-50 )
{
return false;
}
if( rightA <= leftB)//+50 )
{
return false;
}
if( leftA >= rightB)//-50 )
{
return false;
}
//If none of the sides from A are outside B
return true;
}
I think my problem lies in the checkCollisions()
function, because the the ouput "Collision Detected" is never shown on the console. I have tried many variations of looping and storing them from the map to the vector but I still can't figure out why the collision detection stopped working.
The solution I've realised now is actually very simple. I had to multiply each element of x and y with the tile size.
collisionExists( x[k]*TILE_SIZE,y[l]*TILE_SIZE,sprite)
I was passing x and y co-ordinates instead to my function and that was a fundamental error on my part.