The final hurdle in my little snake game: collision detection. I read a tutorial on Allegro collision detection, and used their method. I have the snake, and I have the little fruit that you have to get to score. For both of the images, I have a bounding box with 4 variables, one for each side. But for some reason, it always thinks that the snake has collided with the fruit, even if it hasn't. I don't know if anyone wants to take the time to check over all the collision detection code, but it would be greatly appreciated. I've looked over it and can't find anything wrong. I basically just copied it from the tutorial, so it should work.
Code:
//Includes
#include <allegro.h>
#include<iostream>
#include<string>
#include <stdlib.h>
#include <stdlib.h>
#include <cstdlib>
#include <time.h>
#include <vector>
#include <complex>
#include <math.h>
#include <cmath>
#include <time.h>
using namespace std;
//Graphics
BITMAP *snakeimg = NULL;
BITMAP *buffer = NULL;
BITMAP *fruit = NULL;
//Sounds
//Variables
float x,y;
float dir = 45;
float dx = sin(dir);
float dy = cos(dir);
#define PI 3.14159265
int maxsize = 3;
int timer = 0;
int fx,fy;
int snakeright,snakeleft;
int snaketop,snakebottom;
int fruitright,fruitleft;
int fruittop,fruitbottom;
bool collision = false;
//Structs
struct snake {
int x;
int y;
};
//Vectors
vector<snake> snakes(0);
//Functions
void UpdateSnake();
void TestKeys();
void TestCollisions();
int main(int argc, char argv[1])
{
srand( (unsigned)time( NULL ) );
fx = (rand() % 400) + 0;
fy = (rand() % 400) + 0;
allegro_init();
install_keyboard();
set_color_depth(24);
set_gfx_mode(GFX_AUTODETECT_WINDOWED,400,400,0,0);
//BITMAPS
snakeimg = load_bitmap("Snake.bmp",NULL);
buffer = create_bitmap(400,400);
fruit = load_bitmap("Fruit.bmp",NULL);
while(!key[KEY_ESC])
{
clear_bitmap(buffer);
TestKeys();
UpdateSnake();
TestCollisions();
draw_sprite(buffer,fruit,fx,fy);
draw_sprite(screen,buffer,0,0);
}
allegro_exit();
return 0;
//Cleanup
for(int i = 0;i < snakes.size(); i++);
{
snakes.erase(snakes.begin()+i);
}
destroy_bitmap(snakeimg);
destroy_bitmap(buffer);
destroy_bitmap(fruit);
}
END_OF_MAIN();
void UpdateSnake()
{
snakeleft = x;
snaketop = y;
snakeright = snakeleft + snakeimg->w;
snakebottom = snaketop + snakeimg->h;
fruitleft = fx;
fruittop = fy;
fruitright = fruitleft + fruit->w;
fruitbottom = fruittop + fruit->h;
dx = sin(dir*PI/180);
dy = cos(dir*PI/180);
x = x + dx/5;
y = y + dy/5;
timer++;
if(timer >50)
{
snake w;
w.x = x;
w.y = y;
snakes.push_back(w);
timer = 0;
}
if(snakes.size() > maxsize)
{
snakes.erase(snakes.begin()+0);
}
for(int i = 0; i < snakes.size(); i++)
{
draw_sprite(buffer,snakeimg,snakes[i].x,snakes[i].y);
}
}
END_OF_FUNCTION(UpdateSnake);
void TestKeys()
{
if(key[KEY_LEFT])
{
dir = dir + .4;
}
else if(key[KEY_RIGHT])
{
dir = dir - .4;
}
}
END_OF_FUNCTION(TestKeys);
void TestCollisions()
{
collision = false;
// Test the top left corncer of the first box to the second
// (Is the corner in or on the second box?)
if(
(snakeleft >= fruitleft) && (snaketop >= fruittop) &&
(snakeleft <= fruitright) && (snaketop <= fruitbottom)
)
{
collision = true;
}
// Test the top right corner of the first box to the second
// (Is the corner in or on the second box?)
else if(
(snakeright <= fruitright) && (snakeright >= fruitleft) &&
(snaketop >= fruittop) && (snaketop <= fruitbottom)
)
{
collision = true;
}
// Test the bottom left corner of the first box to the second
// (Is the corner in or on the second box?)
else if(
(snakeleft >= fruitleft) && (snakeleft <= fruitright) &&
(snakebottom <= fruitbottom) && (snakebottom >= fruittop)
)
{
collision = true;
}
// Test the borrom right corner of the first box to the second
// (Is the corner in or on the second box?)
else if(
(snakeright <= fruitright) && (snakeright >= fruitleft) &&
(snakebottom <= fruitbottom) && (snakebottom >= fruittop)
)
{
collision = true;
}
// Test the top left corner of the second box to the first box
// (Is the corner in or on the first box?)
if(
(fruitleft >= snakeleft) && (fruittop >= snaketop) &&
(fruitleft <= snakeright) && (fruittop <= snakebottom)
)
{
collision = true;
}
// Text the top right corner of the second box to the first box
// (Is the corner in or on the second box?)
else if(
(fruitleft <= snakeright) && (fruitright >= snakeleft) &&
(fruittop >= snaketop) && (fruittop <= snakebottom)
)
{
collision = true;
}
// Test the bottom left corner of the second box to the first box
// (Is the corner in or on the second box?)
else if(
(fruitright <= snakeright) && (fruitright >= snakeleft) &&
(fruitbottom <= snakebottom) && (fruitbottom >= snaketop)
)
{
collision = true;
}
// Test the bottom right corner of the second box to the first box
// (Is the corner in or on the second box?)
else if(
(fruitright <= snakeright) && (fruitright >= snakeleft) &&
(fruitbottom <= snakebottom) && (fruitbottom >= snaketop)
)
{
collision = true;
}
// Check box 1 for a horizontal cross on box 2
// (This covers a vertical cross for box 2 on box 1)
if(
(snaketop > fruittop) && (snakebottom < fruitbottom) &&
(fruitleft > snakeleft) && (fruitright < snakeright)
)
{
collision = true;
}
// Check box 2 for a horizontal cross on box 1
// (This covers veritcal cross for box 1 on box 2)
if(
(fruittop > snaketop) && (fruitbottom < snakebottom) &&
(snakeleft > fruitleft) && (snakeright < fruitright)
)
{
collision = true;
}
if(collision = true)
{
fx = (rand() % 400) + 0;
fy = (rand() % 400) + 0;
}
}
END_OF_FUNCTION(TestCollisions);