1. // You must include the Allegro Header file
  2. #include <allegro.h>
  3. #include <string>
  4.  
  5.  
  6.  
  7.  
  8.  
  9. const int SCREEN_WIDTH=1280;
  10. const int SCREEN_HEIGHT=768;
  11. const int COLOR_DEPTH=32;
  12. typedef BITMAP *BITMAP_PTR;
  13.  
  14.  
  15. /*TIMER STUFF*/
  16. volatile long speed_counter = 0;
  17. void increment_speed_counter() //A function to increment the speed counter
  18. {
  19. speed_counter++; // This will just increment the speed counter by one. :)
  20. }
  21. END_OF_FUNCTION(increment_speed_counter); //Make sure you tell it that it's the end of the
  22. //function
  23.  
  24.  
  25. //functions
  26. int FAILED(int test)
  27. {
  28. return test;
  29. }
  30.  
  31. void error(const std::string& message)
  32. {
  33. set_gfx_mode(GFX_TEXT,0,0,0,0); //Set the screen mode for allegro messages
  34. allegro_message(message.c_str());
  35. exit(EXIT_FAILURE);
  36. }
  37.  
  38. class Game
  39. {
  40. private:
  41. BITMAP *background;
  42. BITMAP *buffer;
  43. BITMAP *frame1;
  44. BITMAP *frame2;
  45. BITMAP *frame3;
  46. BITMAP *ball;
  47.  
  48.  
  49. //variables
  50. int guy_x;
  51. int guy_y;
  52. int ball_x;
  53. int ball_y;
  54. int frame_counter;
  55.  
  56. //flags
  57.  
  58. int show_bbox;
  59. int collision;
  60.  
  61.  
  62. //boundingboxes
  63. int ball_bb_left;
  64. int ball_bb_top;
  65. int ball_bb_right;
  66. int ball_bb_bottom;
  67.  
  68. int guy_bb_left;
  69. int guy_bb_top;
  70. int guy_bb_right;
  71. int guy_bb_bottom;
  72.  
  73. //member functions
  74. void check_frame();
  75. void choose_blit();
  76. void loadc_bitmap(BITMAP_PTR& bmp,const std::string& filename);
  77. void draw_boxes();
  78. void col_detect();
  79. public:
  80.  
  81. Game();
  82. ~Game();
  83.  
  84. void play();
  85. };
  86.  
  87. //Game class functions
  88. void Game::play()
  89. {
  90. //logic
  91. while(speed_counter>0)
  92. {
  93. //key checks for guy
  94. if(key[KEY_RIGHT]) // If the user hits the right key, change the picture's X coordinate
  95. {
  96. guy_x+=3; // Moving right so up the X coordinate by 3
  97. }
  98. if(key[KEY_LEFT]) // Ditto' - only for left key
  99. {
  100. guy_x-=3; // Moving left, so lower the X coordinate by 3
  101. }
  102. if(key[KEY_UP]) // If the user hits the up key, change the picture's Y coordinate
  103. {
  104. guy_y -=3; // Moving up, so lower the Y coordinate by 3
  105. }
  106. if(key[KEY_DOWN]) // Ditto' - only for down
  107. {
  108. guy_y +=3; // Moving down, so up the Y coordinate by 3
  109. }
  110.  
  111. //key checks for ball
  112. if(key[KEY_D]) // If the user hits the right key, change the picture's X coordinate
  113. {
  114. ball_x+=3; // Moving right so up the X coordinate by 3
  115. }
  116. if(key[KEY_A]) // Ditto' - only for left key
  117. {
  118. ball_x-=3; // Moving left, so lower the X coordinate by 3
  119. }
  120. if(key[KEY_W]) // If the user hits the up key, change the picture's Y coordinate
  121. {
  122. ball_y -=3; // Moving up, so lower the Y coordinate by 3
  123. }
  124. if(key[KEY_S]) // Ditto' - only for down
  125. {
  126. ball_y +=3; // Moving down, so up the Y coordinate by 3
  127. }
  128. //bbox stuff
  129. if(key[KEY_SPACE])
  130. {
  131. show_bbox = TRUE;
  132. }
  133.  
  134. else if(!key[KEY_SPACE])
  135. {
  136. show_bbox = FALSE;
  137. }
  138. //update the bboxes
  139. ball_bb_left = ball_x;
  140. ball_bb_top = ball_y;
  141. ball_bb_right = (ball_x + (ball->w));
  142. ball_bb_bottom = (ball_y + (ball->h));
  143.  
  144. guy_bb_left = guy_x;
  145. guy_bb_top = guy_y;
  146. guy_bb_right = (guy_x + (frame1->w));
  147. guy_bb_bottom = (guy_y + (frame1->h));
  148. //check for collisions
  149. col_detect();
  150. //counter
  151. speed_counter--;
  152. frame_counter++;
  153. check_frame();
  154. }
  155.  
  156. choose_blit(); // Draw the right frame to the buffer
  157.  
  158. if(show_bbox == TRUE)
  159. {
  160. draw_boxes();
  161. }
  162.  
  163. if(collision == TRUE)
  164. {
  165. textprintf_ex(buffer, font, 10,10, makecol(255,0,255), -1, "Collision!");
  166. }
  167.  
  168. blit(buffer, screen, 0,0,0,0,SCREEN_WIDTH,SCREEN_HEIGHT); // Draw the buffer to the screen
  169. clear_bitmap(buffer);
  170. // Blits to primary buffer. screen=primary buffer?
  171. }
  172.  
  173. void Game::loadc_bitmap(BITMAP_PTR& bmp,const std::string& filename)
  174. {
  175. bmp=load_bitmap(filename.c_str(), NULL);//Load image 1
  176.  
  177. if(bmp == NULL)
  178. {
  179. set_gfx_mode(GFX_TEXT,0,0,0,0); //Set the screen mode for allegro messages
  180. allegro_message("Failed to load bitmap %s",filename.c_str());
  181. exit(EXIT_FAILURE);
  182. }
  183.  
  184. }
  185.  
  186. void Game::choose_blit()
  187. {
  188. blit(background,buffer, 0,0,0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
  189.  
  190. if(frame_counter < 30) // Less than a full second
  191. {
  192. draw_sprite(buffer, frame1, guy_x, guy_y); // Draw the first frame
  193. }
  194. else if(frame_counter >= 30 && frame_counter < 60) // Between 1 and 2 seconds
  195. {
  196. draw_sprite(buffer, frame2, guy_x, guy_y); // Draw the second frame
  197. }
  198. else if(frame_counter >= 60 && frame_counter < 90) // If we are between 2 and 3 seconds
  199. {
  200. draw_sprite(buffer, frame1, guy_x, guy_y); // Draw the first frame again,
  201. // to acheive better effect
  202. }
  203. else // If we are over 3 seconds
  204. {
  205. draw_sprite(buffer, frame3, guy_x, guy_y); // Draw the last frame.
  206. }
  207. draw_sprite(buffer, ball, ball_x, ball_y);
  208. }
  209.  
  210. void Game::check_frame()
  211. {
  212. if(frame_counter>120)
  213. {
  214. frame_counter=0;
  215. }
  216. }
  217.  
  218. void Game::draw_boxes()
  219. {
  220. line(buffer, guy_bb_left, guy_bb_top, guy_bb_right, guy_bb_top, makecol(255,0,0));
  221. line(buffer, guy_bb_left, guy_bb_bottom, guy_bb_right, guy_bb_bottom, makecol(255,0,0));
  222. line(buffer, guy_bb_left, guy_bb_top, guy_bb_left, guy_bb_bottom, makecol(255,0,0));
  223. line(buffer, guy_bb_right, guy_bb_top, guy_bb_right, guy_bb_bottom, makecol(255,0,0));
  224.  
  225. line(buffer, ball_bb_left, ball_bb_top, ball_bb_right, ball_bb_top, makecol(255,0,0));
  226. line(buffer, ball_bb_left, ball_bb_bottom, ball_bb_right, ball_bb_bottom, makecol(255,0,0));
  227. line(buffer, ball_bb_left, ball_bb_top, ball_bb_left, ball_bb_bottom, makecol(255,0,0));
  228. line(buffer, ball_bb_right, ball_bb_top, ball_bb_right, ball_bb_bottom, makecol(255,0,0));
  229. }
  230.  
  231. void Game::col_detect()
  232. {
  233. collision = TRUE; // Assume that there is no collision
  234. // NOTE: This could easily be concatenated into one big if statement across
  235. // four 'or' clauses -- but it's split up this way for easy reading
  236. if(guy_bb_bottom < ball_bb_top)
  237. {
  238. collision = FALSE;
  239. }
  240. else if(guy_bb_top > ball_bb_bottom)
  241. {
  242. collision = FALSE;
  243. }
  244. else if(guy_bb_right < ball_bb_left)
  245. {
  246. collision = FALSE;
  247. }
  248. else if(guy_bb_left > ball_bb_right)
  249. {
  250. collision = FALSE;
  251. }
  252.  
  253. }
  254.  
  255. //Game class constructor and destructor
  256. Game::Game()
  257. {
  258.  
  259. //Loading a pic into the empty BITMAP structure
  260. loadc_bitmap(background,"background.bmp");
  261. loadc_bitmap(frame1,"frame1.bmp");
  262. loadc_bitmap(frame2,"frame2.bmp");
  263. loadc_bitmap(frame3,"frame3.bmp");
  264. loadc_bitmap(ball,"ball.bmp");
  265. //just creating an empty bitmap for main buffer
  266. buffer = create_bitmap(SCREEN_WIDTH,SCREEN_HEIGHT);
  267. if(buffer == NULL)
  268. {
  269. set_gfx_mode(GFX_TEXT,0,0,0,0);
  270. allegro_message("Could not create buffer!");
  271. exit(EXIT_FAILURE);
  272. }
  273.  
  274. //initialize variables
  275. show_bbox = FALSE;
  276. collision = FALSE;
  277. frame_counter = 0;
  278.  
  279. guy_x = SCREEN_WIDTH/2;
  280. guy_y = SCREEN_HEIGHT/2;
  281. ball_x = 100;
  282. ball_y = 200;
  283.  
  284. //initialize bboxes
  285. ball_bb_left = ball_x;
  286. ball_bb_top = ball_y;
  287. ball_bb_right = (ball_x + ball->w);
  288. ball_bb_bottom = (ball_y + ball->h);
  289.  
  290. guy_bb_left = guy_x;
  291. guy_bb_top = guy_y;
  292. guy_bb_right = (guy_x + frame1->w);
  293. guy_bb_bottom = (guy_y + frame1->h);
  294.  
  295. }
  296.  
  297. Game::~Game()
  298. {
  299. destroy_bitmap(background);//free mem
  300. destroy_bitmap(buffer);
  301. destroy_bitmap(frame1);//Release the bitmap data
  302. destroy_bitmap(frame2);//Release the bitmap data
  303. destroy_bitmap(frame3);//Release the bitmap data
  304. destroy_bitmap(ball);
  305. }
  306.  
  307. //Main
  308. int main(int argc, char *argv[])
  309. {
  310. if(FAILED(allegro_init()))
  311. {
  312. error("\nFailed allegro INIT");
  313. }
  314. if(FAILED(install_keyboard()))
  315. {
  316. error("\nFailed to install keyboard");
  317. }
  318.  
  319.  
  320. LOCK_VARIABLE(speed_counter); //Used to set the timer - which regulates the game's
  321. LOCK_FUNCTION(increment_speed_counter);//speed
  322. install_int_ex(increment_speed_counter, BPS_TO_TIMER(60));
  323.  
  324.  
  325. set_color_depth(COLOR_DEPTH);
  326.  
  327. if(FAILED(install_timer()))
  328. {
  329. error("\nFailed to install timer");
  330. }
  331. if(FAILED(set_gfx_mode(GFX_AUTODETECT_WINDOWED, SCREEN_WIDTH, SCREEN_HEIGHT, 0 ,0)))
  332. {
  333. error("\nFailed to set gfx mode");
  334. }
  335.  
  336. //Main game loop goes here with init and destruct
  337. Game game;
  338. while(!key[KEY_ESC])
  339. {
  340. game.play();
  341. }
  342. return 0;
  343. }
  344. END_OF_MAIN()//Allegro specific weirdness