Hi! I am trying to write a simple game using Allegro 5. It all works with a square, but it doesn't work with my image. My idea is to have a 'warrior' who explores map avoiding some objects around. It's all of course in progress. I am absolute beginner by the way. Before adding image it was okay, but now it shuts down after less than second. What should I change?
Thanks for help and ideas!
CODE (based on Basic Keyboard Example):
#include <stdio.h>
#include <allegro5/allegro.h>
#include <allegro5/allegro_image.h>
const float FPS = 60;
const int SCREEN_W = 1024;
const int SCREEN_H = 768;
const int WARRIOR_SIZE = 16;
enum MYKEYS {
KEY_UP, KEY_DOWN, KEY_LEFT, KEY_RIGHT
};
int main(int argc, char **argv)
{
ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_EVENT_QUEUE *event_queue = NULL;
ALLEGRO_TIMER *timer = NULL;
ALLEGRO_BITMAP *warrior = al_load_bitmap("warrior.png");
float warrior_x = SCREEN_W / 2.0 - WARRIOR_SIZE / 2.0;
float warrior_y = SCREEN_H / 2.0 - WARRIOR_SIZE / 2.0;
bool key[4] = { false, false, false, false };
bool redraw = true;
bool doexit = false;
if (!al_init()) {
fprintf(stderr, "failed to initialize allegro!\n");
return -1;
}
if (!al_install_keyboard()) {
fprintf(stderr, "failed to initialize the keyboard!\n");
return -1;
}
if (!al_init_image_addon()) {
fprintf(stderr, "Failed to initialize al_init_image_addon!\n");
return -1;
}
timer = al_create_timer(1.0 / FPS);
if (!timer) {
fprintf(stderr, "failed to create timer!\n");
return -1;
}
display = al_create_display(SCREEN_W, SCREEN_H);
if (!display) {
fprintf(stderr, "failed to create display!\n");
al_destroy_timer(timer);
return -1;
}
warrior = al_load_bitmap("warrior.png");
if (!warrior) {
fprintf(stderr, "failed to create warrior!\n");
al_destroy_display(display);
al_destroy_timer(timer);
return 0;
}
al_set_target_bitmap(warrior);
al_set_target_bitmap(al_get_backbuffer(display));
event_queue = al_create_event_queue();
if (!event_queue) {
fprintf(stderr, "failed to create event_queue!\n");
al_destroy_bitmap(warrior);
al_destroy_display(display);
al_destroy_timer(timer);
return -1;
}
al_register_event_source(event_queue, al_get_display_event_source(display));
al_register_event_source(event_queue, al_get_timer_event_source(timer));
al_register_event_source(event_queue, al_get_keyboard_event_source());
al_clear_to_color(al_map_rgb(0, 0, 0));
al_flip_display();
al_start_timer(timer);
while (!doexit)
{
ALLEGRO_EVENT ev;
al_wait_for_event(event_queue, &ev);
if (ev.type == ALLEGRO_EVENT_TIMER) {
if (key[KEY_UP] && warrior_y >= 4.0) {
warrior_y -= 4.0;
}
if (key[KEY_DOWN] && warrior_y <= SCREEN_H - WARRIOR_SIZE - 4.0) {
warrior_y += 4.0;
}
if (key[KEY_LEFT] && warrior_x >= 4.0) {
warrior_x -= 4.0;
}
if (key[KEY_RIGHT] && warrior_x <= SCREEN_W - WARRIOR_SIZE - 4.0) {
warrior_x += 4.0;
}
redraw = true;
}
else if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
break;
}
else if (ev.type == ALLEGRO_EVENT_KEY_DOWN) {
switch (ev.keyboard.keycode) {
case ALLEGRO_KEY_UP:
key[KEY_UP] = true;
break;
case ALLEGRO_KEY_DOWN:
key[KEY_DOWN] = true;
break;
case ALLEGRO_KEY_LEFT:
key[KEY_LEFT] = true;
break;
case ALLEGRO_KEY_RIGHT:
key[KEY_RIGHT] = true;
break;
}
}
else if (ev.type == ALLEGRO_EVENT_KEY_UP) {
switch (ev.keyboard.keycode) {
case ALLEGRO_KEY_UP:
key[KEY_UP] = false;
break;
case ALLEGRO_KEY_DOWN:
key[KEY_DOWN] = false;
break;
case ALLEGRO_KEY_LEFT:
key[KEY_LEFT] = false;
break;
case ALLEGRO_KEY_RIGHT:
key[KEY_RIGHT] = false;
break;
case ALLEGRO_KEY_ESCAPE:
doexit = true;
break;
}
}
if (redraw && al_is_event_queue_empty(event_queue)) {
redraw = false;
al_draw_bitmap(warrior, warrior_x, warrior_y, 0);
al_flip_display();
al_clear_to_color(al_map_rgb(250, 250, 250));
}
}
al_destroy_bitmap(warrior);
al_destroy_timer(timer);
al_destroy_display(display);
al_destroy_event_queue(event_queue);
return 0;
}
I'd say the reason is because you're trying to call al_load_bitmap() before Allegro is even initialized. You should have the al_init() function first, then al_init_image_addon(), and only after those two can you actually call al_load_bitmap().
Other than that, you can also try checking if your "warrior" bitmap is NULL, after the al_load_bitmap() call. If so, that means something went wrong with the loading itself, like the file "warrior.png" not being found, or something.
Also, don't forget to use code tags! It makes it much easier for people to read your code and help you!
See:
I have al_init before al_init_image_addon, so I don't know exactly what you mean. I still don't know what to do. Can someone post correct code? I will realise where my mistake was.:-/
Look at the formatted code that Chris Katko posted. In line 17 you do al_load_bitmap. In line 24, you do al_init. And in line 33, you call al_init_image_addon.
You have to move the bitmap loading from line 17 to after line 33.
I did it and it still doesn't work.
int main(int argc, char **argv)
{
ALLEGRO_DISPLAY *display = NULL;
ALLEGRO_EVENT_QUEUE *event_queue = NULL;
ALLEGRO_TIMER *timer = NULL;
float warrior_x = SCREEN_W / 2.0 - WARRIOR_SIZE / 2.0;
float warrior_y = SCREEN_H / 2.0 - WARRIOR_SIZE / 2.0;
bool key[4] = { false, false, false, false };
bool redraw = true;
bool doexit = false;
if (!al_init()) {
fprintf(stderr, "failed to initialize allegro!\n");
return -1;
}
if (!al_install_keyboard()) {
fprintf(stderr, "failed to initialize the keyboard!\n");
return -1;
}
if (!al_init_image_addon()) {
fprintf(stderr, "Failed to initialize al_init_image_addon!\n");
return -1;
}
ALLEGRO_BITMAP *warrior = al_load_bitmap("warrior.png");
timer = al_create_timer(1.0 / FPS);
if (!timer) {
fprintf(stderr, "failed to create timer!\n");
return -1;
}
...
It is better to also first create a display before loading the bitmap. If the image does not load, it is likely Allegro5 cannot find the bitmap. What does al_get_current_directory return, and does that match your expectations?
Okay, guys. It was only problem with a image. I tried it on different one and it works Thanks for help! Now I have to focus on other things.