The Allegro Wiki is migrating to github at https://github.com/liballeg/allegro_wiki/wiki

Allegro Vivace/Game Structure

From Allegro Wiki
Jump to: navigation, search

A basic game structure

Most games are built around the same basic concepts. A game will generally follow the structure described below (which are refered to as "phases"):

  • Initialization
  • Game Loop
  • Cleaning up and exiting

Initialization

The first phase of the game is initialization. This means that we put the game into a known state, so that it always starts the same way. This is often where you allocate the resources a game uses (e.g. loading graphics and sounds), and where you setup the different entities that make up your game (for example making sure that the player always starts at the center of the screen, making a maze, or creating a random map, etc.).

Game Loop

The game loop is the heart of the game. It loops continously until a certain state is reached, such as when the player dies, wins, gives up or anything else you consider a condition where the game should end. The game will need to keep doing things, over and over again, and that's why we need a game loop. A game loop will consist of three main phases:

  • Input
  • Processing
  • Output

Input

The input phase collects input from the player. It could be from any input device, such as the keyboard, mouse, a joystick or a gamepad.

Processing

The process phase responds to the input gathered from the player. If the player has pressed a key, we might need to update the player position. This is also where we handle collision detection between different entities, and handle the artificial intelligence (AI) of, for example, enemies.

Output

The output phase sends information back to the user, usually by displaying graphics on the screen or playing sounds.

Cleaning up and exiting

When the game has finished, we need to do some cleanup. We need to destroy all the resources we allocated in the initialiation phase and everything else we have setup that needs to be dealt with.

Code Example

The source code below is an implementation of the concepts described above using Allegro 5. The program initializes allegro, displays a window, runs a gameloop until the user presses the escaspe key and then quits. We will use this as reference point throughout the tutorial. We will dissect the source code in the next chapter.

#include <allegro5/allegro5.h>
#include <stdio.h>
#include <stdlib.h>
 
bool done;
ALLEGRO_EVENT_QUEUE* event_queue;
ALLEGRO_TIMER* timer;
ALLEGRO_DISPLAY* display;
 
void abort_game(const char* message)
{
    printf("%s \n", message);
    exit(1);
}
 
void init(void)
{
    if (!al_init())
        abort_game("Failed to initialize allegro");
 
    if (!al_install_keyboard())
        abort_game("Failed to install keyboard");
 
    timer = al_create_timer(1.0 / 60);
    if (!timer)
        abort_game("Failed to create timer");
 
    al_set_new_display_flags(ALLEGRO_WINDOWED);
    display = al_create_display(640, 480);
    if (!display)
        abort_game("Failed to create display");
 
    event_queue = al_create_event_queue();
    if (!event_queue)
        abort_game("Failed to create event queue");
 
    al_register_event_source(event_queue, al_get_keyboard_event_source());
    al_register_event_source(event_queue, al_get_timer_event_source(timer));
    al_register_event_source(event_queue, al_get_display_event_source(display));
 
    done = false;
}
 
void shutdown(void)
{
    if (timer)
        al_destroy_timer(timer);
 
    if (display)
        al_destroy_display(display);
 
    if (event_queue)
        al_destroy_event_queue(event_queue);
}
 
void game_loop(void)
{
    bool redraw = true;
    al_start_timer(timer);
 
    while (!done) {
        ALLEGRO_EVENT event;
        al_wait_for_event(event_queue, &event);
 
        if (event.type == ALLEGRO_EVENT_TIMER) {
            redraw = true;
            //update_logic();
        }
        else if (event.type == ALLEGRO_EVENT_KEY_DOWN) {
            if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) {
                done = true;
            }
            //get_user_input();
        }
 
        if (redraw && al_is_event_queue_empty(event_queue)) {
            redraw = false;
            al_clear_to_color(al_map_rgb(0, 0, 0));
            //update_graphics();
            al_flip_display();
        }
    }
}
 
int main(int argc, char* argv[])
{
    init();
    game_loop();
    shutdown();
}