Allegro.cc - Online Community

Allegro.cc Forums » Programming Questions » [a5] A doubt about move of image with keyboard

This thread is locked; no one can reply to it. rss feed Print
 1   2   3 
[a5] A doubt about move of image with keyboard
Jefferson Almeida
Member #12,659
March 2011

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
Major Reynaldo
May 2007
avatar

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
Member #9,841
May 2008
avatar

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
Member #12,659
March 2011

"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
Member #9,841
May 2008
avatar

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
Member #12,659
March 2011

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
Member #261
April 2000
avatar

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
Member #12,659
March 2011

  ...
  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
Member #261
April 2000
avatar

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

Jefferson Almeida
Member #12,659
March 2011

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
Major Reynaldo
May 2007
avatar

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
Member #12,659
March 2011

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
Major Reynaldo
May 2007
avatar

*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
Member #12,659
March 2011

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
Major Reynaldo
May 2007
avatar

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
Member #12,659
March 2011

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

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

Edgar Reynaldo
Major Reynaldo
May 2007
avatar

Jefferson Almeida
Member #12,659
March 2011

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
Major Reynaldo
May 2007
avatar

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
Member #12,659
March 2011

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
Major Reynaldo
May 2007
avatar

Jefferson Almeida
Member #12,659
March 2011

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
Major Reynaldo
May 2007
avatar

Jefferson Almeida
Member #12,659
March 2011

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
Major Reynaldo
May 2007
avatar

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.

 1   2   3 


Go to: