#include #include "allegro.h" #define BLACK makecol(0,0,0) #define WHITE makecol(255,255,255) //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; //sprite variables BITMAP *ballimg[32]; SPRITE theball; SPRITE *ball = &theball; //support variables char s[20]; int n; void erasesprite(BITMAP *dest, SPRITE *spr) { //erase the sprite using BLACK color fill 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 < 40) { spr->y = 40; 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; } void main(void) { BITMAP *temp; //initialize allegro_init(); set_color_depth(16); set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); install_keyboard(); install_timer(); srand(time(NULL)); textout(screen, font, "SpriteGrabber Program (ESC to quit)", 0, 0, WHITE); //load 32-frame tiled sprite image 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 with lots of randomness ball->x = rand() % (SCREEN_W - ballimg[0]->w); ball->y = rand() % (SCREEN_H - ballimg[0]->h); ball->width = ballimg[0]->w; ball->height = ballimg[0]->h; ball->xdelay = rand() % 2 + 1; ball->ydelay = rand() % 2 + 1; ball->xcount = 0; ball->ycount = 0; ball->xspeed = rand() % 2 + 4; ball->yspeed = rand() % 2 + 4; ball->curframe = 0; ball->maxframe = 31; ball->framecount = 0; ball->framedelay = 1; ball->animdir = 1; //game loop while (!key[KEY_ESC]) { erasesprite(screen, ball); //perform standard position/frame update updatesprite(ball); //now do something with the sprite--a basic screen bouncer bouncesprite(ball); //lock the screen acquire_screen(); //draw the ball sprite draw_sprite(screen, ballimg[ball->curframe], ball->x, ball->y); //display some logistics textprintf(screen, font, 0, 20, WHITE, "x,y,xspeed,yspeed: %2d,%2d,%2d,%2d", ball->x, ball->y, ball->xspeed, ball->yspeed); textprintf(screen, font, 0, 30, WHITE, "xcount,ycount,framecount,animdir: %2d,%2d,%2d,%2d", ball->xcount, ball->ycount, ball->framecount, ball->animdir); //unlock the screen release_screen(); rest(10); } for (n=0; n<31; n++) destroy_bitmap(ballimg[n]); return; } END_OF_MAIN();