#include #include "allegro.h" #define BLACK makecol(0,0,0) #define WHITE makecol(255,255,255) #define NUM 10 #define WIDTH 640 #define HEIGHT 480 #define MODE GFX_AUTODETECT_WINDOWED //define the sprite structure typedef struct SPRITE { int x,y; int width,height; int xspeed,yspeed; int xdelay,ydelay; int xcount,ycount; int curframe,maxframe,animdir; int framecount,framedelay; }SPRITE; //variables BITMAP *ballimg[32]; SPRITE theballs[NUM]; SPRITE *balls[NUM]; void erasesprite(BITMAP *dest, SPRITE *spr) { //erase the sprite rectfill(dest, spr->x, spr->y, spr->x + spr->width, spr->y + spr->height, BLACK); } void updatesprite(SPRITE *spr) { //update x position if (++spr->xcount > spr->xdelay) { spr->xcount = 0; spr->x += spr->xspeed; } //update y position if (++spr->ycount > spr->ydelay) { spr->ycount = 0; spr->y += spr->yspeed; } //update frame based on animdir if (++spr->framecount > spr->framedelay) { spr->framecount = 0; if (spr->animdir == -1) { if (--spr->curframe < 0) spr->curframe = spr->maxframe; } else if (spr->animdir == 1) { if (++spr->curframe > spr->maxframe) spr->curframe = 0; } } } void bouncesprite(SPRITE *spr) { //simple screen bouncing behavior if (spr->x < 0) { spr->x = 0; spr->xspeed = rand() % 2 + 4; spr->animdir *= -1; } else if (spr->x > SCREEN_W - spr->width) { spr->x = SCREEN_W - spr->width; spr->xspeed = rand() % 2 - 6; spr->animdir *= -1; } if (spr->y < 20) { spr->y = 20; spr->yspeed = rand() % 2 + 4; spr->animdir *= -1; } else if (spr->y > SCREEN_H - spr->height) { spr->y = SCREEN_H - spr->height; spr->yspeed = rand() % 2 - 6; spr->animdir *= -1; } } BITMAP *grabframe(BITMAP *source, int width, int height, int startx, int starty, int columns, int frame) { BITMAP *temp = create_bitmap(width,height); int x = startx + (frame % columns) * width; int y = starty + (frame / columns) * height; blit(source,temp,x,y,0,0,width,height); return temp; } int inside(int x,int y,int left,int top,int right,int bottom) { if (x > left && x < right && y > top && y < bottom) return 1; else return 0; } int collided(SPRITE *a, SPRITE *b) { int wa = a->x + a->width; int ha =a->y + a->height; int wb = b->x + b->width; int hb = b->y + b->height; int bx = 5; // The bounding box used is 5 pixels smaller along each edge int by = 5; // than an true bounding box. return (inside(a->x, a->y, b->x+bx, b->y+by, wb-bx, hb-by) || inside(a->x, ha, b->x+bx, b->y+by, wb-bx, hb-by) || inside(wa, a->y, b->x+bx, b->y+by, wb-bx, hb-by) || inside(wa, ha, b->x+bx, b->y+by, wb-bx, hb-by)); } void checkcollisions(int num) { int n,cx1,cy1,cx2,cy2; for (n=0; nx + balls[n]->width / 2; cy1 = balls[n]->y + balls[n]->height / 2; //calculate center of secondary sprite cx2 = balls[num]->x + balls[num]->width / 2; cy2 = balls[num]->y + balls[num]->height / 2; //figure out which way the sprites collided if (cx1 <= cx2) { balls[n]->xspeed = -1 * rand() % 6 + 1; balls[num]->xspeed = rand() % 6 + 1; if (cy1 <= cy2) { balls[n]->yspeed = -1 * rand() % 6 + 1; balls[num]->yspeed = rand() % 6 + 1; } else { balls[n]->yspeed = rand() % 6 + 1; balls[num]->yspeed = -1 * rand() % 6 + 1; } } else { //cx1 is > cx2 balls[n]->xspeed = rand() % 6 + 1; balls[num]->xspeed = -1 * rand() % 6 + 1; if (cy1 <= cy2) { balls[n]->yspeed = rand() % 6 + 1; balls[num]->yspeed = -1 * rand() % 6 + 1; } else { balls[n]->yspeed = -1 * rand() % 6 + 1; balls[num]->yspeed = rand() % 6 + 1; } } } } } void main(void) { BITMAP *temp; BITMAP *buffer; int n; //initialize allegro_init(); set_color_depth(16); set_gfx_mode(MODE, WIDTH, HEIGHT, 0, 0); install_keyboard(); install_timer(); srand(time(NULL)); //create second buffer buffer = create_bitmap(SCREEN_W, SCREEN_H); text_mode(-1); textout(buffer, font, "CollisionTest Program (ESC to quit)", 0, 0, WHITE); //load sprite images temp = load_bitmap("sphere.bmp", NULL); for (n=0; n<32; n++) ballimg[n] = grabframe(temp,64,64,0,0,8,n); destroy_bitmap(temp); //initialize the sprite for (n=0; nx = rand() % (SCREEN_W - ballimg[0]->w); balls[n]->y = rand() % (SCREEN_H - ballimg[0]->h); balls[n]->width = ballimg[0]->w; balls[n]->height = ballimg[0]->h; balls[n]->xdelay = 0; balls[n]->ydelay = 0; balls[n]->xcount = 0; balls[n]->ycount = 0; balls[n]->xspeed = rand() % 5 + 1; balls[n]->yspeed = rand() % 5 + 1; balls[n]->curframe = rand() % 32; balls[n]->maxframe = 31; balls[n]->framecount = 0; balls[n]->framedelay = 0; balls[n]->animdir = 1; } //game loop while (!key[KEY_ESC]) { //erase the sprites for (n=0; ncurframe], balls[n]->x, balls[n]->y); //update the screen acquire_screen(); blit(buffer,screen,0,0,0,0,buffer->w,buffer->h); release_screen(); rest(10); } for (n=0; n<32; n++) destroy_bitmap(ballimg[n]); return; } END_OF_MAIN();