[a5] A doubt about move of image with keyboard
Jefferson Almeida

Hi, I can add the commands to move the image in my current "main_loop ();" or I'll have to modify it?

EDIT 1: In the Code::Blocks the indentation was perfect, here messed up a little and I do not know the reason :X

#SelectExpand
1/* Test */ 2 3void draw_character() 4{ 5 ALLEGRO_BITMAP *layer; 6 layer = al_load_bitmap("Sprites/FFT1/21.bmp"); 7 al_convert_mask_to_alpha(layer, (al_map_rgb(255, 0, 255))); 8 al_draw_bitmap(layer, 0,0,0); 9} 10 11 12void test(); 13void graphics(); 14void create_layers(); 15void map_draw(); 16 17static void main_loop(void) 18{ 19 ALLEGRO_EVENT ev; 20 int move = 0; 21 int andando = 0; 22 int prox, proy; 23 24 while (true) { 25 if (al_event_queue_is_empty(event_queue)) { 26 /* Test */ 27 draw_character(); 28 al_flip_display(); 29 } 30 al_wait_for_event(event_queue, &ev); 31 switch (ev.type) 32 { 33 case ALLEGRO_EVENT_DISPLAY_CLOSE: 34 return; 35 break; 36 case ALLEGRO_EVENT_KEY_DOWN: 37 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) 38 /* Test */ 39 draw_character(); 40 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) 41 /* Test */ 42 draw_character(); 43 else if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 44 return; 45 break; 46 case ALLEGRO_EVENT_KEY_CHAR: 47 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) 48 /* Test */ 49 draw_character(); 50 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) 51 /* Test */ 52 draw_character(); 53 else if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 54 return; 55 break; 56 case ALLEGRO_EVENT_TIMER: 57 /* Future Update of time */ 58// update(); 59 break; 60 } 61 } 62} 63 64int main(int argc , char** argv) 65{ 66 if(!al_init()) { 67 fprintf(stderr, "Failed al_init"); 68 return -1; 69 } 70 if(!al_init_primitives_addon()) { 71 fprintf(stderr, "Failed to initialize Addon primitives!\n"); 72 return -1; 73 } 74 al_init_font_addon(); 75 al_init_ttf_addon(); 76 if(!al_init_image_addon()) { 77 fprintf(stderr, "Failed to initialize Image addon!\n"); 78 return -1; 79 } 80 if(!al_install_mouse()) { 81 fprintf(stderr, "Failed to initialize Mouse!\n"); 82 return -1; 83 } 84 if(!al_install_keyboard()) { 85 fprintf(stderr, "Failed to initialize Keyboard!\n"); 86 return -1; 87 } 88 if(!al_install_audio()) { 89 fprintf(stderr, "failed to initialize audio!\n"); 90 return -1; 91 } 92 if(!al_init_acodec_addon()) { 93 fprintf(stderr, "failed to initialize audio codecs!\n"); 94 return -1; 95 } 96 if(!al_reserve_samples(1)) { 97 fprintf(stderr, "failed to reserve samples!\n"); 98 return -1; 99 } 100 timer = al_create_timer(1.0 / FPS); 101 if(!timer) { 102 fprintf(stderr, "Failed to created timer!\n"); 103 return -1; 104 } 105 font = al_load_ttf_font("DejaVuSans.ttf", 15, 0); 106 if(!font) { 107 fprintf(stderr, "Failed to load font!\n"); 108 return -1; 109 } 110 111 al_set_target_bitmap(al_get_backbuffer(display)); 112 113 event_queue = al_create_event_queue(); 114 if(!event_queue) { 115 fprintf(stderr, "Failed to create event_queue!\n"); 116 return -1; 117 } 118 test(); 119 graphics(); 120 //create_layers(); 121 display = al_create_display(SCREEN_W, SCREEN_H); 122 123 al_play_sample(sample, 1.0, 0.0,1.0,ALLEGRO_PLAYMODE_LOOP,NULL); 124 125 al_register_event_source(event_queue, al_get_display_event_source(display)); 126 127 al_get_timer_count(timer); 128 129 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 130 131 al_register_event_source(event_queue, al_get_keyboard_event_source()); 132 133 al_register_event_source(event_queue, al_get_mouse_event_source()); 134 135 al_flip_display(); 136 137 al_start_timer(timer); 138 139 main_loop(); 140 141 return 0; 142}

Edgar Reynaldo

1) Use integers local to main_loop and pass them to draw_character :

void draw_character(int x , int y) {
   al_draw_bitmap(char , x , y , 0);
}

void main_loop() {
   int cx = 10;
   int cy = 10;
   while (1) {
      /// blah
      draw_character(cx,cy);
   }
}

2) Use global integers

#SelectExpand
1int cx = 10; 2int cy = 10; 3 4void draw_character() { 5 al_draw_bitmap(char , cx , cy , 0); 6} 7 8void main_loop { 9 while (1) { 10 /// Blah 11 cx += 5; 12 cy += 5; 13 draw_character(); 14 } 15}

aniquilator

In your code, in your function , draw_character(), you lod the bitmap every time.
This isn't wise and will populate your game with memory leaks.

#SelectExpand
1void draw_character() 2{ 3 ALLEGRO_BITMAP *layer; 4 layer = al_load_bitmap("Sprites/FFT1/21.bmp"); 5 al_convert_mask_to_alpha(layer, (al_map_rgb(255, 0, 255))); 6 al_draw_bitmap(layer, 0,0,0); 7} 8//create a function that will loads yout sprites, and them draw them 9void load_character(ALLEGRO_BITMAP* character) 10{ 11 character = al_load_bitmap("Sprites/FFT1/21.bmp"); 12 if(character != NULL) 13 { 14 al_convert_mask_to_alpha(character, (al_map_rgb(255, 0, 255))); 15 } 16 else 17 { 18 printf("error loading the char\n"); 19 } 20} 21void draw_character(ALLEGRO_BITMAP* character) 22{ 23 al_draw_bitmap(character, 0,0,0); 24} 25void destroy_char(ALLEGRO_BITMAP* character) 26{ 27 //destroy it 28}

Its just some tips, of couse you would llike to load all characters sprites in the load function, and destroy all in the destroy function. ;)

Jefferson Almeida

"I'm trying to figure out why it happens

http://i52.tinypic.com/dcwm7o.jpg"

EDIT 1: The first question I fix with "al_clear_to_color...." Thanks!

If I want to put three sprites to change as the character moves, I can create a simple animation of the three images and put to animate if the condition is = move? or has an easier way?

aniquilator

To animate, you will have to load all the char sprites, and you can put themm all in a vector, and access them by the index of the frame you want to show.
for example:

#SelectExpand
1std::vector<ALLEGRO_BITMAP*> sprites; 2sprites.push_back(al_load_bitmap... ); 3sprites.push_back(al_load_bitmap... ); 4sprites.push_back(al_load_bitmap... ); 5 6float frame = 0; 7int lastFrame = sprites.size(); 8 9while(1) 10{ 11 //logic 12 al_draw_ ... (sprites[(int)frame]); 13 frame+= 0.5;//the less is this value , the slower is the animation 14 if((int)frame >= lastFrame) 15 frame = 0; 16}

Thats the basic i think.
PS: std::vector is a c++ class, and you have to include: #include<vector>

Jefferson Almeida

I'm trying this way:

#SelectExpand
1 2int cx = 10; 3int cy = 10; 4 5void draw_character() 6{ 7 std::vector<ALLEGRO_BITMAP*> sprites; 8 sprites.push_back(al_load_bitmap("Sprites/FFT1/21.bmp")); 9 sprites.push_back(al_load_bitmap("Sprites/FFT1/22.bmp")); 10 sprites.push_back(al_load_bitmap("Sprites/FFT1/23.bmp")); 11 float frame = 0; 12 int lastFrame = sprites.size(); 13 al_convert_mask_to_alpha(sprites[(int)frame], (al_map_rgb(255, 0, 255))); 14 al_draw_bitmap(sprites[(int)frame], cx, cy, 0); 15 frame+= 0.5; 16 if((int)frame >= lastFrame) 17 frame = 0; 18} 19... frame++;

When I get back I'll see if I can fix it!

EDIT 1: I managed to animate, now I'm trying to change of
picture the every move!

Trent Gamblin

You have to erase what you've drawn previously (by drawing the scene or just clearing to black for testing) then draw everything again.

Jefferson Almeida

  ...
  std::vector<ALLEGRO_BITMAP*> sprites;
  sprites.push_back(al_load_bitmap("Sprites/FFT1/21.bmp"));
  sprites.push_back(al_load_bitmap("Sprites/FFT1/22.bmp"));
  sprites.push_back(al_load_bitmap("Sprites/FFT1/23.bmp"));
  ...

I was trying to use the code that load the images off the "void" to separate the parts that loads the images for not have to load always, but after of the third move with the character... my program give error when I do that!

Trent Gamblin

Do you have new code? I can't see how that's happening with your last paste.

Jefferson Almeida

My code...

#SelectExpand
1/* Test */ 2 3int cx = 10; 4int cy = 10; 5 6std::vector<ALLEGRO_BITMAP*> sprites; 7float frame = 0; 8 9 10void draw_character() 11{ 12 sprites.push_back(al_load_bitmap("Sprites/FFT1/21.bmp")); 13 sprites.push_back(al_load_bitmap("Sprites/FFT1/22.bmp")); 14 sprites.push_back(al_load_bitmap("Sprites/FFT1/23.bmp")); 15 int lastFrame = sprites.size(); 16 al_convert_mask_to_alpha(sprites[(int)frame], (al_map_rgb(255, 0, 255))); 17 al_draw_bitmap(sprites[(int)frame], cx, cy, 0); 18 frame+= 0.0; 19 if((int)frame >= lastFrame) 20 frame = 0; 21} 22 23 24static void main_loop(void) 25{ 26 27 ALLEGRO_EVENT ev; 28 while (true) { 29 if (al_event_queue_is_empty(event_queue)) { 30 /* Test */ 31 draw_character(); 32 al_flip_display(); 33 } 34 al_wait_for_event(event_queue, &ev); 35 switch (ev.type) 36 { 37 case ALLEGRO_EVENT_DISPLAY_CLOSE: 38 return; 39 break; 40 case ALLEGRO_EVENT_KEY_DOWN: 41 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) { 42 cx -= 5; 43 cy -= 5; 44 } 45 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 46 cx += 5; 47 cy += 5; 48 frame++; 49 } 50 else if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 51 return; 52 break; 53 case ALLEGRO_EVENT_KEY_CHAR: 54 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) 55 /* Test, just to compile */ 56 draw_character(); 57 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) 58 /* Test, just to compile */ 59 draw_character(); 60 else if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 61 return; 62 break; 63 case ALLEGRO_EVENT_TIMER: 64 /* Future Update */ 65 //update(); 66 break; 67 } 68 69 al_clear_to_color(al_map_rgb(0,0,0)); 70 } 71} 72 73 74int main(int argc , char** argv) 75{ 76 if(!al_init()) { 77 fprintf(stderr, "Failed al_init"); 78 return -1; 79 } 80 if(!al_init_primitives_addon()) { 81 fprintf(stderr, "Failed to initialize Addon primitives!\n"); 82 return -1; 83 } 84 al_init_font_addon(); 85 al_init_ttf_addon(); 86 if(!al_init_image_addon()) { 87 fprintf(stderr, "Failed to initialize Image addon!\n"); 88 return -1; 89 } 90 if(!al_install_mouse()) { 91 fprintf(stderr, "Failed to initialize Mouse!\n"); 92 return -1; 93 } 94 if(!al_install_keyboard()) { 95 fprintf(stderr, "Failed to initialize Keyboard!\n"); 96 return -1; 97 } 98 if(!al_install_audio()) { 99 fprintf(stderr, "failed to initialize audio!\n"); 100 return -1; 101 } 102 if(!al_init_acodec_addon()) { 103 fprintf(stderr, "failed to initialize audio codecs!\n"); 104 return -1; 105 } 106 if(!al_reserve_samples(1)) { 107 fprintf(stderr, "failed to reserve samples!\n"); 108 return -1; 109 } 110 timer = al_create_timer(1.0 / FPS); 111 if(!timer) { 112 fprintf(stderr, "Failed to created timer!\n"); 113 return -1; 114 } 115 font = al_load_ttf_font("DejaVuSans.ttf", 15, 0); 116 if(!font) { 117 fprintf(stderr, "Failed to load font!\n"); 118 return -1; 119 } 120 121 al_set_target_bitmap(al_get_backbuffer(display)); 122 123 event_queue = al_create_event_queue(); 124 if(!event_queue) { 125 fprintf(stderr, "Failed to create event_queue!\n"); 126 return -1; 127 } 128 test(); 129 graphics(); 130 //load_character(); 131 //create_layers(); 132 display = al_create_display(SCREEN_W, SCREEN_H); 133 134 al_play_sample(sample, 1.0, 0.0,1.0,ALLEGRO_PLAYMODE_LOOP,NULL); 135 136 al_register_event_source(event_queue, al_get_display_event_source(display)); 137 138 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 139 140 al_register_event_source(event_queue, al_get_keyboard_event_source()); 141 142 al_register_event_source(event_queue, al_get_mouse_event_source()); 143 144 al_flip_display(); 145 146 al_get_timer_count(timer); 147 148 al_start_timer(timer); 149 150 main_loop(); 151 152 al_destroy_bitmap(sprites[(int)frame]); 153 154 return 0; 155}

and I tried to do:

#SelectExpand
1 2static void main_loop(void) 3{ 4 5 ALLEGRO_EVENT ev; 6 sprites.push_back(al_load_bitmap("Sprites/FFT1/21.bmp")); 7 sprites.push_back(al_load_bitmap("Sprites/FFT1/22.bmp")); 8 sprites.push_back(al_load_bitmap("Sprites/FFT1/23.bmp")); 9 int lastFrame = sprites.size(); 10 while (true) { 11 if (al_event_queue_is_empty(event_queue)) { 12 /* Test */ 13 al_convert_mask_to_alpha(sprites[(int)frame], (al_map_rgb(255, 0, 255))); 14 al_draw_bitmap(sprites[(int)frame], cx, cy, 0); 15 frame+= 0.0; 16 if((int)frame >= lastFrame) 17 frame = 0; 18 //draw_character(); 19 al_flip_display(); 20 }

*The indentation is correct?

Edgar Reynaldo

The first code you posted is not good code. You load three images every time you draw your character.

Only use al_convert_mask_to_alpha once for each sprite that needs it, not every time you draw it.

The indentation is still not totally right :

  ALLEGRO_EVENT ev;
    sprites.push_back(al_load_bitmap("Sprites/FFT1/21.bmp"));

Both lines should be at the same indentation level :

   ALLEGRO_EVENT ev;
   sprites.push_back(al_load_bitmap("Sprites/FFT1/21.bmp"));

Jefferson Almeida

Hi... when I separate the images that I have to load of the my "void draw_character..." the my program hangs in the third movement!

**The indentation is correct in my code: blocks, but when I post here some parts stay crooked and i dont know why.**

#SelectExpand
1/* Test */ 2 3int cx = 10; 4int cy = 10; 5std::vector<ALLEGRO_BITMAP*> sprites; 6float frame = 0; 7 8void draw_character(void) 9{ 10 11 al_draw_bitmap(sprites[(int)frame], cx, cy, 0); 12 13} 14 15 16void update(void) 17{ 18 ALLEGRO_KEYBOARD_STATE state; 19 al_get_keyboard_state(&state); 20 if (al_key_down(&state, ALLEGRO_KEY_DOWN)) { 21 int lastFrame = sprites.size(); 22 frame+= 0.0; 23 if((int)frame >= lastFrame) 24 frame = 0; 25 } 26} 27 28static void main_loop(void) 29{ 30 ALLEGRO_EVENT ev; 31 while (true) { 32 if (al_event_queue_is_empty(event_queue)) { 33 draw_character(); 34 al_flip_display(); 35 } 36 al_wait_for_event(event_queue, &ev); 37 switch (ev.type) 38 { 39 case ALLEGRO_EVENT_DISPLAY_CLOSE: 40 return; 41 break; 42 case ALLEGRO_EVENT_KEY_DOWN: 43 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) { 44 cx -= 5; 45 cy -= 5; 46 break; 47 } 48 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 49 cx += 5; 50 cy += 5; 51 frame++; 52 break; 53 } 54 else if (ev.keyboard.keycode == ALLEGRO_KEY_RIGHT) { 55 cx += 5; 56 cy ++; 57 break; 58 } 59 else if (ev.keyboard.keycode == ALLEGRO_KEY_LEFT) { 60 cx -= 5; 61 cy --; 62 break; 63 } 64 else if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 65 return; 66 break; 67 case ALLEGRO_EVENT_KEY_CHAR: 68 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) 69 draw_character(); 70 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) 71 draw_character(); 72 else if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 73 return; 74 break; 75 case ALLEGRO_EVENT_TIMER: 76 /* Future Update */ 77 update(); 78 break; 79 } 80 81 al_clear_to_color(al_map_rgb(0,0,0)); 82 } 83}

#SelectExpand
1int main(int argc , char** argv) 2{ 3 if(!al_init()) { 4 fprintf(stderr, "Failed al_init"); 5 return -1; 6 } 7 if(!al_init_primitives_addon()) { 8 fprintf(stderr, "Failed to initialize Addon primitives!\n"); 9 return -1; 10 } 11 al_init_font_addon(); 12 al_init_ttf_addon(); 13 if(!al_init_image_addon()) { 14 fprintf(stderr, "Failed to initialize Image addon!\n"); 15 return -1; 16 } 17 if(!al_install_mouse()) { 18 fprintf(stderr, "Failed to initialize Mouse!\n"); 19 return -1; 20 } 21 if(!al_install_keyboard()) { 22 fprintf(stderr, "Failed to initialize Keyboard!\n"); 23 return -1; 24 } 25 if(!al_install_audio()) { 26 fprintf(stderr, "failed to initialize audio!\n"); 27 return -1; 28 } 29 if(!al_init_acodec_addon()) { 30 fprintf(stderr, "failed to initialize audio codecs!\n"); 31 return -1; 32 } 33 if(!al_reserve_samples(1)) { 34 fprintf(stderr, "failed to reserve samples!\n"); 35 return -1; 36 } 37 timer = al_create_timer(1.0 / FPS); 38 if(!timer) { 39 fprintf(stderr, "Failed to created timer!\n"); 40 return -1; 41 } 42 font = al_load_ttf_font("DejaVuSans.ttf", 15, 0); 43 if(!font) { 44 fprintf(stderr, "Failed to load font!\n"); 45 return -1; 46 } 47 48 al_set_target_bitmap(al_get_backbuffer(display)); 49 50 event_queue = al_create_event_queue(); 51 if(!event_queue) { 52 fprintf(stderr, "Failed to create event_queue!\n"); 53 return -1; 54 } 55 //test(); 56 graphics(); 57 /* Test with character frames */ 58 sprites.push_back(al_load_bitmap("Sprites/FFT1/21.bmp")); 59 sprites.push_back(al_load_bitmap("Sprites/FFT1/22.bmp")); 60 sprites.push_back(al_load_bitmap("Sprites/FFT1/23.bmp")); 61 62 display = al_create_display(SCREEN_W, SCREEN_H); 63 64 al_play_sample(sample, 1.0, 0.0,1.0,ALLEGRO_PLAYMODE_LOOP,NULL); 65 66 al_register_event_source(event_queue, al_get_display_event_source(display)); 67 68 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 69 70 al_register_event_source(event_queue, al_get_keyboard_event_source()); 71 72 al_register_event_source(event_queue, al_get_mouse_event_source()); 73 74 al_flip_display(); 75 76 al_get_timer_count(timer); 77 78 al_start_timer(timer); 79 80 main_loop(); 81 82 al_destroy_bitmap(sprites[(int)frame]); 83 84 return 0; 85}

Edgar Reynaldo

*The indentation is correct in my code: blocks, but when I post here some parts stay crooked and i dont know why.*

Are you mixing tabs with spaces? Use one or the other, but never both.

Você está misturando as guias com os espaços? Use um ou outro, mas nunca ambos.

Jefferson Almeida said:

void update(void)
{


if (al_key_down(&state, ALLEGRO_KEY_DOWN)) {
int lastFrame = sprites.size();
frame+= 0.0;
if((int)frame >= lastFrame) frame = 0; } }

Don't mix ALLEGRO_EVENT_KEY_DOWN with ALLEGRO_KEYBOARD_STATE - use one or the other. In your case, I would just use the ALLEGRO_KEYBOARD_STATE, and check that during the timer event :

Não misture com ALLEGRO_EVENT_KEY_DOWN ALLEGRO_KEYBOARD_STATE - use um ou outro. No seu caso, gostaria apenas de usar o ALLEGRO_KEYBOARD_STATE, e verificar que, durante o evento timer :

   if (ev.type == ALLEGRO_EVENT_TIMER) {
      ALLEGRO_KEYBOARD_STATE state;
      al_get_keyboard_state(&state);
      if (al_key_down(&state , ALLEGRO_KEY_DOWN)) {
         ++frame;
         if ((size_t)frame >= sprites.size()) {
            frame -= (float)(sprites.size() - 1);
         }
      }
      else if (al_key_down(&state , ALLEGRO_KEY_UP)) {
         ///
      }
      else if (...) {}
   }

The reason your code is failing now is because you only correct an out of bounds 'frame' variable when the timer ticks. You could have an ALLEGRO_EVENT_KEY_DOWN event just after a timer tick incrementing frames to 3.0 and then access (int)3.0 in your sprites array, which is out of bounds.

O motivo é o seu código não é agora, porque você só corrigir uma variável fora do 'frame' limites quando o cronômetro carrapatos. Você poderia ter um evento ALLEGRO_EVENT_KEY_DOWN logo após um timer tick quadros incremento de 3,0 e, em seguida, (int) Access 3.0 em sua matriz sprites, que está fora dos limites.

Jefferson Almeida

Hi... Firstly, thank you! I fix the "update" as you show me , I'm thinking in a solution for animation now, when I'm moving my character... still give error in the third movement, I'm to look for what you said about "frame".

EDIT1: When this party is separated of the function that draw give the error, but a time loaded the images should be stored without the need to reload... I think!

...
    sprites.push_back(al_load_bitmap("Sprites/FFT1/21.bmp"));
    sprites.push_back(al_load_bitmap("Sprites/FFT1/22.bmp"));
    sprites.push_back(al_load_bitmap("Sprites/FFT1/23.bmp"));
...

EDIT 2: I think this is wrong, but it's the only way I could make it work.

#SelectExpand
1void load() 2{ 3 sprites.push_back(al_load_bitmap("Sprites/FFT1/21.bmp")); 4 sprites.push_back(al_load_bitmap("Sprites/FFT1/22.bmp")); 5 sprites.push_back(al_load_bitmap("Sprites/FFT1/23.bmp")); 6 spritesr.push_back(al_load_bitmap("Sprites/FFT1/61.bmp")); 7 spritesr.push_back(al_load_bitmap("Sprites/FFT1/62.bmp")); 8 spritesr.push_back(al_load_bitmap("Sprites/FFT1/63.bmp")); 9 10} 11 12void update(void) 13{ 14 load(); 15 if (ev.type == ALLEGRO_EVENT_TIMER) { 16 ALLEGRO_KEYBOARD_STATE state; 17 al_get_keyboard_state(&state); 18 if (al_key_down(&state , ALLEGRO_KEY_DOWN)) { 19 ++frame; 20 if ((size_t)frame >= sprites.size()) { 21 frame -= (float)(sprites.size() - 1); 22 } 23 } 24 else if (al_key_down(&state , ALLEGRO_KEY_UP)) { 25 ++frame; 26 if ((size_t)frame >= sprites.size()) { 27 frame -= (float)(sprites.size() - 1); 28 } 29 } 30 } 31}

Edgar Reynaldo

Don't load during update. Only load your images once.

            ++frame;
            if ((size_t)frame >= sprites.size()) {
                frame -= (float)(sprites.size() - 1);
            }

Let me make a correction - I gave you the wrong code earlier - it should be :

   frame += inc;// inc must be in the range [0.0 , sprites.size() )
   if (frame >= (float)sprites.size()) {
      frame -= (float)sprites.size();
   }

The 'inc' variable is a floating point increment to let you change the frame by less than one. Set it to whatever works for you.

Jefferson Almeida

Hi, I updated the code how you said, but still give the same error.

http://i53.tinypic.com/2irkkrs.jpg

Edgar Reynaldo

I can't keep guessing what is wrong. Either post your latest full code, or learn how to use a debugger.

You're probably accessing an element outside the boundaries of the vector again. Check for that first.

Jefferson Almeida

My last code:

/* Test */

int cx = 10;
int cy = 10;
int inc = 0.0;
float frame = 0;
std::vector<ALLEGRO_BITMAP*> sprites;

Draw Character:

void draw_character()
{
    al_convert_mask_to_alpha(sprites[(int)frame], (al_map_rgb(255, 0, 255)));
    al_draw_bitmap(sprites[(int)frame], cx, cy, 0);

}

Update:

#SelectExpand
1void update(void) 2{ 3 if (ev.type == ALLEGRO_EVENT_TIMER) { 4 ALLEGRO_KEYBOARD_STATE state; 5 al_get_keyboard_state(&state); 6 if (al_key_down(&state , ALLEGRO_KEY_DOWN)) { 7 frame += inc, sprites.size(); 8 if (frame >= (float)sprites.size()) { 9 frame -= (float)sprites.size(); 10 } 11 } 12 else if (al_key_down(&state , ALLEGRO_KEY_RIGHT)) { 13 frame += inc; 14 if (frame >= (float)sprites.size()) { 15 frame -= (float)sprites.size(); 16 } 17 } 18 else if (al_key_down(&state , ALLEGRO_KEY_UP)) { 19 frame += inc; 20 if (frame >= (float)sprites.size()) { 21 frame -= (float)sprites.size(); 22 } 23 } 24 } 25}

Main loop:

#SelectExpand
1static void main_loop(void) 2{ 3 ALLEGRO_EVENT ev; 4 while (true) { 5 if (al_event_queue_is_empty(event_queue)) { 6 draw_character(); 7 al_flip_display(); 8 al_clear_to_color(al_map_rgb(0,0,0)); 9 //map_draw(); 10 } 11 al_wait_for_event(event_queue, &ev); 12 switch (ev.type) 13 { 14 case ALLEGRO_EVENT_DISPLAY_CLOSE: 15 return; 16 break; 17 case ALLEGRO_EVENT_KEY_DOWN: 18 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) { 19 cx -= 5; 20 cy -= 5; 21 frame++; 22 break; 23 } 24 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 25 cx += 5; 26 cy += 5; 27 frame++; 28 break; 29 } 30 else if (ev.keyboard.keycode == ALLEGRO_KEY_RIGHT) { 31 cx += 5; 32 cy ++; 33 frame++; 34 break; 35 } 36 else if (ev.keyboard.keycode == ALLEGRO_KEY_LEFT) { 37 cx -= 5; 38 cy --; 39 frame++; 40 break; 41 } 42 else if (ev.keyboard.keycode == ALLEGRO_KEY_F1) { 43 al_draw_bitmap(menuedit, 200, 100, 0); 44 al_flip_display(); 45 } 46 else if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 47 return; 48 break; 49 case ALLEGRO_EVENT_KEY_CHAR: 50 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) 51 draw_character(); 52 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) 53 draw_character(); 54 else if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 55 return; 56 break; 57 case ALLEGRO_EVENT_TIMER: 58 /* Future Update */ 59 update(); 60 break; 61 } 62 } 63}

Main:

#SelectExpand
1int main(int argc , char** argv) 2{ 3 if(!al_init()) { 4 fprintf(stderr, "Failed al_init"); 5 return -1; 6 } 7 if(!al_init_primitives_addon()) { 8 fprintf(stderr, "Failed to initialize Addon primitives!\n"); 9 return -1; 10 } 11 al_init_font_addon(); 12 al_init_ttf_addon(); 13 if(!al_init_image_addon()) { 14 fprintf(stderr, "Failed to initialize Image addon!\n"); 15 return -1; 16 } 17 if(!al_install_mouse()) { 18 fprintf(stderr, "Failed to initialize Mouse!\n"); 19 return -1; 20 } 21 if(!al_install_keyboard()) { 22 fprintf(stderr, "Failed to initialize Keyboard!\n"); 23 return -1; 24 } 25 if(!al_install_audio()) { 26 fprintf(stderr, "failed to initialize audio!\n"); 27 return -1; 28 } 29 if(!al_init_acodec_addon()) { 30 fprintf(stderr, "failed to initialize audio codecs!\n"); 31 return -1; 32 } 33 if(!al_reserve_samples(1)) { 34 fprintf(stderr, "failed to reserve samples!\n"); 35 return -1; 36 } 37 timer = al_create_timer(1.0 / FPS); 38 if(!timer) { 39 fprintf(stderr, "Failed to created timer!\n"); 40 return -1; 41 } 42 font = al_load_ttf_font("DejaVuSans.ttf", 15, 0); 43 if(!font) { 44 fprintf(stderr, "Failed to load font!\n"); 45 return -1; 46 } 47 48 al_set_target_bitmap(al_get_backbuffer(display)); 49 50 event_queue = al_create_event_queue(); 51 if(!event_queue) { 52 fprintf(stderr, "Failed to create event_queue!\n"); 53 return -1; 54 } 55 //test(); 56 //create_layers(); 57 graphics(); 58 sprites.push_back(al_load_bitmap("Sprites/FFT1/21.bmp")); 59 sprites.push_back(al_load_bitmap("Sprites/FFT1/22.bmp")); 60 sprites.push_back(al_load_bitmap("Sprites/FFT1/23.bmp")); 61 62 display = al_create_display(SCREEN_W, SCREEN_H); 63 64 al_play_sample(sample, 1.0, 0.0,1.0,ALLEGRO_PLAYMODE_LOOP,NULL); 65 66 al_register_event_source(event_queue, al_get_display_event_source(display)); 67 68 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 69 70 al_register_event_source(event_queue, al_get_keyboard_event_source()); 71 72 al_register_event_source(event_queue, al_get_mouse_event_source()); 73 74 al_flip_display(); 75 76 al_get_timer_count(timer); 77 78 al_start_timer(timer); 79 80 main_loop(); 81 82 al_destroy_bitmap(sprites[(int)frame]); 83 84 return 0; 85}

Edgar Reynaldo

Main loop :

      case ALLEGRO_EVENT_KEY_DOWN:
          if (ev.keyboard.keycode == ALLEGRO_KEY_UP) {
              cx -= 5;
              cy -= 5;
frame++;
break; }

You're still mixing ALLEGRO_EVENT_KEY_DOWN with al_key_down, and you're not checking the bounds of your sprites vector when you modify 'frame'.

Also, you're still converting your bitmap every time you draw it - only convert it once when you load it.

Você ainda está com a mistura ALLEGRO_EVENT_KEY_DOWN al_key_down, e você não está verificando os limites do seu vetor sprites quando você modifica 'frame'.

Além disso, você ainda converter o bitmap de cada vez que desenhá-la - só convertê-lo uma vez quando você carregá-lo.

It might help simplify things if you tried out my basic animation class :
animation class

Then your setup code would look like this :

#SelectExpand
1 const int NUM_SPRITES = 3; 2 const char* sprite_files[NUM_SPRITES] = { 3 "Sprites/FFT1/21.bmp", 4 "Sprites/FFT1/22.bmp", 5 "Sprites/FFT1/23.bmp" 6 }; 7 8 for (int i = 0 ; i < NUM_SPRITES ; ++i) { 9 ALLEGRO_BITMAP* bmp = al_load_bitmap(sprite_files[i]); 10 if (!bmp) { 11 printf("Error loading %s\n" , sprite_files[i]); 12 return 1; 13 } 14 al_convert_mask_to_alpha(bmp, (al_map_rgb(255, 0, 255))); 15 sprites.push_back(bmp); 16 } 17 18 Animation anime(sprites.size() , 1.0); 19 for (int i = 0 ; i < NUM_SPRITES ; ++i) { 20 anime.SetBitmap(i , sprites[i]); 21 }

And you would use it like this :

   if (ev.type == ALLEGRO_EVENT_TIMER) {
      anime.AdvanceFrameTime(1.0/FPS);
      redraw = true;
   }

//  ......

   if (redraw) {
      clear_to_color(al_map_rgb(0,0,0));
      anime.Draw(character_x , character_y);
      al_flip_display();
      redraw = false;
   }

Jefferson Almeida

Well... I'm trying to use the animation class but I no have slightest idea where will every thing.
The setup code will inside of main?

Edgar Reynaldo

Yes, the setup code would go in main, after you initialize allegro and the image addon and create a display.

Jefferson Almeida

Hi, again
http://www.allegro.cc/forums/thread/607529/920236#target

...
      try {
         frames = new ALLEGRO_BITMAP*[framecount];
      }
      catch {
         frames = 0;
         return false;
      }
      num_frames = framecount;
   }
...

That would be "catch(Animation) {..." ?

Edgar Reynaldo

No, it should have been :

      try {
         frames = new ALLEGRO_BITMAP*[framecount];
      }
catch (...) {
frames = 0; return false; } num_frames = framecount;

Jefferson Almeida

Theoretically it would be something more or less so?

#SelectExpand
1 2int cx = 10; 3int cy = 10; 4 5std::vector<ALLEGRO_BITMAP*> sprites; 6 7class Animation { 8private : 9 ALLEGRO_BITMAP** frames; 10 double duration; 11 double time_passed; 12 int frame_number; 13 int num_frames; 14public : 15 Animation() : 16 frames(0), 17 duration(0.0), 18 time_passed(0.0), 19 frame_number(0), 20 num_frames(0) 21 {} 22 Animation(int framecount , double time_length) : 23 frames(0), 24 duration(0.0), 25 time_passed(0.0), 26 frame_number(0), 27 num_frames(0) 28 { 29 Reallocate(framecount , time_length); 30 } 31 ~Animation() {Free();} 32 void Free() { 33 if (frames) {delete [] frames;frames = 0;} 34 num_frames = 0; 35 } 36 bool Reallocate(int framecount , double time_length) { 37 if (framecount < 1) {return false;} 38 if (time_length <= 0.0) {return false;} 39 Free(); 40 duration = time_length; 41 time_passed = 0.0; 42 frame_number = 0; 43 try { 44 frames = new ALLEGRO_BITMAP*[framecount]; 45 } 46 catch(...) { 47 frames = 0; 48 return false; 49 } 50 num_frames = framecount; 51 } 52 53 void SetBitmap(int index , ALLEGRO_BITMAP* bmp) { 54 assert((index >= 0) && (index < num_frames)); 55 frames[index] = bmp; 56 } 57 58 void AdvanceFrameTime(double delta_time) { 59 SetFrameTime(time_passed + delta_time); 60 } 61 void SetFrameTime(double frame_time) { 62 // simple forward repeating animation 63 time_passed = frame_time; 64 while (time_passed >= duration) {time_passed -= duration;} 65 while (time_passed < 0.0) {time_passed += duration;} 66 frame_number = (int)(time_passed / duration); 67 // shouldn't be necessary, but just in case 68 if (frame_number < 0) {frame_number = 0;} 69 if (frame_number >= num_frames) {frame_number = num_frames - 1;} 70 } 71 72 void Draw(int cx , int cy) { 73 al_draw_bitmap(frames[frame_number] , cx , cy , 0); 74 } 75 76}; 77 78int main(int argc , char** argv) 79{ 80 if(!al_init()) { 81 fprintf(stderr, "Failed al_init"); 82 return -1; 83 } 84 if(!al_init_primitives_addon()) { 85 fprintf(stderr, "Failed to initialize Addon primitives!\n"); 86 return -1; 87 } 88 al_init_font_addon(); 89 al_init_ttf_addon(); 90 if(!al_init_image_addon()) { 91 fprintf(stderr, "Failed to initialize Image addon!\n"); 92 return -1; 93 } 94 if(!al_install_mouse()) { 95 fprintf(stderr, "Failed to initialize Mouse!\n"); 96 return -1; 97 } 98 if(!al_install_keyboard()) { 99 fprintf(stderr, "Failed to initialize Keyboard!\n"); 100 return -1; 101 } 102 if(!al_install_audio()) { 103 fprintf(stderr, "failed to initialize audio!\n"); 104 return -1; 105 } 106 if(!al_init_acodec_addon()) { 107 fprintf(stderr, "failed to initialize audio codecs!\n"); 108 return -1; 109 } 110 if(!al_reserve_samples(1)) { 111 fprintf(stderr, "failed to reserve samples!\n"); 112 return -1; 113 } 114 timer = al_create_timer(1.0 / FPS); 115 if(!timer) { 116 fprintf(stderr, "Failed to created timer!\n"); 117 return -1; 118 } 119 font = al_load_ttf_font("DejaVuSans.ttf", 15, 0); 120 if(!font) { 121 fprintf(stderr, "Failed to load font!\n"); 122 return -1; 123 } 124 125 al_set_target_bitmap(al_get_backbuffer(display)); 126 127 event_queue = al_create_event_queue(); 128 if(!event_queue) { 129 fprintf(stderr, "Failed to create event_queue!\n"); 130 return -1; 131 } 132 133 display = al_create_display(SCREEN_W, SCREEN_H); 134 135 const int NUM_SPRITES = 3; 136 const char* sprite_files[NUM_SPRITES] = { 137 "Sprites/FFT1/21.bmp", 138 "Sprites/FFT1/22.bmp", 139 "Sprites/FFT1/23.bmp" 140 }; 141 for (int i = 0 ; i < NUM_SPRITES ; ++i) { 142 ALLEGRO_BITMAP* bmp = al_load_bitmap(sprite_files[i]); 143 if (!bmp) { 144 printf("Error loading %s\n" , sprite_files[i]); 145 return 1; 146 } 147 al_convert_mask_to_alpha(bmp, (al_map_rgb(255, 0, 255))); 148 sprites.push_back(bmp); 149 } 150 Animation anime(sprites.size() , 1.0); 151 for (int i = 0 ; i < NUM_SPRITES ; ++i) { 152 anime.SetBitmap(i , sprites[i]); 153 } 154 155 al_play_sample(sample, 1.0, 0.0,1.0,ALLEGRO_PLAYMODE_LOOP,NULL); 156 157 al_register_event_source(event_queue, al_get_display_event_source(display)); 158 159 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 160 161 al_register_event_source(event_queue, al_get_keyboard_event_source()); 162 163 al_register_event_source(event_queue, al_get_mouse_event_source()); 164 165 al_flip_display(); 166 167 al_get_timer_count(timer); 168 169 al_start_timer(timer); 170 171 ALLEGRO_EVENT ev; 172 bool redraw = true; 173 bool doexit = false; 174 while (true) { 175 if (al_event_queue_is_empty(event_queue)) { 176 anime.Draw(cx , cy); 177 al_flip_display(); 178 al_clear_to_color(al_map_rgb(0,0,0)); 179 } 180 al_wait_for_event(event_queue, &ev); 181 switch (ev.type) 182 { 183 case ALLEGRO_EVENT_DISPLAY_CLOSE: 184 doexit = true; 185 break; 186 case ALLEGRO_EVENT_KEY_DOWN: 187 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) { 188 cx -= 5; 189 cy -= 5; 190 //frame++; 191 break; 192 } 193 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 194 cx += 5; 195 cy += 5; 196 //frame++; 197 break; 198 } 199 else if (ev.keyboard.keycode == ALLEGRO_KEY_RIGHT) { 200 cx += 5; 201 cy ++; 202 //frame++; 203 break; 204 } 205 else if (ev.keyboard.keycode == ALLEGRO_KEY_LEFT) { 206 cx -= 5; 207 cy --; 208 //frame++; 209 break; 210 } 211 else if (ev.keyboard.keycode == ALLEGRO_KEY_F1) { 212 al_draw_bitmap(menuedit, 200, 100, 0); 213 al_flip_display(); 214 } 215 else if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 216 doexit = true; 217 break; 218 case ALLEGRO_EVENT_KEY_CHAR: 219 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) 220 anime.Draw(cx , cy); 221 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) 222 anime.Draw(cx , cy); 223 else if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 224 doexit = true; 225 break; 226 case ALLEGRO_EVENT_TIMER: 227 if (ev.type == ALLEGRO_EVENT_TIMER) { 228 anime.AdvanceFrameTime(1.0/FPS); 229 redraw = true; 230 } 231 if (redraw) { 232 al_clear_to_color(al_map_rgb(0,0,0)); 233 anime.Draw(cx , cy); 234 al_flip_display(); 235 redraw = false; 236 } 237 238 } 239 } 240}

Edgar Reynaldo

Not quite - redraw goes outside of the event loop, and you shouldn't draw during your logic (you do it in the ALLEGRO_EVENT_KEY_CHAR check). Always separate logic from drawing.

Não é bem assim - redesenhar vai para fora do ciclo de eventos, e você não deve chamar durante a sua lógica (que fazê-lo na seleção ALLEGRO_EVENT_KEY_CHAR). Sempre lógica separada do desenho.

Jefferson Almeida

Now is almost 04:00 in Brazil and I'm totally lost, sleep will not let me think straight, I go to bed and when I wake up I try to solve it, thanks a lot!

Edgar Reynaldo

Let me know how it goes.

Jefferson Almeida

Here, my last code:

#SelectExpand
1int cx = 10; 2int cy = 10; 3 4std::vector<ALLEGRO_BITMAP*> sprites; 5 6class Animation { 7private : 8 ALLEGRO_BITMAP** frames; 9 double duration; 10 double time_passed; 11 int frame_number; 12 int num_frames; 13public : 14 Animation() : 15 frames(0), 16 duration(0.0), 17 time_passed(0.0), 18 frame_number(0), 19 num_frames(0) 20 {} 21 Animation(int framecount , double time_length) : 22 frames(0), 23 duration(0.0), 24 time_passed(0.0), 25 frame_number(0), 26 num_frames(0) 27 { 28 Reallocate(framecount , time_length); 29 } 30 ~Animation() {Free();} 31 void Free() { 32 if (frames) {delete [] frames;frames = 0;} 33 num_frames = 0; 34 } 35 bool Reallocate(int framecount , double time_length) { 36 if (framecount < 1) {return false;} 37 if (time_length <= 0.0) {return false;} 38 Free(); 39 duration = time_length; 40 time_passed = 0.0; 41 frame_number = 0; 42 try { 43 frames = new ALLEGRO_BITMAP*[framecount]; 44 } 45 catch(...) { 46 frames = 0; 47 return false; 48 } 49 num_frames = framecount; 50 } 51 52 void SetBitmap(int index , ALLEGRO_BITMAP* bmp) { 53 assert((index >= 0) && (index < num_frames)); 54 frames[index] = bmp; 55 } 56 57 void AdvanceFrameTime(double delta_time) { 58 SetFrameTime(time_passed + delta_time); 59 } 60 void SetFrameTime(double frame_time) { 61 // simple forward repeating animation 62 time_passed = frame_time; 63 while (time_passed >= duration) {time_passed -= duration;} 64 while (time_passed < 0.0) {time_passed += duration;} 65 frame_number = (int)(time_passed / duration); 66 // shouldn't be necessary, but just in case 67 if (frame_number < 0) {frame_number = 0;} 68 if (frame_number >= num_frames) {frame_number = num_frames - 1;} 69 } 70 71 void Draw(int cx , int cy) { 72 al_draw_bitmap(frames[frame_number] , cx , cy , 0); 73 } 74 75}; 76 77int main(int argc , char** argv) 78{ 79 if(!al_init()) { 80 fprintf(stderr, "Failed al_init"); 81 return -1; 82 } 83 if(!al_init_primitives_addon()) { 84 fprintf(stderr, "Failed to initialize Addon primitives!\n"); 85 return -1; 86 } 87 al_init_font_addon(); 88 al_init_ttf_addon(); 89 if(!al_init_image_addon()) { 90 fprintf(stderr, "Failed to initialize Image addon!\n"); 91 return -1; 92 } 93 if(!al_install_mouse()) { 94 fprintf(stderr, "Failed to initialize Mouse!\n"); 95 return -1; 96 } 97 if(!al_install_keyboard()) { 98 fprintf(stderr, "Failed to initialize Keyboard!\n"); 99 return -1; 100 } 101 if(!al_install_audio()) { 102 fprintf(stderr, "failed to initialize audio!\n"); 103 return -1; 104 } 105 if(!al_init_acodec_addon()) { 106 fprintf(stderr, "failed to initialize audio codecs!\n"); 107 return -1; 108 } 109 if(!al_reserve_samples(1)) { 110 fprintf(stderr, "failed to reserve samples!\n"); 111 return -1; 112 } 113 timer = al_create_timer(1.0 / FPS); 114 if(!timer) { 115 fprintf(stderr, "Failed to created timer!\n"); 116 return -1; 117 } 118 font = al_load_ttf_font("DejaVuSans.ttf", 15, 0); 119 if(!font) { 120 fprintf(stderr, "Failed to load font!\n"); 121 return -1; 122 } 123 124 al_set_target_bitmap(al_get_backbuffer(display)); 125 126 event_queue = al_create_event_queue(); 127 if(!event_queue) { 128 fprintf(stderr, "Failed to create event_queue!\n"); 129 return -1; 130 } 131 132 display = al_create_display(SCREEN_W, SCREEN_H); 133 134 const int NUM_SPRITES = 3; 135 const char* sprite_files[NUM_SPRITES] = { 136 "Sprites/FFT1/21.bmp", 137 "Sprites/FFT1/22.bmp", 138 "Sprites/FFT1/23.bmp" 139 }; 140 for (int i = 0 ; i < NUM_SPRITES ; ++i) { 141 ALLEGRO_BITMAP* bmp = al_load_bitmap(sprite_files[i]); 142 if (!bmp) { 143 printf("Error loading %s\n" , sprite_files[i]); 144 return -1; 145 } 146 al_convert_mask_to_alpha(bmp, (al_map_rgb(255, 0, 255))); 147 sprites.push_back(bmp); 148 } 149 Animation anime(sprites.size() , 1.0); 150 for (int i = 0 ; i < NUM_SPRITES ; ++i) { 151 anime.SetBitmap(i , sprites[i]); 152 } 153 154 al_play_sample(sample, 1.0, 0.0,1.0,ALLEGRO_PLAYMODE_LOOP,NULL); 155 156 al_register_event_source(event_queue, al_get_display_event_source(display)); 157 158 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 159 160 al_register_event_source(event_queue, al_get_keyboard_event_source()); 161 162 al_register_event_source(event_queue, al_get_mouse_event_source()); 163 164 al_flip_display(); 165 166 al_get_timer_count(timer); 167 168 al_start_timer(timer); 169 170 bool redraw; 171 bool quit; 172 while (!quit) { 173 if(redraw) { 174 al_clear_to_color(al_map_rgb(0,0,0)); 175 anime.Draw(cx , cy); 176 break; 177 } 178 al_flip_display(); 179 redraw = false; 180 } 181 while (1) { 182 ALLEGRO_EVENT ev; 183 if (al_event_queue_is_empty(event_queue)) { 184 anime.Draw(cx , cy); 185 al_flip_display(); 186 al_clear_to_color(al_map_rgb(0,0,0)); 187 } 188 al_wait_for_event(event_queue, &ev); 189 switch (ev.type) 190 { 191 case ALLEGRO_EVENT_DISPLAY_CLOSE: 192 quit = true; 193 break; 194 case ALLEGRO_EVENT_KEY_DOWN: 195 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) { 196 cx -= 5; 197 cy -= 5; 198 //frame++; 199 break; 200 } 201 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 202 cx += 5; 203 cy += 5; 204 //frame++; 205 break; 206 } 207 else if (ev.keyboard.keycode == ALLEGRO_KEY_RIGHT) { 208 cx += 5; 209 cy ++; 210 //frame++; 211 break; 212 } 213 else if (ev.keyboard.keycode == ALLEGRO_KEY_LEFT) { 214 cx -= 5; 215 cy --; 216 //frame++; 217 break; 218 } 219 else if (ev.keyboard.keycode == ALLEGRO_KEY_F1) { 220 al_draw_bitmap(menuedit, 200, 100, 0); 221 al_flip_display(); 222 } 223 else if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 224 quit = true; 225 break; 226 case ALLEGRO_EVENT_KEY_CHAR: 227 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) { 228 cx -= 5; 229 cy -= 5; 230 //frame++; 231 break; 232 } 233 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 234 cx += 5; 235 cy += 5; 236 //frame++; 237 break; 238 } 239 else if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { 240 quit = true; 241 break; 242 } 243 case ALLEGRO_EVENT_TIMER: 244 if (ev.type == ALLEGRO_EVENT_TIMER) { 245 anime.AdvanceFrameTime(1.0/FPS); 246 redraw = true; 247 } 248 } 249 } 250 return 0; 251};

Edgar Reynaldo

    while (!quit) {
        if(redraw) {
            al_clear_to_color(al_map_rgb(0,0,0));
            anime.Draw(cx , cy);
break;
} al_flip_display(); redraw = false; }

Without that break statement, you will be stuck in that loop forever, because quit is always false. With the break statement, you only clear the screen and draw the animation, but don't flip the display.

Your drawing code goes inside your game loop.

Jefferson Almeida

@@"

edit1: So I do not need to do a "if(redraw).." ?

#SelectExpand
1 bool redraw; 2 bool quit; 3 while (1) { 4 ALLEGRO_EVENT ev; 5 if (al_event_queue_is_empty(event_queue)) { 6 anime.Draw(cx , cy); 7 al_flip_display(); 8 al_clear_to_color(al_map_rgb(0,0,0)); 9 } 10 al_wait_for_event(event_queue, &ev); 11 switch (ev.type) 12 { 13 case ALLEGRO_EVENT_DISPLAY_CLOSE: 14 quit = true; 15 break; 16 case ALLEGRO_EVENT_KEY_DOWN: 17 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) { 18 cx -= 5; 19 cy -= 5; 20 //frame++; 21 break; 22 } 23 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 24 cx += 5; 25 cy += 5; 26 break; 27 } 28 else if (ev.keyboard.keycode == ALLEGRO_KEY_RIGHT) { 29 cx += 5; 30 cy ++; 31 //frame++; 32 break; 33 } 34 else if (ev.keyboard.keycode == ALLEGRO_KEY_LEFT) { 35 cx -= 5; 36 cy --; 37 //frame++; 38 break; 39 } 40 else if (ev.keyboard.keycode == ALLEGRO_KEY_F1) { 41 al_draw_bitmap(menuedit, 200, 100, 0); 42 al_flip_display(); 43 } 44 else if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 45 quit = true; 46 break; 47 case ALLEGRO_EVENT_KEY_CHAR: 48 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) { 49 cx -= 5; 50 cy -= 5; 51 //frame++; 52 break; 53 } 54 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 55 cx += 5; 56 cy += 5; 57 frame++; 58 //sprites; 59 break; 60 } 61 else if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { 62 quit = true; 63 break; 64 } 65 case ALLEGRO_EVENT_TIMER: 66 if (ev.type == ALLEGRO_EVENT_TIMER) { 67 anime.AdvanceFrameTime(1.0/FPS); 68 redraw = true; 69 } 70 } 71 } 72 return 0; 73};

Edgar Reynaldo

You don't have to use a redraw flag, but it makes it clearer. Also, it probably looks better if you only redraw when the timer goes off.

Jefferson Almeida

The part of animation is correct?

Edit 1: I can to put the "event timer" and then redraw or is better I to put the timer in a "case" in the end?

#SelectExpand
1 bool redraw; 2 bool quit; 3 while (1) { 4 ALLEGRO_EVENT ev; 5 if (ev.type == ALLEGRO_EVENT_TIMER) { 6 anime.AdvanceFrameTime(1.0/FPS); 7 redraw = true; 8 } 9 if (redraw) { 10 al_clear_to_color(al_map_rgb(0,0,0)); 11 anime.Draw(cx , cy); 12 al_flip_display(); 13 redraw = false; 14 } 15 al_wait_for_event(event_queue, &ev); 16 switch(ev.type) { 17 case ALLEGRO_EVENT_DISPLAY_CLOSE: 18 quit = true; 19 break; 20 case ALLEGRO_EVENT_KEY_DOWN: 21 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) { 22 cx -= 5; 23 cy -= 5; 24 break; 25 } 26 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 27 cx += 5; 28 cy += 5; 29 break; 30 } 31 else if (ev.keyboard.keycode == ALLEGRO_KEY_RIGHT) { 32 cx += 5; 33 cy ++; 34 break; 35 } 36 else if (ev.keyboard.keycode == ALLEGRO_KEY_LEFT) { 37 cx -= 5; 38 cy --; 39 break; 40 } 41 else if (ev.keyboard.keycode == ALLEGRO_KEY_F1) { 42 al_draw_bitmap(menuedit, 200, 100, 0); 43 al_flip_display(); 44 } 45 else if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 46 quit = true; 47 break; 48 case ALLEGRO_EVENT_KEY_CHAR: 49 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) { 50 cx -= 5; 51 cy -= 5; 52 break; 53 } 54 else if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 55 cx += 5; 56 cy += 5; 57 break; 58 } 59 else if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) 60 quit = true; 61 break; 62 //case ALLEGRO_EVENT_TIMER: 63 //if (ev.type == ALLEGRO_EVENT_TIMER) { 64 //anime.AdvanceFrameTime(1.0/FPS); 65 //redraw = true; 66 //break; 67 //} 68 } 69 } 70 return 0; 71}

Edgar Reynaldo

Game loop :

#SelectExpand
1while (!quit) { 2 while (1) ( 3 ALLEGRO_EVENT ev; 4 al_wait_for_event(event_queue , &ev); 5 if (ev.type == BLAH) { 6 7 } 8 else if (ev.type == ALLEGRO_EVENT_TIMER) { 9 anime.AdvanceFrameTime(1.0/FPS); 10 redraw = true; 11 } 12 if (al_is_event_queue_empty(event_queue)) { 13 break; 14 } 15 } 16 if (redraw) { 17 al_clear_to_color(al_map_rgb(0,0,0)); 18 anime.Draw(x,y); 19 al_flip_display(); 20 redraw = false; 21 } 22}

Jefferson Almeida

Look:

#SelectExpand
1 while (!quit) { 2 while (1) { 3 ALLEGRO_EVENT ev; 4 al_wait_for_event(event_queue , &ev); 5 if (ev.type == ALLEGRO_EVENT_KEY_DOWN) { 6 if(ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 7 cx += 5; 8 cy += 5; 9 break; 10 } 11 } 12 else if (ev.type == ALLEGRO_EVENT_TIMER) { 13 anime.AdvanceFrameTime(1.0/FPS); 14 redraw = true; 15 } 16 if (al_is_event_queue_empty(event_queue)) { 17 break; 18 } 19 } 20 if (redraw) { 21 al_clear_to_color(al_map_rgb(0,0,0)); 22 anime.Draw(cx,cy); 23 al_flip_display(); 24 redraw = false; 25 } 26 } 27}

Edgar Reynaldo

It looks fine to me.

So does it work or what?

Jefferson Almeida

Just to know if it was right =D
The animation I have to add anything ?

class of the another topic

#SelectExpand
1class Animation { 2private : 3 ALLEGRO_BITMAP** frames; 4 double duration; 5 double time_passed; 6 int frame_number; 7 int num_frames; 8public : 9 Animation() : 10 frames(0), 11 duration(0.0), 12 time_passed(0.0), 13 frame_number(0), 14 num_frames(0) 15 {} 16 Animation(int framecount , double time_length) : 17 frames(0), 18 duration(0.0), 19 time_passed(0.0), 20 frame_number(0), 21 num_frames(0) 22 { 23 Reallocate(framecount , time_length); 24 } 25 ~Animation() {Free();} 26 void Free() { 27 if (frames) {delete [] frames;frames = 0;} 28 num_frames = 0; 29 } 30 bool Reallocate(int framecount , double time_length) { 31 if (framecount < 1) {return false;} 32 if (time_length <= 0.0) {return false;} 33 Free(); 34 duration = time_length; 35 time_passed = 0.0; 36 frame_number = 0; 37 try { 38 frames = new ALLEGRO_BITMAP*[framecount]; 39 } 40 catch(...) { 41 frames = 0; 42 return false; 43 } 44 num_frames = framecount; 45 } 46 47 void SetBitmap(int index , ALLEGRO_BITMAP* bmp) { 48 assert((index >= 0) && (index < num_frames)); 49 frames[index] = bmp; 50 } 51 52 void AdvanceFrameTime(double delta_time) { 53 SetFrameTime(time_passed + delta_time); 54 } 55 void SetFrameTime(double frame_time) { 56 // simple forward repeating animation 57 time_passed = frame_time; 58 while (time_passed >= duration) {time_passed -= duration;} 59 while (time_passed < 0.0) {time_passed += duration;} 60 frame_number = (int)(time_passed / duration); 61 // shouldn't be necessary, but just in case 62 if (frame_number < 0) {frame_number = 0;} 63 if (frame_number >= num_frames) {frame_number = num_frames - 1;} 64 } 65 66 void Draw(int cx , int cy) { 67 al_draw_bitmap(frames[frame_number] , cx , cy , 0); 68 } 69 70};

code that I put in the main!

#SelectExpand
1... 2 const int NUM_SPRITES = 3; 3 const char* sprite_files[NUM_SPRITES] = { 4 "Sprites/FFT1/21.bmp", 5 "Sprites/FFT1/22.bmp", 6 "Sprites/FFT1/23.bmp" 7 }; 8 for (int i = 0 ; i < NUM_SPRITES ; ++i) { 9 ALLEGRO_BITMAP* bmp = al_load_bitmap(sprite_files[i]); 10 if (!bmp) { 11 printf("Error loading %s\n" , sprite_files[i]); 12 return -1; 13 } 14 al_convert_mask_to_alpha(bmp, (al_map_rgb(255, 0, 255))); 15 sprites.push_back(bmp); 16 } 17 Animation anime(sprites.size() , 1.0); 18 for (int i = 0 ; i < NUM_SPRITES ; ++i) { 19 anime.SetBitmap(i , sprites[i]); 20 } 21...

Edgar Reynaldo

It still looks fine - does it work or not?

Jefferson Almeida

Hi, sorry for delay... I was trying to discover before to ask help!
yeah, My animation no work!

Edit1: Oddly enough... rs... I think this time the indentation are totally right. o_O"

#SelectExpand
1 2int cx = 0; 3int cy = 0; 4float frame = 0; 5std::vector<ALLEGRO_BITMAP*> sprites; 6 7class Animation { 8private : 9 ALLEGRO_BITMAP** frames; 10 double duration; 11 double time_passed; 12 int frame_number; 13 int num_frames; 14public : 15 Animation() : 16 frames(0), 17 duration(0.0), 18 time_passed(0.0), 19 frame_number(0), 20 num_frames(0) 21 {} 22 Animation(int framecount , double time_length) : 23 frames(0), 24 duration(0.0), 25 time_passed(0.0), 26 frame_number(0), 27 num_frames(0) 28 { 29 Reallocate(framecount , time_length); 30 } 31 ~Animation() {Free();} 32 void Free() { 33 if (frames) {delete [] frames;frames = 0;} 34 num_frames = 0; 35 } 36 bool Reallocate(int framecount , double time_length) { 37 if (framecount < 1) {return false;} 38 if (time_length <= 0.0) {return false;} 39 Free(); 40 duration = time_length; 41 time_passed = 0.0; 42 frame_number = 0; 43 try { 44 frames = new ALLEGRO_BITMAP*[framecount]; 45 } 46 catch(...) { 47 frames = 0; 48 return false; 49 } 50 num_frames = framecount; 51 } 52 53 void SetBitmap(int index , ALLEGRO_BITMAP* bmp) { 54 assert((index >= 0) && (index < num_frames)); 55 frames[index] = bmp; 56 } 57 58 void AdvanceFrameTime(double delta_time) { 59 SetFrameTime(time_passed + delta_time); 60 } 61 void SetFrameTime(double frame_time) { 62 // simple forward repeating animation 63 time_passed = frame_time; 64 while (time_passed >= duration) {time_passed -= duration;} 65 while (time_passed < 0.0) {time_passed += duration;} 66 frame_number = (int)(time_passed / duration); 67 // shouldn't be necessary, but just in case 68 if (frame_number < 0) {frame_number = 0;} 69 if (frame_number >= num_frames) {frame_number = num_frames - 1;} 70 } 71 72 void Draw(int cx , int cy) { 73 al_draw_bitmap(frames[frame_number] , cx , cy , 0); 74 } 75 76};

Main:

#SelectExpand
1int main(int argc , char** argv) 2{ 3 if(!al_init()) { 4 fprintf(stderr, "Failed al_init"); 5 return -1; 6 } 7 if(!al_init_primitives_addon()) { 8 fprintf(stderr, "Failed to initialize Addon primitives!\n"); 9 return -1; 10 } 11 al_init_font_addon(); 12 al_init_ttf_addon(); 13 if(!al_init_image_addon()) { 14 fprintf(stderr, "Failed to initialize Image addon!\n"); 15 return -1; 16 } 17 if(!al_install_mouse()) { 18 fprintf(stderr, "Failed to initialize Mouse!\n"); 19 return -1; 20 } 21 if(!al_install_keyboard()) { 22 fprintf(stderr, "Failed to initialize Keyboard!\n"); 23 return -1; 24 } 25 if(!al_install_audio()) { 26 fprintf(stderr, "failed to initialize audio!\n"); 27 return -1; 28 } 29 if(!al_init_acodec_addon()) { 30 fprintf(stderr, "failed to initialize audio codecs!\n"); 31 return -1; 32 } 33 if(!al_reserve_samples(1)) { 34 fprintf(stderr, "failed to reserve samples!\n"); 35 return -1; 36 } 37 timer = al_create_timer(1.0 / FPS); 38 if(!timer) { 39 fprintf(stderr, "Failed to created timer!\n"); 40 return -1; 41 } 42 font = al_load_ttf_font("DejaVuSans.ttf", 15, 0); 43 if(!font) { 44 fprintf(stderr, "Failed to load font!\n"); 45 return -1; 46 } 47 48 al_set_target_bitmap(al_get_backbuffer(display)); 49 50 event_queue = al_create_event_queue(); 51 if(!event_queue) { 52 fprintf(stderr, "Failed to create event_queue!\n"); 53 return -1; 54 } 55 56 display = al_create_display(SCREEN_W, SCREEN_H); 57 58 const int NUM_SPRITES = 3; 59 const char* sprite_files[NUM_SPRITES] = { 60 "Sprites/FFT1/21.bmp", 61 "Sprites/FFT1/22.bmp", 62 "Sprites/FFT1/23.bmp" 63 }; 64 for (int i = 0 ; i < NUM_SPRITES ; ++i) { 65 ALLEGRO_BITMAP* bmp = al_load_bitmap(sprite_files[i]); 66 if (!bmp) { 67 printf("Error loading %s\n" , sprite_files[i]); 68 return -1; 69 } 70 al_convert_mask_to_alpha(bmp, (al_map_rgb(255, 0, 255))); 71 sprites.push_back(bmp); 72 } 73 Animation anime(sprites.size() , 1.0); 74 for (int i = 0 ; i < NUM_SPRITES ; ++i) { 75 anime.SetBitmap(i , sprites[i]); 76 } 77 78 al_play_sample(sample, 1.0, 0.0,1.0,ALLEGRO_PLAYMODE_LOOP,NULL); 79 80 al_register_event_source(event_queue, al_get_display_event_source(display)); 81 82 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 83 84 al_register_event_source(event_queue, al_get_keyboard_event_source()); 85 86 al_register_event_source(event_queue, al_get_mouse_event_source()); 87 88 al_flip_display(); 89 90 al_get_timer_count(timer); 91 92 al_start_timer(timer); 93 94 bool redraw; 95 bool quit; 96 while (!quit) { 97 while (1) { 98 ALLEGRO_EVENT ev; 99 al_wait_for_event(event_queue , &ev); 100 if (ev.type == ALLEGRO_EVENT_KEY_DOWN) { 101 if(ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 102 cx += 5; 103 cy += 5; 104 //frame++; 105 break; 106 } 107 } 108 else if (ev.type == ALLEGRO_EVENT_TIMER) { 109 anime.AdvanceFrameTime(1.0/FPS); 110 redraw = true; 111 } 112 if (al_is_event_queue_empty(event_queue)) { 113 break; 114 } 115 } 116 if (redraw) { 117 al_clear_to_color(al_map_rgb(0,0,0)); 118 anime.Draw(cx,cy); 119 al_flip_display(); 120 redraw = false; 121 } 122 } 123}

Edgar Reynaldo

Sorry, there was a bug in the frame setting code in SetFrameTime. This version should work properly. Just replace the old class with this one.

#SelectExpand
1 2class Animation { 3private : 4 ALLEGRO_BITMAP** frames; 5 double duration; 6 double time_passed; 7 int frame_number; 8 int num_frames; 9public : 10 Animation() : 11 frames(0), 12 duration(0.0), 13 time_passed(0.0), 14 frame_number(0), 15 num_frames(0) 16 {} 17 Animation(int framecount , double time_length) : 18 frames(0), 19 duration(0.0), 20 time_passed(0.0), 21 frame_number(0), 22 num_frames(0) 23 { 24 Reallocate(framecount , time_length); 25 } 26 ~Animation() {Free();} 27 void Free() { 28 if (frames) {delete [] frames;frames = 0;} 29 num_frames = 0; 30 } 31 bool Reallocate(int framecount , double time_length) { 32 if (framecount < 1) {return false;} 33 if (time_length <= 0.0) {return false;} 34 Free(); 35 duration = time_length; 36 time_passed = 0.0; 37 frame_number = 0; 38 try { 39 frames = new ALLEGRO_BITMAP*[framecount]; 40 } 41 catch(...) { 42 frames = 0; 43 return false; 44 } 45 num_frames = framecount; 46 return true; 47 } 48 49 void SetBitmap(int index , ALLEGRO_BITMAP* bmp) { 50 assert((index >= 0) && (index < num_frames)); 51 frames[index] = bmp; 52 } 53 54 void AdvanceFrameTime(double delta_time) { 55 SetFrameTime(time_passed + delta_time); 56 } 57 void SetFrameTime(double frame_time) { 58 // simple forward repeating animation 59 time_passed = frame_time; 60 while (time_passed >= duration) {time_passed -= duration;} 61 while (time_passed < 0.0) {time_passed += duration;} 62 frame_number = (int)((float)num_frames*(time_passed / duration)); 63 // shouldn't be necessary, but just in case 64 if (frame_number < 0) {frame_number = 0;} 65 if (frame_number >= num_frames) {frame_number = num_frames - 1;} 66 } 67 68 void Draw(int x , int y) { 69 al_draw_bitmap(frames[frame_number] , x , y , 0); 70 } 71 72 double FrameTime() {return time_passed;} 73 int FrameNum() {return frame_number;} 74 75};

The bug was in SetFrameTime here :

   void SetFrameTime(double frame_time) {
      // simple forward repeating animation
      time_passed = frame_time;
      while (time_passed >= duration) {time_passed -= duration;}
      while (time_passed < 0.0) {time_passed += duration;}
frame_number = (int)((float)num_frames*(time_passed / duration));
// shouldn't be necessary, but just in case if (frame_number < 0) {frame_number = 0;} if (frame_number >= num_frames) {frame_number = num_frames - 1;} }

Neil Walker

All your code seems (e.g. the 'sprite' vector, the load function, etc) to be set on having just one sprite. What about other sprites in the game or different animations for the same sprite (e.g. moving left, right, jumping, etc).

What you should do is as well as having an animation class, have an animation manager class to store all your animations (I used a config file that stored each animation in a stl map so you could retrieve by namem this also means you don't hard code bitmap names into the executable).

Regarding the Animation class, in my animation I added a set of actions (e.g. pause, manual increment, frame based increment), a sprite step mode (i.e. what happens when you move from one frame to the next and/or get to the start/end) for example FORWARDONLY (first to last then stay at last from), BACKWARDONLY, FLIPFLOP (repeat forwards, backwards), REPEATFORWARD (at end go back to start) and a basic event (i.e. function pointer) to trigger when animation ends (handy for setting an action, like a dying animation then informing the system that the death throws are finished).

Jefferson Almeida

Hi... no problem Edgar... Thanks a lot!

Hi Neil, thanks for tips, maybe I use: http://oi54.tinypic.com/2qjvxig.jpg and al_create_sub_bitmap

Edit 1: I saw in the another topic an cool example, I made ​​a small correction!

I realize that this makes the image to animate in all positions, if I want my image to animate for each moviment, RIGHT, LEFT, UP, DOWN I had to do something similar and split into frames?
It would be an animation for each move?

#SelectExpand
1class Animation { 2protected : 3 ALLEGRO_BITMAP** frames; 4 double duration; 5 double frames_per_sec; 6 double frametime; 7 int num_frames; 8 int frame_num; 9 10public : 11 Animation() : 12 frames(0), 13 duration(0.0), 14 frames_per_sec(0.0), 15 frametime(0.0), 16 num_frames(0), 17 frame_num(0) 18 {} 19 ~Animation() {Free();} 20 21 void Free() { 22 if (frames) { 23 delete [] frames; 24 frames = 0; 25 } 26 } 27 28 void Setup(double play_duration , int number_of_frames) { 29 Free(); 30 assert(number_of_frames > 0); 31 assert(play_duration > 0.0); 32 duration = play_duration; 33 num_frames = number_of_frames; 34 frames = new ALLEGRO_BITMAP*[num_frames]; 35 frames_per_sec = (double)num_frames / duration; 36 SetFrameTime(0.0); 37 } 38 void AdvanceFrameTime(double delta_time) { 39 SetFrameTime(frametime + delta_time); 40 } 41 void SetFrameTime(double new_frame_time) { 42 while(new_frame_time < 0.0) {new_frame_time += duration;} 43 while(new_frame_time >= duration) {new_frame_time -= duration;} 44 frametime = new_frame_time; 45 frame_num = (int)(frametime*frames_per_sec); 46 } 47 void SetBitmap(ALLEGRO_BITMAP* bmp, int frame_number) { 48 assert(frames); 49 assert((frame_number >= 0) && (frame_number < num_frames)); 50 frames[frame_number] = bmp; 51 } 52 void Display(int x , int y) { 53 assert(frames); 54 assert(frames[frame_num]); 55 al_draw_bitmap(frames[frame_num] , (float)x , (float)y , 0); 56 } 57 58};

#SelectExpand
1double duration = 10.0; 2int number_of_frames = 40; 3Animation anime; 4anime.Setup(duration , number_of_frames); 5 6ALLEGRO_BITMAP* bmp = al_load_bitmap("player.png"); 7//converts the sprite sheet's magenta background to transparent pixels al_convert_mask_to_alpha(bmp, (al_map_rgb(255, 0, 255))); 8int i = 0; 9ALLEGRO_BITMAP* bmp_array[40]; 10for(int x = 0; x < 8; x++) { 11 for(int y = 0; y < 5; y++) { 12 ALLEGRO_BITMAP* bmp_array[x][y]; 13 bmp_array[x][y] = al_create_sub_bitmap(bmp, 32*x, 32*y, 32, 32); 14 anime.SetBitmap(bmp_array[x][y] , i); 15 ++i; 16 } 17} 18 19// Event loop 20 while (1) { 21 ALLEGRO_EVENT ev; 22 al_wait_for_event(event_queue , &ev); 23 if (ev.type == ALLEGRO_EVENT_TIMER) { 24 anime.AdvanceFrameTime(SECONDS_PER_TICK); 25 redraw = true; 26 } 27 if (al_is_event_queue_empty(event_queue)) {break}; 28 } 29 if (redraw) { 30 al_clear_to_color(al_map_rgb(0,0,0)); 31 anime.Draw(400 - al_get_bitmap_width(bmp)/2 , 300 - al_get_bitmap_height(bmp)/2); 32 al_flip_display(); 33 } 34}

Edgar Reynaldo

I realize that this makes the image to animate in all positions, if I want my image to animate for each moviment, RIGHT, LEFT, UP, DOWN I had to do something similar and split into frames?
It would be an animation for each move?

Yes, there would be a separate animation for each.

Jefferson Almeida said:

ALLEGRO_BITMAP* bmp_array[40];
for(int x = 0; x < 8; x++) {
   for(int y = 0; y < 5; y++) {
ALLEGRO_BITMAP* bmp_array[x][y];
bmp_array[x][y] = al_create_sub_bitmap(bmp, 32*x, 32*y, 32, 32); anime.SetBitmap(bmp_array[x][y] , i); ++i; } }

That is not good coding. You've declared a shadowed variable named bmp_array, and you are assigning the bitmaps to the local bmp_array, not the bmp_array you declared on the first line. That means every sub bitmap created there will be leaked, because the Animation class does not destroy the ALLEGRO_BITMAP*'s that it holds. If you're using MinGW as your compiler, then you should add the compiler flag -Wshadow to your compilation command. It will tell you when you are shadowing (creating more than one variable with the same name) variables.

Isso não é bom de codificação. Você declarou uma variável chamada bmp_array sombra, e você atribuir o bitmaps para o bmp_array local, não a bmp_array você declarou na primeira linha. Isso significa que cada sub bitmap criado haverá vazamento, porque a classe Animação não é destruir o * ALLEGRO_BITMAP 'que detém. Se você estiver usando MinGW como seu compilador, então você deve adicionar o compilador bandeira Wshadow para o comando de compilação. Ele lhe dirá quando você está sombreamento (criando mais de uma variável com o mesmo nome) variáveis.

Jefferson Almeida

I saw this code this topic: http://www.allegro.cc/forums/thread/607037/913972#target

I stayed curious to see but do not compiled... so I put this way with the leaked just to see.

I'm trying to do of way that I can to have the animations for all movements for when a key is pressed.
I do not know if is better to have all movements in just one image or have all images apart.

Edgar Reynaldo

If you're going to use my Animation class, you need to have a separate Animation for each movement of the character - one for left, right, up, down. The Animation class is currently not copy-able, so you can't store it directly in a map, but you could use a map of pointers :

#SelectExpand
1#include <map> 2using std::map; 3 4#include <string> 5using std::string; 6 7enum KEYS { 8 LEFT = 0, 9 RIGHT = 1, 10 UP = 2, 11 DOWN = 3, 12 NUMKEYS = 4 13} 14 15bool key[NUMKEYS]; 16for (int i = 0 ; i < NUMKEYS ; ++i) {key[i] = false;} 17 18// in main 19Animation anime[4]; 20anime[0].Reallocate(3 , 3.0); 21// load bitmaps and use SetBitmap 22 23map<string , Animation*> amap; 24amap["left"] = &(anime[0]); 25amap["right"] = &(anime[1]); 26amap["up"] = &(anime[2]); 27amap["down"] = &(anime[3]); 28 29Animation* current = amap["left"]; 30 31// in logic 32if (ev.type == ALLEGRO_EVENT_KEY_DOWN) { 33 if (ev.keyboard.keycode == ALLEGRO_KEY_LEFT) { 34 current = amap["left"]; 35 current->SetFrameTime(0.0); 36 key[LEFT] = true; 37 } 38} 39else if (ev.type == ALLEGRO_EVENT_KEY_UP) { 40 if (ev.keyboard.keycode == ALLEGRO_KEY_LEFT) { 41 key[LEFT] = false; 42 } 43} 44else if (ev.type == ALLEGRO_EVENT_TIMER) { 45 if (key[LEFT] || key[RIGHT] || key[UP] || key[DOWN]) { 46 current->AdvanceFrameTime(1.0/FPS); 47 if (key[LEFT]) { 48 cx -= 5; 49 } 50 if (key[RIGHT]) { 51 cx += 5; 52 } 53 } else { 54 current->SetFrameTime(0.0); 55 } 56 redraw = true; 57}

This is just an example, but it should show you how to switch between animations, and only update the animation when you are moving.

Jefferson Almeida

Hello, to use "SetBitmap" he needs a member, which I use, already there is:
Anime animation [4];
Anime [0]. reallocate (3, 3.0);

Edgar Reynaldo
Animation anime[4];
anime[0].Reallocate(3 , 3.0);
ALLEGRO_BITMAP* bmp1 = al_load_bitmap("FFT_21.bmp");
anime[0].SetBitmap(0 , bmp1);

// repeat for bitmaps 0-2
// repeat for anime[0] thru anime[3]

Jefferson Almeida

This way?

#SelectExpand
1 ... 2 Animation anime[4]; 3 anime[0].Reallocate(3 , 3.0); 4 // load bitmaps and use SetBitmap 5 ALLEGRO_BITMAP* bmp0 = al_load_bitmap("Sprites/FFT1/41.bmp"); 6 ALLEGRO_BITMAP* bmp1 = al_load_bitmap("Sprites/FFT1/42.bmp"); 7 ALLEGRO_BITMAP* bmp2 = al_load_bitmap("Sprites/FFT1/43.bmp"); 8 if(!bmp0 && bmp1 && bmp2) { 9 fprintf(stderr, "Failed to load left images"); 10 return -1; 11 } 12 al_convert_mask_to_alpha(bmp0, (al_map_rgb(255, 0, 255))); 13 al_convert_mask_to_alpha(bmp1, (al_map_rgb(255, 0, 255))); 14 al_convert_mask_to_alpha(bmp2, (al_map_rgb(255, 0, 255))); 15 anime[0].SetBitmap(0 , bmp0); 16 anime[0].SetBitmap(1 , bmp1); 17 anime[0].SetBitmap(2 , bmp2); 18 ...

Do I have to redraw?
Something like "anime[0].Draw(cx, cy);" ?
or the fact to be a "current frame" him redraw automatically!

Edgar Reynaldo
#SelectExpand
1Animation* current = &(anime[0]); 2 3//... 4 5// if moving left 6current = &(anime[LEFT]); 7// if moving right 8current = &(anime[RIGHT]); 9// so on... 10 11if (redraw) { 12 al_clear_to_color(al_map_rgb(0,0,0)); 13 current->Draw(cx , cy); 14 al_flip_display(); 15}

Jefferson Almeida

Hi... I put this way and work! "Since last post I just change "anime.Draw(cx,cy)" for "current->Draw(cx, cy);"

I just could not update the sprite at every turn, it updates after a long time the button pressed.

#SelectExpand
1 ... 2 display = al_create_display(SCREEN_W, SCREEN_H); 3 4 bool key[NUMKEYS]; 5 for (int i = 0 ; i < NUMKEYS ; ++i) {key[i] = false;} 6 7 Animation anime[4]; 8 anime[0].Reallocate(3 , 3.0); 9 anime[1].Reallocate(3 , 3.0); 10 // load bitmaps and use SetBitmap 11 ALLEGRO_BITMAP* bmpl0 = al_load_bitmap("Sprites/FFT1/41.bmp"); 12 ALLEGRO_BITMAP* bmpl1 = al_load_bitmap("Sprites/FFT1/42.bmp"); 13 ALLEGRO_BITMAP* bmpl2 = al_load_bitmap("Sprites/FFT1/43.bmp"); 14 ALLEGRO_BITMAP* bmpr0 = al_load_bitmap("Sprites/FFT1/21.bmp"); 15 ALLEGRO_BITMAP* bmpr1 = al_load_bitmap("Sprites/FFT1/22.bmp"); 16 ALLEGRO_BITMAP* bmpr2 = al_load_bitmap("Sprites/FFT1/23.bmp"); 17 if(!bmpl0 && bmpl1 && bmpl2 && bmpr0 && bmpr1 && bmpr2) { 18 fprintf(stderr, "Failed to load left and right images"); 19 return -1; 20 } 21 al_convert_mask_to_alpha(bmpl0, (al_map_rgb(255, 0, 255))); 22 al_convert_mask_to_alpha(bmpl1, (al_map_rgb(255, 0, 255))); 23 al_convert_mask_to_alpha(bmpl2, (al_map_rgb(255, 0, 255))); 24 al_convert_mask_to_alpha(bmpr0, (al_map_rgb(255, 0, 255))); 25 al_convert_mask_to_alpha(bmpr1, (al_map_rgb(255, 0, 255))); 26 al_convert_mask_to_alpha(bmpr2, (al_map_rgb(255, 0, 255))); 27 anime[0].SetBitmap(0 , bmpl0); 28 anime[0].SetBitmap(1 , bmpl1); 29 anime[0].SetBitmap(2 , bmpl2); 30 anime[1].SetBitmap(0 , bmpr0); 31 anime[1].SetBitmap(1 , bmpr1); 32 anime[1].SetBitmap(2 , bmpr2); 33 34 35 map<string , Animation*> amap; 36 amap["left"] = &(anime[0]); 37 amap["right"] = &(anime[1]); 38 amap["up"] = &(anime[2]); 39 amap["down"] = &(anime[3]); 40 41 Animation* current = &(anime[0]); 42 43 al_register_event_source(event_queue, al_get_display_event_source(display)); 44 45 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 46 47 al_register_event_source(event_queue, al_get_keyboard_event_source()); 48 49 al_register_event_source(event_queue, al_get_mouse_event_source()); 50 51 al_get_timer_count(timer); 52 53 al_start_timer(timer); 54 55 bool quit; 56 bool redraw; 57 while (!quit) { 58 while (1) { 59 ALLEGRO_EVENT ev; 60 al_wait_for_event(event_queue , &ev); 61 if (ev.type == ALLEGRO_EVENT_KEY_DOWN) { 62 if (ev.keyboard.keycode == ALLEGRO_KEY_LEFT) { 63 current = amap["left"]; 64 current->SetFrameTime(0.0); 65 key[LEFT] = true; 66 } 67 if (ev.keyboard.keycode == ALLEGRO_KEY_RIGHT) { 68 current = amap["right"]; 69 current->SetFrameTime(0.0); 70 key[RIGHT] = true; 71 } 72 } 73 else if (ev.type == ALLEGRO_EVENT_KEY_UP) { 74 if (ev.keyboard.keycode == ALLEGRO_KEY_LEFT) { 75 key[LEFT] = false; 76 } 77 if (ev.keyboard.keycode == ALLEGRO_KEY_RIGHT) { 78 key[RIGHT] = false; 79 } 80 } 81 else if (ev.type == ALLEGRO_EVENT_TIMER) { 82 if (key[LEFT] || key[RIGHT] || key[UP] || key[DOWN]) { 83 current->AdvanceFrameTime(1.0/FPS); 84 if (key[LEFT]) { 85 cx -= 5; 86 } 87 if (key[RIGHT]) { 88 cx += 5; 89 } 90 } else { 91 current->SetFrameTime(0.0); 92 } 93 redraw = true; 94 } 95 if (redraw) { 96 al_clear_to_color(al_map_rgb(0,0,0)); 97 current->Draw(cx, cy); 98 al_flip_display(); 99 } 100 } 101 } 102};

Edgar Reynaldo

Your 'if (redraw)' block should not be inside your 'while (1)' loop.

You also need to break out of the 'while (1)' loop when there are no more events, so you can redraw.

Edit
Actually, never mind what I just said. Your code looks like it should do what you want it to. It waits for an event, then processes it appropriately. One thing though - you never set redraw to false, so it redraws every time there is an event. Not really a problem though.

You can try shortening the duration of the animation :

anime[0].Reallocate(3 , 1.0);

Jefferson Almeida

Hi, I changed for "anime[0].Reallocate(4 , 0.1);" and stayed a little better... Thanks a lot!

#SelectExpand
1... 2bool key[NUMKEYS]; 3 for (int i = 0 ; i < NUMKEYS ; ++i) {key[i] = false;} 4 5 Animation anime[4]; 6 anime[0].Reallocate(4 , 0.1); 7 anime[1].Reallocate(4 , 0.1); 8 anime[2].Reallocate(4, 0.1); 9 anime[3].Reallocate(4, 0.1); 10 // load bitmaps and use SetBitmap 11 /* Left Images */ 12 ALLEGRO_BITMAP* aphonsol0 = al_load_bitmap("Sprites/FFT1/aphonsol0.png"); 13 ALLEGRO_BITMAP* aphonsol1 = al_load_bitmap("Sprites/FFT1/aphonsol1.png"); 14 ALLEGRO_BITMAP* aphonsol2 = al_load_bitmap("Sprites/FFT1/aphonsol2.png"); 15 ALLEGRO_BITMAP* aphonsol3 = al_load_bitmap("Sprites/FFT1/aphonsol3.png"); 16 /* Right Images */ 17 ALLEGRO_BITMAP* aphonsor0 = al_load_bitmap("Sprites/FFT1/aphonsor0.png"); 18 ALLEGRO_BITMAP* aphonsor1 = al_load_bitmap("Sprites/FFT1/aphonsor1.png"); 19 ALLEGRO_BITMAP* aphonsor2 = al_load_bitmap("Sprites/FFT1/aphonsor2.png"); 20 ALLEGRO_BITMAP* aphonsor3 = al_load_bitmap("Sprites/FFT1/aphonsor3.png"); 21 /* Up Images */ 22 ALLEGRO_BITMAP* aphonsou0 = al_load_bitmap("Sprites/FFT1/aphonsou0.png"); 23 ALLEGRO_BITMAP* aphonsou1 = al_load_bitmap("Sprites/FFT1/aphonsou1.png"); 24 ALLEGRO_BITMAP* aphonsou2 = al_load_bitmap("Sprites/FFT1/aphonsou2.png"); 25 ALLEGRO_BITMAP* aphonsou3 = al_load_bitmap("Sprites/FFT1/aphonsou3.png"); 26 /* Down Images */ 27 ALLEGRO_BITMAP* aphonsod0 = al_load_bitmap("Sprites/FFT1/aphonsod0.png"); 28 ALLEGRO_BITMAP* aphonsod1 = al_load_bitmap("Sprites/FFT1/aphonsod1.png"); 29 ALLEGRO_BITMAP* aphonsod2 = al_load_bitmap("Sprites/FFT1/aphonsod2.png"); 30 ALLEGRO_BITMAP* aphonsod3 = al_load_bitmap("Sprites/FFT1/aphonsod3.png"); 31 if(!aphonsol0 && aphonsol1 && aphonsol2 && aphonsol3 && aphonsor0 && aphonsor1 && aphonsor2 && aphonsor3 && aphonsou0 && aphonsou1 && aphonsou2 && aphonsou3 && aphonsod0 && aphonsod1 && aphonsod2 && aphonsod3) { 32 fprintf(stderr, "Failed to load up, dowm, left and right images"); 33 return -1; 34 } 35 //For clear the background images al_convert_mask_to_alpha(bmp, (al_map_rgb(255, 0, 255))); 36 /* Left */ 37 anime[0].SetBitmap(0 , aphonsol0); 38 anime[0].SetBitmap(1 , aphonsol1); 39 anime[0].SetBitmap(2 , aphonsol2); 40 anime[0].SetBitmap(3 , aphonsol3); 41 /* Right */ 42 anime[1].SetBitmap(0 , aphonsor0); 43 anime[1].SetBitmap(1 , aphonsor1); 44 anime[1].SetBitmap(2 , aphonsor2); 45 anime[1].SetBitmap(3 , aphonsor3); 46 /* Up */ 47 anime[2].SetBitmap(0 , aphonsou0); 48 anime[2].SetBitmap(1 , aphonsou1); 49 anime[2].SetBitmap(2 , aphonsou2); 50 anime[2].SetBitmap(3 , aphonsou3); 51 /* Down */ 52 anime[3].SetBitmap(0 , aphonsod0); 53 anime[3].SetBitmap(1 , aphonsod1); 54 anime[3].SetBitmap(2 , aphonsod2); 55 anime[3].SetBitmap(3 , aphonsod3); 56 57 map<string , Animation*> amap; 58 amap["left"] = &(anime[0]); 59 amap["right"] = &(anime[1]); 60 amap["up"] = &(anime[2]); 61 amap["down"] = &(anime[3]); 62 63 Animation* current = &(anime[2]); 64 65 al_register_event_source(event_queue, al_get_display_event_source(display)); 66 67 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 68 69 al_register_event_source(event_queue, al_get_keyboard_event_source()); 70 71 al_register_event_source(event_queue, al_get_mouse_event_source()); 72 73 al_get_timer_count(timer); 74 75 al_start_timer(timer); 76 77 bool quit; 78 bool redraw; 79 while (!quit) { 80 while (1) { 81 ALLEGRO_EVENT ev; 82 al_wait_for_event(event_queue , &ev); 83 if (ev.type == ALLEGRO_EVENT_KEY_DOWN) { 84 if (ev.keyboard.keycode == ALLEGRO_KEY_LEFT) { 85 current = amap["left"]; 86 current->SetFrameTime(0.0); 87 key[LEFT] = true; 88 break; 89 } 90 if (ev.keyboard.keycode == ALLEGRO_KEY_RIGHT) { 91 current = amap["right"]; 92 current->SetFrameTime(0.0); 93 key[RIGHT] = true; 94 break; 95 } 96 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) { 97 current = amap["up"]; 98 current->SetFrameTime(0.0); 99 key[UP] = true; 100 break; 101 } 102 if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 103 current = amap["down"]; 104 current->SetFrameTime(0.0); 105 key[DOWN] = true; 106 break; 107 } 108 } 109 else if (ev.type == ALLEGRO_EVENT_KEY_UP) { 110 if (ev.keyboard.keycode == ALLEGRO_KEY_LEFT) { 111 key[LEFT] = false; 112 break; 113 } 114 if (ev.keyboard.keycode == ALLEGRO_KEY_RIGHT) { 115 key[RIGHT] = false; 116 break; 117 } 118 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) { 119 key[UP] = false; 120 break; 121 } 122 if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 123 key[DOWN] = false; 124 break; 125 } 126 } 127 else if (ev.type == ALLEGRO_EVENT_TIMER) { 128 if (key[LEFT] || key[RIGHT] || key[UP] || key[DOWN]) { 129 current->AdvanceFrameTime(1.0/FPS); 130 if (key[LEFT]) { 131 cx -= 1; 132 cy --; 133 } 134 if (key[RIGHT]) { 135 cx += 1; 136 cy ++; 137 } 138 if (key[UP]) { 139 cx += 1; 140 cy --; 141 } 142 if (key[DOWN]) { 143 cx -= 1; 144 cy ++; 145 } 146 } else { 147 current->SetFrameTime(0.0); 148 } 149 redraw = true; 150 } 151 if (redraw) { 152 al_clear_to_color(al_map_rgb(0,0,0)); 153 current->Draw(cx, cy); 154 al_flip_display(); 155 redraw = false; 156 } 157 } 158 } 159};

Now I'm beginning to do a isometric map with some tiles that I have!

Edit1: I can add my "map_draw();" in the "if(redraw){" or I have to create a class for him and to do it work with the "current->" ?

Edit2: Hi... I removed the "if(redraw) {" and add the "if (al_event_queue_is_empty(event_queue)) {" in your place for put the "map_draw();" , but I think this did not the right way!

    ...
    while (!quit) {
        while (1) {
            ALLEGRO_EVENT ev;
            if (al_event_queue_is_empty(event_queue)) {
                current->Draw(cx, cy);
                al_flip_display();
                al_clear_to_color(al_map_rgb(0,0,0));
                map_draw();
            }
            al_wait_for_event(event_queue , &ev);
            if (ev.type == ALLEGRO_EVENT_KEY_DOWN) {
            ...

Edgar Reynaldo

Edit1: I can add my "map_draw();" in the "if(redraw){" or I have to create a class for him and to do it work with the "current->" ?

Yes, just add map_draw() to the 'if (redraw)' block.

Jefferson Almeida said:

I removed the "if(redraw) {" and add the "if (al_event_queue_is_empty(event_queue)) {" in your place for put the "map_draw();" , but I think this did not the right way!

Think about it - do you want to redraw when the timer goes off, or do you want to redraw when the event queue has been fully processed?

Jefferson Almeida

When I used the "if(redraw) {" and add "map_draw();" the movement of the character stayed with a imense lag.
map_draw(): http://oi51.tinypic.com/1zdywyo.jpg

I think with the time will to give bug!

Edgar Reynaldo

If the character movement is lagging behind, you are either not altering it's position often enough, or you are not redrawing enough.

I think with the time will to give bug!

What?

Jefferson Almeida

Hi, I thought in to create an animation for the character when I press the key F1, but I remember what has many positions: RIGHT, LEFT, UP... has some event that check the last key press for I can to make the animation from him when not in motion.

#SelectExpand
1#include <map> 2using std::map; 3 4#include <string> 5using std::string; 6 7 8/* Test */ 9int cx = 10; 10int cy = 10; 11 12 13 14class Animation { 15private : 16 ALLEGRO_BITMAP** frames; 17 double duration; 18 double time_passed; 19 int frame_number; 20 int num_frames; 21public : 22 Animation() : 23 frames(0), 24 duration(0.0), 25 time_passed(0.0), 26 frame_number(0), 27 num_frames(0) 28 {} 29 Animation(int framecount , double time_length) : 30 frames(0), 31 duration(0.0), 32 time_passed(0.0), 33 frame_number(0), 34 num_frames(0) 35 { 36 Reallocate(framecount , time_length); 37 } 38 ~Animation() {Free();} 39 void Free() { 40 if (frames) {delete [] frames;frames = 0;} 41 num_frames = 0; 42 } 43 bool Reallocate(int framecount , double time_length) { 44 if (framecount < 1) {return false;} 45 if (time_length <= 0.0) {return false;} 46 Free(); 47 duration = time_length; 48 time_passed = 0.0; 49 frame_number = 0; 50 try { 51 frames = new ALLEGRO_BITMAP*[framecount]; 52 } 53 catch(...) { 54 frames = 0; 55 return false; 56 } 57 num_frames = framecount; 58 return true; 59 } 60 61 void SetBitmap(int index , ALLEGRO_BITMAP* bmp) { 62 assert((index >= 0) && (index < num_frames)); 63 frames[index] = bmp; 64 } 65 66 void AdvanceFrameTime(double delta_time) { 67 SetFrameTime(time_passed + delta_time); 68 } 69 void SetFrameTime(double frame_time) { 70 // simple forward repeating animation 71 time_passed = frame_time; 72 while (time_passed >= duration) {time_passed -= duration;} 73 while (time_passed < 0.0) {time_passed += duration;} 74 frame_number = (int)((float)num_frames*(time_passed / duration)); 75 // shouldn't be necessary, but just in case 76 if (frame_number < 0) {frame_number = 0;} 77 if (frame_number >= num_frames) {frame_number = num_frames - 1;} 78 } 79 80 void Draw(int cx , int cy) { 81 al_draw_bitmap(frames[frame_number], cx , cy , 0); 82 } 83 84 double FrameTime() {return time_passed;} 85 int FrameNum() {return frame_number;} 86 87}; 88 89enum KEYS { 90 LEFT = 0, 91 RIGHT = 1, 92 UP = 2, 93 DOWN = 3, 94 F1 = 4, 95 NUMKEYS = 5 96}; 97 98 // Here my main 99 ... 100 101 bool key[NUMKEYS]; 102 for (int i = 0 ; i < NUMKEYS ; ++i) {key[i] = false;} 103 104 Animation anime[5]; 105 anime[0].Reallocate(4 , 0.1); 106 anime[1].Reallocate(4 , 0.1); 107 anime[2].Reallocate(4 , 0.1); 108 anime[3].Reallocate(4 , 0.1); 109 anime[4].Reallocate(4 , 0.1); 110 // Here Load images... 111 ... 112 // Here Setbitmap 113 /* Left */ 114 anime[0].SetBitmap(0 , aphonsol0); 115 anime[0].SetBitmap(1 , aphonsol1); 116 anime[0].SetBitmap(2 , aphonsol2); 117 anime[0].SetBitmap(3 , aphonsol3); 118 /* Right */ 119 anime[1].SetBitmap(0 , aphonsor0); 120 anime[1].SetBitmap(1 , aphonsor1); 121 anime[1].SetBitmap(2 , aphonsor2); 122 anime[1].SetBitmap(3 , aphonsor3); 123 /* Up */ 124 anime[2].SetBitmap(0 , aphonsou0); 125 anime[2].SetBitmap(1 , aphonsou1); 126 anime[2].SetBitmap(2 , aphonsou2); 127 anime[2].SetBitmap(3 , aphonsou3); 128 /* Down */ 129 anime[3].SetBitmap(0 , aphonsod0); 130 anime[3].SetBitmap(1 , aphonsod1); 131 anime[3].SetBitmap(2 , aphonsod2); 132 anime[3].SetBitmap(3 , aphonsod3); 133 /* F1 */ 134 //anime[4]. 135 136 map<string , Animation*> amap; 137 amap["left"] = &(anime[0]); 138 amap["right"] = &(anime[1]); 139 amap["up"] = &(anime[2]); 140 amap["down"] = &(anime[3]); 141 amap["f1"] = &(anime[4]); 142 143 Animation* current = &(anime[2]); 144 145 al_register_event_source(event_queue, al_get_display_event_source(display)); 146 147 al_register_event_source(event_queue, al_get_timer_event_source(timer)); 148 149 al_register_event_source(event_queue, al_get_keyboard_event_source()); 150 151 al_register_event_source(event_queue, al_get_mouse_event_source()); 152 153 al_get_timer_count(timer); 154 155 al_start_timer(timer); 156 157 al_flip_display(); 158 159 bool quit; 160 bool redraw; 161 while (!quit) { 162 while (1) { 163 ALLEGRO_EVENT ev; 164 if(redraw && al_is_event_queue_empty(event_queue)) { 165 current->Draw(cx, cy); 166 al_flip_display(); 167 al_clear_to_color(al_map_rgb(0,0,0)); 168 map_draw(); 169 redraw = false; 170 } 171 al_wait_for_event(event_queue , &ev); 172 if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) { 173 quit = true; 174 break; 175 } 176 else if (ev.type == ALLEGRO_EVENT_KEY_DOWN) { 177 if (ev.keyboard.keycode == ALLEGRO_KEY_LEFT) { 178 current = amap["left"]; 179 current->SetFrameTime(0.0); 180 key[LEFT] = true; 181 break; 182 } 183 if (ev.keyboard.keycode == ALLEGRO_KEY_RIGHT) { 184 current = amap["right"]; 185 current->SetFrameTime(0.0); 186 key[RIGHT] = true; 187 break; 188 } 189 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) { 190 current = amap["up"]; 191 current->SetFrameTime(0.0); 192 key[UP] = true; 193 break; 194 } 195 if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 196 current = amap["down"]; 197 current->SetFrameTime(0.0); 198 key[DOWN] = true; 199 break; 200 } 201 if (ev.keyboard.keycode == ALLEGRO_KEY_F1) { 202 //current = amap["f1"]; 203 //current->SetFrameTime(0.0); 204 //key[F1] = true; 205 al_draw_bitmap(menuedit, 500, 80, 0); 206 break; 207 } 208 if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { 209 quit = true; 210 break; 211 } 212 } 213 else if (ev.type == ALLEGRO_EVENT_KEY_UP) { 214 if (ev.keyboard.keycode == ALLEGRO_KEY_LEFT) { 215 key[LEFT] = false; 216 break; 217 } 218 if (ev.keyboard.keycode == ALLEGRO_KEY_RIGHT) { 219 key[RIGHT] = false; 220 break; 221 222 } 223 if (ev.keyboard.keycode == ALLEGRO_KEY_UP) { 224 key[UP] = false; 225 break; 226 } 227 if (ev.keyboard.keycode == ALLEGRO_KEY_DOWN) { 228 key[DOWN] = false; 229 break; 230 } 231 if (ev.keyboard.keycode == ALLEGRO_KEY_F1) { 232 key[F1] = false; 233 break; 234 } 235 if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE) { 236 quit = false; 237 break; 238 } 239 } 240 else if (ev.type == ALLEGRO_EVENT_TIMER) { 241 if (key[LEFT] || key[RIGHT] || key[UP] || key[DOWN] || key[F1]) { 242 current->AdvanceFrameTime(1.0/FPS); 243 if (key[LEFT]) { 244 cx -= 1; 245 cy --; 246 } 247 if (key[RIGHT]) { 248 cx += 1; 249 cy ++; 250 } 251 if (key[UP]) { 252 cx += 1; 253 //cy --; 254 } 255 if (key[DOWN]) { 256 cx -= 1; 257 //cy ++; 258 } 259 if (key[F1]) { 260 // 261 } 262 } else { 263 current->SetFrameTime(0.0); 264 } 265 redraw = true; 266 267 } 268 } 269 } 270 271 al_destroy_timer(timer); 272 al_destroy_display(display); 273 al_destroy_event_queue(event_queue); 274 return 0; 275};

Thread #607476. Printed from Allegro.cc