|
[a5] A doubt about move of image with keyboard |
Jefferson Almeida
Member #12,659
March 2011
|
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! |
Jefferson Almeida
Member #12,659
March 2011
|
Here, my last code: 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
Major Reynaldo
May 2007
|
Jefferson Almeida said:
while (!quit) { if(redraw) { al_clear_to_color(al_map_rgb(0,0,0)); anime.Draw(cx , cy);
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. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Jefferson Almeida
Member #12,659
March 2011
|
@@" edit1: So I do not need to do a "if(redraw).." ? 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
Major Reynaldo
May 2007
|
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. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Jefferson Almeida
Member #12,659
March 2011
|
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? 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
Major Reynaldo
May 2007
|
Game loop : 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}
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Jefferson Almeida
Member #12,659
March 2011
|
Look: 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
Major Reynaldo
May 2007
|
It looks fine to me. So does it work or what? My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Jefferson Almeida
Member #12,659
March 2011
|
Just to know if it was right =D class of the another topic 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! 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
Major Reynaldo
May 2007
|
It still looks fine - does it work or not? My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Jefferson Almeida
Member #12,659
March 2011
|
Hi, sorry for delay... I was trying to discover before to ask help! Edit1: Oddly enough... rs... I think this time the indentation are totally right. o_O" 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: 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
Major Reynaldo
May 2007
|
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. 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;}
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Neil Walker
Member #210
April 2000
|
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). Neil. wii:0356-1384-6687-2022, kart:3308-4806-6002. XBOX:chucklepie |
Jefferson Almeida
Member #12,659
March 2011
|
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? 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};
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
Major Reynaldo
May 2007
|
Jefferson Almeida said:
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? 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++) { 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. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Jefferson Almeida
Member #12,659
March 2011
|
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. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
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 : 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. My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Jefferson Almeida
Member #12,659
March 2011
|
Hello, to use "SetBitmap" he needs a member, which I use, already there is: |
Edgar Reynaldo
Major Reynaldo
May 2007
|
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]
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Jefferson Almeida
Member #12,659
March 2011
|
This way? 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? |
Edgar Reynaldo
Major Reynaldo
May 2007
|
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}
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
Jefferson Almeida
Member #12,659
March 2011
|
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. 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
Major Reynaldo
May 2007
|
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 You can try shortening the duration of the animation : anime[0].Reallocate(3 , 1.0);
My Website! | EAGLE GUI Library Demos | My Deviant Art Gallery | Spiraloid Preview | A4 FontMaker | Skyline! (Missile Defense) Eagle and Allegro 5 binaries | Older Allegro 4 and 5 binaries | Allegro 5 compile guide |
|
|