September 21, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Cross-Platform Game Development for C++ Developers, Part II: The Allegro Platform

  • August 17, 2005
  • By Victor Volkman
  • Send Email »
  • More Articles »

A Complete Allegro Example (cont'd)

The following is the code for the demo:


  1 #include <allegro.h>
  2 vector<Point> g_points;    // List of points aka balls. aka
                               // ball centers?
  3 vector<Joint> g_joints;    // List of physical objects,
                               // e.g. wheel and bumpers.
  4 kVec   g_accControl;
  5
  6 int main(void)
  7 {
  8    allegro_init();         // Initialize allegro.
  9    install_keyboard();     // Enable keyboard.
 10    install_mouse();        // Enable mouse.
 11    install_timer();        // Needed for show_mouse();
 12
 13    // Create a 800x600 non-fullscreen window.
 14    set_gfx_mode(GFX_AUTODETECT_WINDOWED, 800, 600, 0, 0);
 15
 16    set_window_title("Kee-Yip Chan's Snooker Clone");
 17    text_mode(-1);    // Text will be drawn on transparent
                         // background.
 18
 19    BITMAP* buffer = create_bitmap(SCREEN_W, SCREEN_H);
       // Create a bitmap for double buffering.
 20
 21     // Initialize data.
 22    create_joints(g_joints);    // register hardcoded screen
                                   // positions for wheel,
 23                                // floor, and bumpers
 24
 25    // Create points aka balls: player ball and three blue
 26    // balls position, velocity, size, and mass.
 27    g_points.push_back(Point(kVec(100, 300),kVec(0, 0),16, 10));
      // Player.
 28    g_points.push_back(Point(kVec(50, 40), kVec(0, 0),12, 5));
       // medium ball.
 29    g_points.push_back(Point(kVec(80, 40), kVec(0, 0) 12, 5));
       // medium ball.
 30    g_points.push_back(Point(kVec(110, 40),kVec(0, 0),6, 1));
       // small ball.
 31
 32    // Main loop, exit when ESC is pressed.
 33    while(!key[KEY_ESC]) {            // Check input.
 34       if(key[KEY_UP])
 35           g_accControl.y = -0.07;    // Jet pack. Accelerate
                                         // upwards
 36       if(key[KEY_LEFT])
 37           g_accControl.x = -0.07;    // Walk left. Accelerate
                                         // to the left.
 38       if(key[KEY_RIGHT])
 39           g_accControl.x = 0.07;     // Walk right. Accelerate
                                         // to the right.
 40
 41       static bool leftMousePressed = false,
                      rightMousePressed = false;
 42       if(mouse_b & 1) { // Left mouse button pressed.
 43           if(!leftMousePressed){
 44              leftMousePressed = true;    // Create a new ball.
 45              g_points.push_back(Point(kVec(mouse_x, mouse_y),
                                    kVec(0, 0), 12, 5));
 46              }
 47           }
 48       if(!(mouse_b & 1))
 49         // Ensures that it doesn't repeat the mouse press;
 50         // otherwise, streams of new balls would gush out.
 51           leftMousePressed = false;
 52       if(mouse_b & 2) {    // Right mouse button pressed.
 53             if(!rightMousePressed){
 54                 rightMousePressed = true;    // Create a new
                                                 // ball.
 55                 g_points.push_back(Point(kVec(mouse_x, mouse_y),
                                             kVec(0, 0), 6, 1));
 56             }
 57         }
 58       if(!(mouse_b & 2))
 59         // Ensures that it doesn't repeat the mouse press;
 60         // otherwise, streams of new balls would gush out.
 61         rightMousePressed = false;
 62
 63       doPhysics();
 64
 65       // Rendering: Erase the buffer so we can use it again;
          // otherwise, old images will linger.
 66       // White color for clarity.
 67       clear_to_color(buffer, makecol(255, 255, 255));
 68       for(unsigned i = 0; i < g_points.size(); i++) {
            // Draw points.
 69         // Draw a solid ball.
 70         circlefill(buffer,    // Draw to buffer.
 71                  g_points[i].position.x,
                     g_points[i].position.y,
                     // Point's position aka ball's center.
 72                  g_points[i].size,    // Radius.
 73                  (i == 0) ? makecol(255, 0, 0) :
                                makecol(0, 0, 255));
                     // Red if player; otherwise, blue.
 74
 75         // Draw an outlined ball.
 76         circle(buffer,    // Draw to buffer.
 77                   g_points[i].position.x,
                      g_points[i].position.y,
            // Point's position aka ball's center.
 78                   g_points[i].size,     // Radius.
 79                   makecol(0, 0, 0));    // Red if player;
 80                                         // otherwise, blue.
 81         }
 82
 83         // Draw joints.
 84         for (unsigned i = 0; i < g_joints.size(); i++)
 85            line(buffer,  // Draw to buffer.
 86                   g_joints[i].p1.x, g_joints[i].p1.y,
                      // Point 1.
 87                   g_joints[i].p2.x, g_joints[i].p2.y,
                      // Point 2.
 88                   makecol(0, 0, 0));    // Black color.
 89               );
 90
 91         // Print instructions.
 92         textout(buffer, font, "Left Mouse Button - new big ball
                                   Right Mouse Button - new small ball",
 93               125, 1, makecol(0, 0, 0));
 94
 95         textout(buffer, font, "Arrow Keys - move red ball",
 96               300, 592, makecol(0, 0, 0));
 97
 98         show_mouse(buffer); // Draw the mouse cursor.
 99
100         draw_sprite(screen, buffer, 0, 0);
            // Draw the buffer onto the screen.
101       }    // end while
102
103     return 0;
104
105 }END_OF_MAIN();

Lines 33-101 comprise the classic game loop model of programming. Play continues until the player hits the ESC key to exit. Simultaneous keyboard input is supported in lines 34-39, because you can hold down both up and left keys to get roughly diagonal motion.

In lines 41-61, the mouse action is captured in global variables mouse_b (for buttons), mouse_x, and mouse_y. If you had been using a scroll mouse, you would have mouse_z available too. A bit of hand-coded de-bouncing logic also ensures that only one ball drops per mouse-down event.

Line 63 calls doPhysics(), whose purpose is to spin the wheel's line segments, update ball positions, detect ball collisions, and alter their direction vectors appropriately. This is a somewhat intense module (350 lines of math code), but it is an elegant implementation that you should study on your own.

The remaining code, lines 65-101, does the rendering and would certainly belong in its own function body in a non-trivial demo. This renders in the classic double-buffer paradigm, whereby the next incremental screen change is calculated and drawn off-screen then swapped in at the last millisecond (line 100). This both insures visual continuity and reduces annoying flicker where objects would appear to be drawn randomly. Within the rendering code, the line() and circlefill() calls are relatively straightforward: circlefill() takes x, y, radius, and fill color as parameters.

The textout_ex() function can do a bit more than textout() (shown in lines 92-96), allowing you to specify foreground and background colors. Allegro provides routines for loading fonts directly from GRX format .fnt files, 8x8 or 8x16 BIOS format .fnt files, bitmap images, and datafiles. Alternatively, you can import a multiple-range Unicode font by writing a .txt script that specifies a number of different source files for each range of characters. If you want TrueType support, you need the AllegroTTF or equivalent add-in.

Last, but certainly not least, draw_sprite() on line 100 does a masked copy of the newly rendered bitmap to the screen object you created way back on Line 14. A masked copy means that only the non-transparent colored pixels are copied. In this example, I'm fairly sure it devolves to a "blit" (block copy) transfer.





Page 2 of 3



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel