This post is a portion of Part 11 in my on going series about 2D Game Development using the Allegro 5 library. These posts are in course order. You can see all of the posts in this course by clicking the “2D Game Development” button at the top of this site.
- Part 11.0 – Backgrounds
- Part 11.1 – Parallax Backgrounds
- Part 11.2 – Tile Backgrounds
- Part 11.3 – Tile Backgrounds with Mappy
Let’s tackle our first background project. In this video we look at creating scrolling, parallax backgrounds in Allegro 5. Using the attached code and images, you can add some cool effects to your games.
Full source can be found here.
What i have to do if i want to translate parallax background on x-axis?
I’m getting back exception errors with the first background in this video, what’s wrong with my code?
//Allegro5 libraries.
#include
#include
#include
#include
#include
#include
#include
const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 600;
const int FPS = 60;
enum KEYS {UP, DOWN, LEFT, RIGHT, SPACE}; //The keys for our player’s movement.
bool keys[5] = {false, false, false, false, false};
struct Background
{
float x;
float y;
float velX;
float velY;
int dirX;
int dirY;
int width;
int height;
ALLEGRO_BITMAP *image;
};
void InitBackground(Background &back, float x, float y, float velx, float vely, int width, int height, int dirX, int dirY, ALLEGRO_BITMAP *image);
void UpdateBackground(Background &back);
void DrawBackground(Background &back);
int main(void)
{
int x = SCREEN_WIDTH / 2;
int y = SCREEN_HEIGHT / 2;
Background back;
bool done = false; //Declaring our gameOver variable for when the game ends.
bool redraw = false; //Declaring our redraw variable to smooth out movement.
//Allegro Variables.
ALLEGRO_DISPLAY *gameDisplay = NULL; //Initializing a display variable from the ALLEGRO_DISPLAY class.
ALLEGRO_EVENT_QUEUE *eventQueue = NULL;
ALLEGRO_TIMER *gameTimer = NULL;
ALLEGRO_BITMAP *backImage = NULL; //Initializing our background image.
ALLEGRO_FONT *font18 = NULL;
if(!al_init()) //Conditional checks to see if Allegro is initialized.
{
al_show_native_message_box(NULL, NULL, NULL,
“failed to initialize Allegro.”, NULL, NULL);
return -1;
}
gameDisplay = al_create_display(SCREEN_WIDTH, SCREEN_HEIGHT); //Sets the display variable to create a 800 x 400 display window.
if(!gameDisplay) //Conditional checks to see if the display was properly initialized.
{
al_show_native_message_box(NULL, NULL, NULL,
“failed to initialize display.”, NULL, NULL);
return -1;
}
al_init_primitives_addon(); //Initializing the Allegro Primitives addon.
al_install_keyboard(); //Installing keyboard functionality for player input.
al_init_font_addon();
al_init_ttf_addon();
backImage = al_load_bitmap(“starBG.png”);
InitBackground(back, 0, 0, 1, 0, SCREEN_WIDTH, SCREEN_HEIGHT, -1, 1, backImage);
font18 = al_load_font(“arial.ttf”, 18, 0);
eventQueue = al_create_event_queue(); //Creating our event queue object.
gameTimer = al_create_timer(1.0 / FPS); //Creating our timer object.
//Event sources.
al_register_event_source(eventQueue, al_get_keyboard_event_source()); //Keyboard event source.
al_register_event_source(eventQueue, al_get_display_event_source(gameDisplay)); //Display event source.
al_register_event_source(eventQueue, al_get_timer_event_source(gameTimer)); //Timer event source.
al_start_timer(gameTimer);
while(!done)
{
ALLEGRO_EVENT myEvent;
al_wait_for_event(eventQueue, &myEvent);
if(myEvent.type == ALLEGRO_EVENT_KEY_DOWN) //Condition to check for a key press by the player.
{
//Checking for which key by keycode.
switch(myEvent.keyboard.keycode)
{
//Keyboard arrows for player movement.
case ALLEGRO_KEY_UP:
keys[UP] = true; //Player moves up.
break;
case ALLEGRO_KEY_DOWN:
keys[DOWN] = true; //Player moves down.
break;
case ALLEGRO_KEY_LEFT:
keys[LEFT] = true; //Player moves left.
break;
case ALLEGRO_KEY_RIGHT:
keys[RIGHT] = true; //Player moves right.
break;
case ALLEGRO_KEY_SPACE: //Player shoots the ship’s guns.
keys[SPACE] = true;
break;
case ALLEGRO_KEY_ESCAPE: //if ESC is pressed, game is over.
done = true;
break;
}
}
else if(myEvent.type == ALLEGRO_EVENT_KEY_UP) //Condition to check for keys being released on the keyboard.
{
//Checking for which key by keycode.
switch(myEvent.keyboard.keycode)
{
//Releasing the keys.
case ALLEGRO_KEY_UP:
keys[UP] = false; //The Up key is released.
break;
case ALLEGRO_KEY_DOWN:
keys[DOWN] = false; //The Down key is released.
break;
case ALLEGRO_KEY_LEFT:
keys[LEFT] = false; //The Left key is released.
break;
case ALLEGRO_KEY_RIGHT:
keys[RIGHT] = false; //The Right key is released.
break;
case ALLEGRO_KEY_SPACE: //Player stops shooting the ship’s guns.
keys[SPACE] = false;
break;
}
}
else if(myEvent.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
{
done = true;
}
else if(myEvent.type == ALLEGRO_EVENT_TIMER) //Our update function.
{
UpdateBackground(back);
redraw = true;
}
if(redraw && al_is_event_queue_empty(eventQueue))
{
DrawBackground(back);
redraw = false;
al_flip_display(); //Flip the display once every 1/30 of a second with the back buffer display.
al_clear_to_color(al_map_rgb(0, 0, 0)); //clear the display to black every 1/30 of a second.
}
}
al_rest(3.0); //Pausing the program for 3 seconds after everything’s run.
//Destroying objects for clean up.
al_destroy_bitmap(backImage);
al_destroy_timer(gameTimer);
al_destroy_event_queue(eventQueue);
al_destroy_font(font18);
al_destroy_display(gameDisplay);
return 0;
}
void InitBackground(Background &back, float x, float y, float velx, float vely, int width, int height, int dirX, int dirY, ALLEGRO_BITMAP *image)
{
back.x = x;
back.y = y;
back.velX = velx;
back.velY = vely;
back.width = width;
back.height = height;
back.dirX = dirX;
back.dirY = dirY;
back.image = image;
}
void UpdateBackground(Background &back)
{
back.x += back.velX * back.dirX;
if(back.x + back.width <= 0)
back.x = 0;
}
void DrawBackground(Background &back)
{
al_draw_bitmap(back.image, back.x, back.y, 0);
if(back.x + back.width < SCREEN_WIDTH)
al_draw_bitmap(back.image, back.x + back.width, back.y, 0);
}
Mike, You’ve forgotten about
al_destroy_timer(timer);
😉