About load bitmap
keprast

"新年快乐!各位!" :D
(happy New Year! Ladies and gentlemen!)

I would like to ask a small problem today.For newcomers, though, it is very serious. ::)

ALLEGRO_BITMAP,Is he a "const"?(He pointed pointer)
allegro_load_bitmap,How his efficiency?How long it takes to load the image (eg 200 * 200 pixels)?

Or, if we have a lot of animated pictures.Have to use ALLEGRO_BITMAP to create a large number of pointers.
Rather than using load to quickly load.
-------------------------------------
ALLEGRO_BITMAP * running_anima[500];
This should be feasible?

Neil Roy

ALLEGRO_BITMAP
https://www.allegro.cc/manual/5/ALLEGRO_BITMAP

typedef struct ALLEGRO_BITMAP ALLEGRO_BITMAP;

It's a struct which contains information about the bitmap you loaded, things like width, height etc.

keprast

Thanks. ;D

eg:200*200 size,75pixel/cm
--------------------------
New proble:

I changed something, but he can not use it.
My method of using two timers is wrong.
why?

#SelectExpand
1 case ALLEGRO_EVENT_TIMER: 2 if (event.timer.source == timer) 3 { 4 x = x + 5 * xd; 5 y = y + 5 * yd; 6 7 if (xd > 0 && x + sw >= WIDTH) { 8 x = WIDTH - sw; 9 xd = 0; 10 yd = -1; 11 } 12 else if (xd < 0 && x <= 0) { 13 x = 0; 14 xd = 0; 15 yd = 1; 16 } 17 18 if (yd > 0 && y + sh >= HEIGHT) { 19 y = HEIGHT - sh; 20 yd = 0; 21 xd = 1; 22 } 23 else if (yd < 0 && y <= 0) { 24 y = 0; 25 yd = 0; 26 xd = -1; 27 } 28 29 al_set_target_bitmap(al_get_backbuffer(display)); 30 al_clear_to_color(al_map_rgb(255, 255, 255)); 31 } 32 if (event.timer.source == animation) { 33 int pt = 0; 34 pt++; 35 if (pt == 17) 36 pt = 0; 37 al_draw_bitmap(sprite[pt], x, y, 0); 38 } 39 40 al_flip_display();

error:

abort() been xxxxxxxxx.
---------------------------------
Complete code:

#SelectExpand
1#include <allegro5/allegro.h> 2#include <allegro5/allegro_image.h> 3#include <stdio.h> 4 5const int WIDTH = 1024; 6const int HEIGHT = 768; 7char anima[25]; 8 9int main(int argc, char * argv[]) { 10 int running = 1, sw, sh, x, y, xd = 1, yd = 0; 11 ALLEGRO_BITMAP * sprite[16]; 12 for (int i = 0; i < 16; i++) 13 { 14 sprite[i] = NULL; 15 } 16 ALLEGRO_DISPLAY * display = NULL; 17 ALLEGRO_EVENT_QUEUE * event_queue = NULL; 18 ALLEGRO_EVENT event; 19 ALLEGRO_TIMER * timer = NULL; 20 ALLEGRO_TIMER * animation = NULL; 21 22 if (!al_init()) { 23 fprintf(stderr, "Allegro failed to initialize. Something is wrong with your system.\n"); 24 return 1; 25 } 26 27 if (!al_install_keyboard()) { 28 fprintf(stderr, "Allegro failed to install keyboard. Something is wrong with your system.\n"); 29 return 1; 30 } 31 32 display = al_create_display(WIDTH, HEIGHT); 33 34 if (display == NULL) { 35 fprintf(stderr, "Allegro failed to create a display of size 1024x768. Something is wrong with your system.\n"); 36 return 1; 37 } 38 39 timer = al_create_timer(1 / 60.0); 40 animation = al_create_timer(0.0); 41 al_set_timer_speed(animation, 0.2); 42 43 if (timer == NULL) { 44 fprintf(stderr, "Allegro failed to create a timer. Something is wrong with your system.\n"); 45 return 1; 46 } 47 48 event_queue = al_create_event_queue(); 49 50 if (event_queue == NULL) { 51 fprintf(stderr, "Allegro failed to create an event queue. Something is wrong with your system.\n"); 52 return 1; 53 } 54 55 al_register_event_source(event_queue, al_get_display_event_source(display)); 56 al_register_event_source(event_queue, al_get_keyboard_event_source()); 57 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 58 al_register_event_source(event_queue, al_get_timer_event_source(animation)); 59 60 if (!al_init_image_addon()) { 61 fprintf(stderr, "Allegro failed to initialize the image addon. Something is wrong with your system.\n"); 62 return 1; 63 } 64 65 for (int i = 5; i < 21; i++) 66 { 67 sprintf(anima, "%.5i.png", i); 68 sprite[i - 5] = al_load_bitmap(anima); 69 /* if (sprite[i] == NULL) { 70 fprintf(stderr, "Allegro failed to load %s. Image format may not be supported. Or something is wrong with your system.\n", sprite[i]); 71 return 1; 72 }*/ 73 } 74 75 sw = al_get_bitmap_width(sprite[0]); 76 sh = al_get_bitmap_width(sprite[0]); 77 78 x = (WIDTH / 2.0) - (sw / 2.0); 79 y = (HEIGHT / 2.0) - (sh / 2.0); 80 81 al_start_timer(timer); 82 al_start_timer(animation); 83 84 while (running) { 85 al_wait_for_event(event_queue, &event); 86 87 switch (event.type) { 88 case ALLEGRO_EVENT_DISPLAY_CLOSE: 89 running = 0; 90 break; 91 case ALLEGRO_EVENT_KEY_DOWN: 92 if (event.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { 93 running = 0; 94 } 95 96 break; 97 case ALLEGRO_EVENT_TIMER: 98 if (event.timer.source == timer) 99 { 100 x = x + 5 * xd; 101 y = y + 5 * yd; 102 103 if (xd > 0 && x + sw >= WIDTH) { 104 x = WIDTH - sw; 105 xd = 0; 106 yd = -1; 107 } 108 else if (xd < 0 && x <= 0) { 109 x = 0; 110 xd = 0; 111 yd = 1; 112 } 113 114 if (yd > 0 && y + sh >= HEIGHT) { 115 y = HEIGHT - sh; 116 yd = 0; 117 xd = 1; 118 } 119 else if (yd < 0 && y <= 0) { 120 y = 0; 121 yd = 0; 122 xd = -1; 123 } 124 125 al_set_target_bitmap(al_get_backbuffer(display)); 126 al_clear_to_color(al_map_rgb(255, 255, 255)); 127 } 128 if (event.timer.source == animation) { 129 int pt = 0; 130 pt++; 131 if (pt == 17) 132 pt = 0; 133 al_draw_bitmap(sprite[pt], x, y, 0); 134 } 135 136 al_flip_display(); 137 138 break; 139 } 140 } 141 142 return 0; 143}

beoran

With contemporary graphics hardware, it is best to arrange all animation frames in a single bitmap. This is called an "atlas bitmap". You can then either use al_draw_bitmap_region to draw the frames, or al_create_sub_bitmap to create individual bitmaps for the frames efficienly.

And a happy new year to you to!

Edgar Reynaldo

You are mixing drawing and logic. That only causes problems. Keep your drawing code separate from your logic. Have one redraw only, not two running on separate timers or you'll get out of sequence. You can still use two timers for your logic rates, but only one timer should control the redraw.

Neil Roy

To add to beoran's advice. You should also set up a timer so that every time the timer fires off, you update the animation (switch to the next image). You will have to decide for yourself how often you want the time to fire off.

In my Deluxe Pacman 2 game I have one large PNG image for my Pacman character in a 5x5 grid of images that make up the animation. When you are moving, the first 5 images are used and when you die, it goes through the rest.

My Allegro 5 code to load in my main pacman image, with this 5x5 grid of images is...

#SelectExpand
1 // Note: SPRITE_SIZE = the size of each image in your sheet 2 pacman.sheet = al_load_bitmap("Graphics/Pacman.png"); 3 if(!pacman.sheet) { 4 // didn't load, do error stuff here 5 } 6 al_lock_bitmap(pacman.sheet, al_get_bitmap_format(pacman.sheet), ALLEGRO_LOCK_READONLY); 7 for(int y = 0; y < 5; y++) { // bitmaps are 5 rows 8 for(int x = 0; x < 5; x++) { // by 5 columns 9 pacman.bitmap[5 * y + x] = NULL; 10 pacman.bitmap[5 * y + x] = al_create_sub_bitmap(pacman.sheet, x * SPRITE_SIZE, y * SPRITE_SIZE, SPRITE_SIZE, SPRITE_SIZE); 11 if(!pacman.bitmap[5 * y + x]) { 12 // sub_bitmap failed, handle error here 13 } 14 } 15 }

I then later set up a timer for the pacman animation...

   // Create a timer for updating pacman movement
   // once InitPacman is done
   pacman.timer = al_create_timer(1.0f / pacman.ts);
   if(!pacman.timer) {
      // Handle errors here
   }
   al_register_event_source(event_queue, al_get_timer_event_source(pacman.timer));
   al_start_timer(pacman.timer);

pacman.ts holding the speed I wish to update this.

And in my game loop event checker, I check for the timer and update pacman's animation when it fires...

   case ALLEGRO_EVENT_TIMER:
      // PACMAN TIMER
      if(event.timer.source == pacman.timer) {
         // Do pacman stuff here
      }

keprast

A large number of relatives I totally can not find time.

Thank you for your help, I think I understand. :D
But still, the problems are always one after another. ::)
I do not quite understand what a substantive effect locking the image is, except for faster changes.

Neil Roy

From the Allegro wiki (https://www.allegro.cc/manual/5/al_lock_bitmap) on using al_lock_bitmap() with ALLEGRO_LOCK_READONLY as I do in my code.

“ALLEGRO_LOCK_READONLY - The locked region will not be written to. This can be faster if the bitmap is a video texture, as it can be discarded after the lock instead of uploaded back to the card.”

When you read/write a bitmap, Allegro has to update the bitmap after you are done, which takes time. If you lock it as read only, that means you won't be altering it and Allegro can simply discard it once you're done without wasting time updating it. Which makes sense.

keprast

I think I understand, thank you for teaching.
When the image is locked, the image will not be drawn, but he is in memory when it is unlocked, it will draw on the screen.

Thread #617277. Printed from Allegro.cc