Graphics Programming using Allegro

Movable Text

Published:  August 23, 2008
by Richard G. Baldwin

File:  Allegro00115


Preface

General

This lesson is part of a series (see Resources) designed to teach you how to use Allegro to do graphics programming in C++.  My purpose in writing the series is to provide lecture and lab material for a course titled Game Development Using C++ that I teach at Austin Community College in Austin, Texas.  However, if you have stumbled upon this series and you find it useful, you are welcome to study it.

Viewing tip

I recommend that you open another copy of this document in a separate browser window and use the following links to easily find and view the figures and listings while you are reading about them.

Figures

Listings

Supplemental material

I recommend that you also study the other lessons in my extensive collection of online programming tutorials.  You will find a consolidated index at www.DickBaldwin.com.

Preview

In this lesson, I will show you how to write an Allegro project that:

Figure 1 shows three screen shots of the program output as the text was being moved using the arrow keys.

Figure 1. Three screen shots of MovableHelloWorld01.

Discussion and sample code

As usual, I will explain this program in fragments.  A complete listing of the program is provided in Listing 8 near the end of the lesson.

The fragment in Listing 1 shows the include directive along with the beginning of the main function.

Listing 1. Beginning of the main function.
#include <allegro.h>

int main(){
  int x = 20,y = 30;//position coordinates for text

  allegro_init();//Allegro initialization
  install_keyboard();//Set up for keyboard input

  //Set the graphics mode to a 320x240-pixel window.
  set_gfx_mode(GFX_AUTODETECT_WINDOWED, 320,240,0,0);

The new material

The only thing that is new in Listing 1 is the declaration and initialization of two variables of type int that are used to specify the location of the left end of the text.  This statement is highlighted in boldface in Listing 1.

When the code in Listing 1 finishes executing, the variables have been declared and initialized, Allegro has been initialized, the keyboard interrupt handler has been installed, and the graphics mode has been set to display yellow text with a transparent background on the black surface of the window.

Loop and monitor for key presses

Listing 2 shows the beginning of a while loop that continues to loop for as long as the user doesn't press the Esc key.  When the user presses the Esc key, the loop terminates.

Listing 2. Loop and monitor for key presses.
  while(!key[KEY_ESC]){//loop until user presses Esc key

    clear_keybuf();//clear old stuff from the buffer

During each iteration of the loop, tests are made to determine if the user has pressed any of the four arrow keys.  If so, the x or y position coordinates are incremented or decremented to cause the text to be moved by one pixel in the direction indicated by the arrow key that was pressed.

Pressing and holding down two arrow keys at a time does not result in diagonal motion.  The text is capable of moving up, down, right, or left, but is not capable of moving along a diagonal.

Clear the key buffer

Also, at the beginning of each iteration in Listing 2, the clear_keybuf function is called to clear out any old key data that may be left over in the buffer.

Erase the previous line of text

Recall that the objective of this program is to move the text around the window in accordance with the arrow keys when they are pressed.  We need to erase the text before moving it.  Otherwise, the result will be yellow smeared across the screen.  The code in Listing 3 erases the line of text in preparation for re-drawing it in the same or in a different location.

Listing 3. Erase the previous line of text.
    //Draw black text on the existing text to erase it.
    textout_ex(
             screen,//Specify bitmap on the screen
             font,//Use a default font
             "HELLO WORLD",//Specify the text to display
             x,//x-coordinate for text
             y,//y-coordinate for text
             makecol(0,0,0),//Color text black
             -1 );//Transparent text background.

You saw in Figure 1 that we are moving yellow text on a black background.  In this simple case, all we need to do to erase the text is to draw it over top of itself in black.  The code in Listing 3 does exactly that.  The call to the makecol function with parameters of 0,0,0 returns the RGB value for black.  Therefore, each time the code in Listing 3 executes, black text is drawn on a black background resulting in text that cannot be seen.  If there happens to be a line of yellow text there, it will be overwritten with black text.

Modify coordinate variables if arrow keys are pressed

You may have noticed that I skipped rather hurriedly over the conditional clause in the while loop in Listing 2.  That was because I wanted to defer certain details regarding that test until now.

According to allegro.cc, programs that you write using Allegro have access to an array of true/false data where the value in each element in the array represents the pressed/non-pressed state of one key on the keyboard.  If the key is pressed, the element contains a true value.  Otherwise, it contains a false value.

The code in Listing 4 uses four numeric symbolic constants to check the state of each of the arrow keys once during each iteration of the while loop.

Listing 4. Modify coordinate variables if arrow keys are pressed.
    if (key[KEY_UP]) --y;
    else if (key[KEY_DOWN]) ++y;
    else if (key[KEY_RIGHT]) ++x;
    else if (key[KEY_LEFT]) --x;

Not exactly true

Actually, that statement isn't exactly true.  The state of all four arrow keys is checked during a single iteration only if none of the arrow keys are pressed or only the left-arrow key is pressed.  For example, if a true value is found in the array element that represents the up-arrow key, the elements for the remaining three keys are not checked during that iteration.  This explains why the text can only be moved up, down, left, or right.  If you press two keys at the same time, only one of those keys is recognized by the program as being pressed during that iteration of the while loop.

The conditional clause of the while loop

Going back to the conditional clause in the while loop in Listing 2, at the beginning of each iteration, the array element corresponding to the Esc key is checked to see if that key if pressed.  If the Esc key is not pressed, the element contains a value of false, which is inverted by the (!) operator, causing the conditional clause to return true and causing the while loop to execute one additional iteration.

The if statements

Returning to a discussion of the tests in Listing 4, if none of the arrow keys is pressed, the position coordinates for the text remain unchanged.  This will cause the text to be drawn in exactly the same location the next time it is drawn.

However, if one (or more) of the arrow keys is pressed, one of the position coordinates is incremented or decremented by a value of one pixel.  This will cause the text to be drawn in a different location the next time it is drawn.

Draw yellow text at the same or a new position

The code in Listing 5 draws "HELLO WORLD" in yellow text at the location specified by the x and y coordinate variables.

Listing 5. Draw yellow text at the same or a new position.
    textout_ex(
             screen,//Specify bitmap on the screen
             font,//Use a default font
             "HELLO WORLD",//Specify the text to display
             x,//x-coordinate for text
             y,//y-coordinate for text
             makecol(255,255,0),//Color text yellow
             -1 );//Transparent text background.

Delay for ten milliseconds

Listing 6 calls the rest function to purposely insert a ten-millisecond delay during each iteration of the while loop.

Listing 6. Delay for ten milliseconds.
    rest(10);//Give up the cpu for ten milliseconds.
  }//end while loop

Listing 6 also signals the end of the while loop.

The end of the program

Listing 7 shows the end of the main function.

Listing 7. The end of the program.
  return 0;//Return 0 to indicate a successful run.
}//end main function

//Required macro at end of main.
END_OF_MAIN()

When the main function has nothing more to do, it returns, which in turn, causes the program to terminate.

Summary

In this lesson, I showed you how to write an Allegro project that:

Complete program listing

A complete listing of the program discussed in this lesson is shown in Listing 8 below.

Listing 8. Source code for the program named MovableHelloWorld01.
//Project MovableHelloWorld01
//Move text around the screen by pressing the arrow keys.
//Press Esc to terminate the program.
//Note that this program is based on polling and not on
//handling events.

#include <allegro.h>

int main(){
  int x = 20,y = 30;//position coordinates for text

  allegro_init();//Allegro initialization
  install_keyboard();//Set up for keyboard input

  //Set the graphics mode to a 320x240-pixel window.
  set_gfx_mode(GFX_AUTODETECT_WINDOWED, 320,240,0,0);
  
  while(!key[KEY_ESC]){//loop until user presses Esc key

    clear_keybuf();//clear old stuff from the buffer
    
    //Draw black text on the existing text to erase it.
    textout_ex(
             screen,//Specify bitmap on the screen
             font,//Use a default font
             "HELLO WORLD",//Specify the text to display
             x,//x-coordinate for text
             y,//y-coordinate for text
             makecol(0,0,0),//Color text black
             -1 );//Transparent text background.
    
    //Modify coordinate variables if user presses arrow.
    // Note that diagonal motion resulting from holding
    // two keys down is not supported.
    if (key[KEY_UP]) --y;
    else if (key[KEY_DOWN]) ++y;
    else if (key[KEY_RIGHT]) ++x;
    else if (key[KEY_LEFT]) --x;
    
    //Draw fresh text on the window at the new coordinate
    // position.
    textout_ex(
             screen,//Specify bitmap on the screen
             font,//Use a default font
             "HELLO WORLD",//Specify the text to display
             x,//x-coordinate for text
             y,//y-coordinate for text
             makecol(255,255,0),//Color text yellow
             -1 );//Transparent text background.

    rest(10);//Give up the cpu for ten milliseconds.
  }//end while loop

  return 0;//Return 0 to indicate a successful run.
}//end main function

//Required macro at end of main.
END_OF_MAIN()

Resources


Copyright

Copyright 2008, Richard G. Baldwin.  Reproduction in whole or in part in any form or medium without express written permission from Richard Baldwin is prohibited.

About the author

Richard Baldwin is a college professor (at Austin Community College in Austin, TX) and private consultant whose primary focus is a combination of Java, C#, and XML. In addition to the many platform and/or language independent benefits of Java and C# applications, he believes that a combination of Java, C#, and XML will become the primary driving force in the delivery of structured information on the Web.

Richard has participated in numerous consulting projects and he frequently provides onsite training at the high-tech companies located in and around Austin, Texas.  He is the author of Baldwin's Programming Tutorials, which have gained a worldwide following among experienced and aspiring programmers. He has also published articles in JavaPro magazine.

In addition to his programming expertise, Richard has many years of practical experience in Digital Signal Processing (DSP).  His first job after he earned his Bachelor's degree was doing DSP in the Seismic Research Department of Texas Instruments.  (TI is still a world leader in DSP.)  In the following years, he applied his programming and DSP expertise to other interesting areas including sonar and underwater acoustics.

Richard holds an MSEE degree from Southern Methodist University and has many years of experience in the application of computer technology to real-world problems.

Baldwin@DickBaldwin.com

-end-