// You must include the Allegro Header file
#include <allegro.h>
#include <string>
const int SCREEN_WIDTH=1280;
const int SCREEN_HEIGHT=768;
const int COLOR_DEPTH=32;
typedef BITMAP *BITMAP_PTR;
/*TIMER STUFF*/
volatile long speed_counter = 0;
void increment_speed_counter() //A function to increment the speed counter
{
speed_counter++; // This will just increment the speed counter by one. :)
}
END_OF_FUNCTION(increment_speed_counter); //Make sure you tell it that it's the end of the
//function
//functions
int FAILED(int test)
{
return test;
}
void error(const std::string& message)
{
set_gfx_mode(GFX_TEXT,0,0,0,0); //Set the screen mode for allegro messages
allegro_message(message.c_str());
exit(EXIT_FAILURE);
}
class Game
{
private:
BITMAP *background;
BITMAP *buffer;
BITMAP *frame1;
BITMAP *frame2;
BITMAP *frame3;
BITMAP *ball;
//variables
int guy_x;
int guy_y;
int ball_x;
int ball_y;
int frame_counter;
//flags
int show_bbox;
int collision;
//boundingboxes
int ball_bb_left;
int ball_bb_top;
int ball_bb_right;
int ball_bb_bottom;
int guy_bb_left;
int guy_bb_top;
int guy_bb_right;
int guy_bb_bottom;
//member functions
void check_frame();
void choose_blit();
void loadc_bitmap(BITMAP_PTR& bmp,const std::string& filename);
void draw_boxes();
void col_detect();
public:
Game();
~Game();
void play();
};
//Game class functions
void Game::play()
{
//logic
while(speed_counter>0)
{
//key checks for guy
if(key[KEY_RIGHT]) // If the user hits the right key, change the picture's X coordinate
{
guy_x+=3; // Moving right so up the X coordinate by 3
}
if(key[KEY_LEFT]) // Ditto' - only for left key
{
guy_x-=3; // Moving left, so lower the X coordinate by 3
}
if(key[KEY_UP]) // If the user hits the up key, change the picture's Y coordinate
{
guy_y -=3; // Moving up, so lower the Y coordinate by 3
}
if(key[KEY_DOWN]) // Ditto' - only for down
{
guy_y +=3; // Moving down, so up the Y coordinate by 3
}
//key checks for ball
if(key[KEY_D]) // If the user hits the right key, change the picture's X coordinate
{
ball_x+=3; // Moving right so up the X coordinate by 3
}
if(key[KEY_A]) // Ditto' - only for left key
{
ball_x-=3; // Moving left, so lower the X coordinate by 3
}
if(key[KEY_W]) // If the user hits the up key, change the picture's Y coordinate
{
ball_y -=3; // Moving up, so lower the Y coordinate by 3
}
if(key[KEY_S]) // Ditto' - only for down
{
ball_y +=3; // Moving down, so up the Y coordinate by 3
}
//bbox stuff
if(key[KEY_SPACE])
{
show_bbox = TRUE;
}
else if(!key[KEY_SPACE])
{
show_bbox = FALSE;
}
//update the bboxes
ball_bb_left = ball_x;
ball_bb_top = ball_y;
ball_bb_right = (ball_x + (ball->w));
ball_bb_bottom = (ball_y + (ball->h));
guy_bb_left = guy_x;
guy_bb_top = guy_y;
guy_bb_right = (guy_x + (frame1->w));
guy_bb_bottom = (guy_y + (frame1->h));
//check for collisions
col_detect();
//counter
speed_counter--;
frame_counter++;
check_frame();
}
choose_blit(); // Draw the right frame to the buffer
if(show_bbox == TRUE)
{
draw_boxes();
}
if(collision == TRUE)
{
textprintf_ex(buffer, font, 10,10, makecol(255,0,255), -1, "Collision!");
}
blit(buffer, screen, 0,0,0,0,SCREEN_WIDTH,SCREEN_HEIGHT); // Draw the buffer to the screen
clear_bitmap(buffer);
// Blits to primary buffer. screen=primary buffer?
}
void Game::loadc_bitmap(BITMAP_PTR& bmp,const std::string& filename)
{
bmp=load_bitmap(filename.c_str(), NULL);//Load image 1
if(bmp == NULL)
{
set_gfx_mode(GFX_TEXT,0,0,0,0); //Set the screen mode for allegro messages
allegro_message("Failed to load bitmap %s",filename.c_str());
exit(EXIT_FAILURE);
}
}
void Game::choose_blit()
{
blit(background,buffer, 0,0,0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
if(frame_counter < 30) // Less than a full second
{
draw_sprite(buffer, frame1, guy_x, guy_y); // Draw the first frame
}
else if(frame_counter >= 30 && frame_counter < 60) // Between 1 and 2 seconds
{
draw_sprite(buffer, frame2, guy_x, guy_y); // Draw the second frame
}
else if(frame_counter >= 60 && frame_counter < 90) // If we are between 2 and 3 seconds
{
draw_sprite(buffer, frame1, guy_x, guy_y); // Draw the first frame again,
// to acheive better effect
}
else // If we are over 3 seconds
{
draw_sprite(buffer, frame3, guy_x, guy_y); // Draw the last frame.
}
draw_sprite(buffer, ball, ball_x, ball_y);
}
void Game::check_frame()
{
if(frame_counter>120)
{
frame_counter=0;
}
}
void Game::draw_boxes()
{
line(buffer, guy_bb_left, guy_bb_top, guy_bb_right, guy_bb_top, makecol(255,0,0));
line(buffer, guy_bb_left, guy_bb_bottom, guy_bb_right, guy_bb_bottom, makecol(255,0,0));
line(buffer, guy_bb_left, guy_bb_top, guy_bb_left, guy_bb_bottom, makecol(255,0,0));
line(buffer, guy_bb_right, guy_bb_top, guy_bb_right, guy_bb_bottom, makecol(255,0,0));
line(buffer, ball_bb_left, ball_bb_top, ball_bb_right, ball_bb_top, makecol(255,0,0));
line(buffer, ball_bb_left, ball_bb_bottom, ball_bb_right, ball_bb_bottom, makecol(255,0,0));
line(buffer, ball_bb_left, ball_bb_top, ball_bb_left, ball_bb_bottom, makecol(255,0,0));
line(buffer, ball_bb_right, ball_bb_top, ball_bb_right, ball_bb_bottom, makecol(255,0,0));
}
void Game::col_detect()
{
collision = TRUE; // Assume that there is no collision
// NOTE: This could easily be concatenated into one big if statement across
// four 'or' clauses -- but it's split up this way for easy reading
if(guy_bb_bottom < ball_bb_top)
{
collision = FALSE;
}
else if(guy_bb_top > ball_bb_bottom)
{
collision = FALSE;
}
else if(guy_bb_right < ball_bb_left)
{
collision = FALSE;
}
else if(guy_bb_left > ball_bb_right)
{
collision = FALSE;
}
}
//Game class constructor and destructor
Game::Game()
{
//Loading a pic into the empty BITMAP structure
loadc_bitmap(background,"background.bmp");
loadc_bitmap(frame1,"frame1.bmp");
loadc_bitmap(frame2,"frame2.bmp");
loadc_bitmap(frame3,"frame3.bmp");
loadc_bitmap(ball,"ball.bmp");
//just creating an empty bitmap for main buffer
buffer = create_bitmap(SCREEN_WIDTH,SCREEN_HEIGHT);
if(buffer == NULL)
{
set_gfx_mode(GFX_TEXT,0,0,0,0);
allegro_message("Could not create buffer!");
exit(EXIT_FAILURE);
}
//initialize variables
show_bbox = FALSE;
collision = FALSE;
frame_counter = 0;
guy_x = SCREEN_WIDTH/2;
guy_y = SCREEN_HEIGHT/2;
ball_x = 100;
ball_y = 200;
//initialize bboxes
ball_bb_left = ball_x;
ball_bb_top = ball_y;
ball_bb_right = (ball_x + ball->w);
ball_bb_bottom = (ball_y + ball->h);
guy_bb_left = guy_x;
guy_bb_top = guy_y;
guy_bb_right = (guy_x + frame1->w);
guy_bb_bottom = (guy_y + frame1->h);
}
Game::~Game()
{
destroy_bitmap(background);//free mem
destroy_bitmap(buffer);
destroy_bitmap(frame1);//Release the bitmap data
destroy_bitmap(frame2);//Release the bitmap data
destroy_bitmap(frame3);//Release the bitmap data
destroy_bitmap(ball);
}
//Main
int main(int argc, char *argv[])
{
if(FAILED(allegro_init()))
{
error("\nFailed allegro INIT");
}
if(FAILED(install_keyboard()))
{
error("\nFailed to install keyboard");
}
LOCK_VARIABLE(speed_counter); //Used to set the timer - which regulates the game's
LOCK_FUNCTION(increment_speed_counter);//speed
install_int_ex(increment_speed_counter, BPS_TO_TIMER(60));
set_color_depth(COLOR_DEPTH);
if(FAILED(install_timer()))
{
error("\nFailed to install timer");
}
if(FAILED(set_gfx_mode(GFX_AUTODETECT_WINDOWED, SCREEN_WIDTH, SCREEN_HEIGHT, 0 ,0)))
{
error("\nFailed to set gfx mode");
}
//Main game loop goes here with init and destruct
Game game;
while(!key[KEY_ESC])
{
game.play();
}
return 0;
}
END_OF_MAIN()//Allegro specific weirdness