2D Game Programming In C++ Under Windows: Allegro Basics

In This Tutorial Series

I: 2D Game Programming In C++ under Windows.

II: 2D Game Programming in C++ under Windows: Allegro Basics (For developing Simple Games)

III: 2D Game Programming In C++ under Windows: Doing Cool Things With Allegro

In the Last Article, we pondered- "How to make a 2D Game?". We discussed how to setup the Environment for programming a game in C++, under Windows.

By Now, you should have two things, before this tutorial will be useful to you:

1. DevC++ IDE.

2. Allegro DevPaks (As Listed in the last Article).

Not sure of What I'm talking about?

Visit my last tutorial. It discusses the Game Programming in general, and Setting up DevC++ and Allegro Library.

ALLEGRO Basics

To begin, you'll just use a few functions, that'll get the work done. And Later, you can look at The Allegro Documentation, and learn to do more.

The Program structure for Game written with Allegro:

Unlike the usual C++ program structure inside main(),

Allegro Program Structure

int main(void)

      {

         allegro_init();

         /* more stuff goes here */

         ...

         return 0;

      }

      END_OF_MAIN()

Initialising Allegro

First we have to initialize Allegro System. Then we’ll set a Graphics Mode. Note that this will override the console set up by C/C++ code.

Initializing Allegro:

int allegro_init();


Macro which initializes the Allegro library.

Setting up Graphics Mode:

(From Allegro Documentation)

“ Due to the wide range of supported platforms, a graphic mode is the only way to safely communicate with the user. Setting a graphic mode involves deciding how to allocate the memory of the video card for your program. Each platform has a number of graphic drivers which support a different range of hardware or behave in different ways. To avoid cluttering your own code with #ifdefs and dealing with drivers added after you release your program, Allegro provides several so called magic drivers. These magic drivers don't really exists, they wrap around a specific kind of functionality.”

There exist several magic drivers for this purpose. The one we’ll use for Windows is:

GFX_DIRECTX_WIN
The regular windowed DirectX driver, running in color conversion mode when the color depth doesn't match that of the Windows desktop.

set_gfx_mode(GFX_DIRECTX_WIN,w,h,0,0);

This works best under Windows. Where ’w’ and ‘h‘ represent the Resolution, and can be changed, as supported by the Display.

By now, you've the display. You need to control the basket. You need to get keyboard Inputs & process them.

Setting Up Keyboard:

install_keyboard();

This function installs the Allegro keyboard interrupt handler. You must call this before using any of the keyboard input routines. Once you have set up the Allegro handler, you can no longer use operating system calls or C library functions to access the keyboard.

Initialising Timer

Now, we’ll need to setup the Timer. We’ll need the Timer to control falling of objects, and to maintain time anyway. You must do this before installing any user timer routines, and also before displaying a mouse pointer, playing FLI animations or MIDI music, and using any of the GUI routines. Allegro can set up several virtual timers. Under non-DOS platforms, these are implemented using parallel threads, which run in a non-blocking way, in parallel to main thread.

install_timer();

Using Timer (It'll be used to control timings of objects falling down, and timings between bonuses, and to determine Player Rating) :

Keep It Global

time_t secs;
     
     
volatile int t=0; //volatile tells the compiler not to optimize the 
		  //variable, as it can be changed 
			

void inc_t(void)
 {
     t++;
 }

You must lock the memory used by timer routines

     
LOCK_VARIABLE(t);
LOCK_FUNCTION(inc_t);
     
install_int(inc_t,1000); //Installs a user timer handler, 

			 //with the speed given as the number of 	

			//milliseconds between ticks

//Now the timer will update update the variable t, after 1000 ms

How Objects will be displayed On Screen?

We’ll draw objects on the Screen, of course! Now what about animation?

When an object moves, two things can be done. The entire screen can be redrawn with present states of all the objects in game or alternatively, only the portion of the screen affected can be updated. The latter technique is known as dirty rectangles method.

We’ll use the first technique.

But updating the screen with so many objects, can be expensive on memory. So we’ll use a buffer bitmap for the purpose.

What’s a Bitmap?

Well, its an image format in general. But in context of Allegro, a BITMAP is a structure which can be used for Image Manipulation.

Once you have selected a graphics mode, you can draw things onto the display via the ‘screen’ bitmap. All the Allegro graphics routines draw onto BITMAP structures. You can create and manipulate bitmaps in system RAM, or you can write to the special ‘screen’ bitmap which represents the video memory in your graphics card.


Using Memory Buffers for inexpensive drawing:

Video Memory can be expensive. So what we do instead is, we create a bitmap, a buffer bitmap. We draw the objects on the buffer. Whenever there is a change in positions of objects on screen, we make the modifications as stated before. And at the end of each control loop, we’ll draw the buffer on ‘screen’ Bitmap. In this way, we bring the Game World in motion.

Creating a BITMAP to use as buffer and using it to draw on ‘screen’:

BITMAP *buffer= create_bitmap(width,height);

//Drawing on 'screen':

clear_to_color(buffer,makecol(255,255,255)); //Clears the bitmap to a color.
					    //Here its White.

//Makecol(r,g,b)- takes 3 Color Values, and returns a RGB Color.
.
.
//Code to handle Keyboard Inputs
.
.
 draw_trans_sprite(buffer,object,x,y);       
//Draws Images with transparent portions.
.
.
//At the end of control loop,    
draw_sprite(screen,buffer,0,0); //Finally draw the memory buffer onto
				//Video Memory

What's a 'sprite' ?

A sprite is a bit old term. It was coined by the old Game Programmers. The term sprite usually refers to the in-game characters, which are basically images.

As far as Allegro is concerned, a bitmap and a sprite are the same thing, but to many people the two words imply slightly different things. Generally you can say that sprites are a subset of bitmaps

Allegro allows lots of operations on sprites. Refer to the Allegro documentation that comes with the package in section 'Blitting and sprites' .

Sprites & Spritesheets (Google it, I insist), are used in 2D games for character repesentation & animation.

A spritesheet containing a few sprites.
A spritesheet containing a few sprites. | Source
An Apple Sprite, that will be used in the game we're making
An Apple Sprite, that will be used in the game we're making

Loading Images:

load_bitmap("Image_filename", palette);

Loads a bitmap from a file. The palette data will be stored in the second parameter, which should be an array of 256 RGB structures. At present this function supports BMP, LBM, PCX, and TGA files, determining the type from the file extension.

But more common image formats are ‘png’,and ‘jpeg’ . Especially we prefer png because it supports transperancy.

But How?

Remember from the last tutorial that we downloaded, ‘AllegroPng’ and ‘JPGAlleg’. These two libraries will help us in this matter.

Loading PNG Images:

First we need to include the header file: “alpng.h”. Next ,

BITMAP * pngImage=load_png(“png_ImageFileName”,palette);

What’s that ‘palette’ ?

The palette data is stored in the second parameter, which should be an array of 256 RGB structures. Its not very important in our context. Just write NULL, instead.

We need To Output Text:

Use these functions to output text:

void textout_ex(BITMAP *bmp, const FONT *f, const char *s, int x, int y, int color, int bg);


Writes the string ‘s’ onto the bitmap at position x, y, using the specified font, foreground color ('color') and background color ('bg'). If the background color is -1, then the text is written transparently. If the foreground color is -1 and a color font is in use, it will be drawn using the colors from the original font bitmap , which allows multicolored text output. For high and true color fonts, the foreground color is ignored and always treated as -1.

Getting Font:

Using True Type Fonts: the ones with extension 'ttf'

You need to include the header file: alfont.h

ALFONT_FONT *Ufont;

alfont_init();

Ufont=alfont_load_font("name_of_font.ttf");
alfont_set_font_size(Ufont,20); //Set up Font Size

Now this 'Ufont' can be used in the FONT parameter to get the required text output.

To print Text at the Centre:

void textout_centre_ex(BITMAP *bmp, const FONT *f, const char *s, int x, y, int color, int bg);


Like textout_ex(), but interprets the x coordinate as the centre rather than the left edge of the string. Example:

/* Important texts go in the middle. */

width = text_length("GAME OVER"); textout_centre_ex (screen, font, "GAME OVER", SCREEN_W / 2, SCREEN_H/2,makecol(255, 0, 0), makecol(0, 0, 0));

Handling Keyboard Inputs

We’ve installed the keyboard. Now we need to react in response to Keyboard Inputs.

If(key[key_code])
{
//Do this
}

Keyboard Scancodes

KEY_A ... KEY_Z, //Alphabets

KEY_0 ... KEY_9, //Numbers

KEY_0_PAD ... KEY_9_PAD, //Numbers-Keypad

KEY_F1 ... KEY_F12, //Function Keys

KEY_ESC, KEY_TILDE, KEY_MINUS, KEY_EQUALS,

KEY_BACKSPACE, KEY_TAB, KEY_OPENBRACE, KEY_CLOSEBRACE,

KEY_ENTER, KEY_COLON, KEY_QUOTE, KEY_BACKSLASH,

KEY_BACKSLASH2, KEY_COMMA, KEY_STOP, KEY_SLASH,

KEY_SPACE,

KEY_INSERT, KEY_DEL, KEY_HOME, KEY_END, KEY_PGUP, KEY_PGDN

KEY_LEFT, KEY_RIGHT, KEY_UP, KEY_DOWN, //Arrow Keys

KEY_SLASH_PAD, KEY_ASTERISK, KEY_MINUS_PAD,

KEY_PLUS_PAD, KEY_DEL_PAD, KEY_ENTER_PAD,

KEY_PRTSCR, KEY_PAUSE,

KEY_ABNT_C1, KEY_YEN, KEY_KANA, KEY_CONVERT, KEY_NOCONVERT,

KEY_AT, KEY_CIRCUMFLEX, KEY_COLON2, KEY_KANJI,

KEY_LSHIFT, KEY_RSHIFT,

KEY_LCONTROL, KEY_RCONTROL,

KEY_ALT, KEY_ALTGR,

KEY_LWIN, KEY_RWIN, KEY_MENU,

KEY_SCRLOCK, KEY_NUMLOCK, KEY_CAPSLOCK

KEY_EQUALS_PAD, KEY_BACKQUOTE, KEY_SEMICOLON, KEY_COMMAND

See whether a Key was pressed

Another function you can use is:

int keypressed();


Returns TRUE if there are keypresses waiting in the input buffer.

Possible usage:

while (!keypressed()) {

/*Do something. */

}

What we know now

Let’s see what we’ve learned till now, well in theory:

  1. How to initialise Allegro System in DevC++
  2. How Elements are drawn on Screen
  3. Loading Images
  4. Outputting Text
  5. Handling Keyboard Inputs

So, that’s quite much of what we need to know to program the basic Game. By now, you are into Game Programming already, and may be you can write something ;) Oh yes, we'll avoid the complicated stuff. Why? Cuz' we want to keep it simple, and second, we aren't designing a GUI for the Game.

In the Next Part (A Sequel Hub to this one) We'll see how an entire Game can be made based upon the present knowledge.

Where To Go From Here

You've learned the Allegro basics required to create a basic 2D Game now. Now let's build up the code that actually runs, and produces something , well see-able!

In the Next tutorial, I'll show you How to do some cool things with Allegro!

More by this Author


2 comments

Lautaro 2 years ago

awesome dude!

stay awesome :3


MysticPrince profile image

MysticPrince 2 years ago from The Source Code Author

Thanks :) Best of Luck for your efforts with Allegro. I'm sure it'll be fun and rewarding :)

    Sign in or sign up and post using a HubPages Network account.

    0 of 8192 characters used
    Post Comment

    No HTML is allowed in comments, but URLs will be hyperlinked. Comments are not for promoting your articles or other sites.


    Click to Rate This Article
    working