|
[ALLEGRO 5] I am having trouble with getting my character to stand still when... |
cpp_4_life
Member #12,389
November 2010
|
Hi, everyone I am having a little trouble with the new Allegro 5. Any way, I am making a game and I have finally got the character to move smoothly. But I want it to stand still when the left key is not pressed, and the right key is not pressed. But it doesn't seem to work, when I let go of both the left or the right it stays at the last position it was running, and it doesn't stand normally. It used to work with Allegro 4, but the API has been revamped so I have to learn it again. Here is the code below: 1#include <allegro5\allegro.h>
2#include <allegro5\allegro_image.h>
3bool doexit = false;
4int x = 0;
5int y = 117;
6int xpos = 405;
7const float fps = 20;
8bool redraw = false;
9bool rightpress = false;
10bool leftwaslast = false;
11bool rightwaslast = true;
12int main(void)
13{
14 ALLEGRO_BITMAP* buffer;
15 ALLEGRO_DISPLAY* screen;
16 ALLEGRO_EVENT_QUEUE* event_queue;
17 ALLEGRO_BITMAP* bck;
18 ALLEGRO_BITMAP* right;
19 ALLEGRO_TIMER* timer;
20 int retval = al_init();
21 if (!retval)
22 {
23 return 0;
24 }
25 screen = al_create_display(256, 192);
26 if (!screen)
27 {
28 return 0;
29 }
30 if (!al_install_keyboard())
31 {
32 return 0;
33 }
34 timer = al_create_timer(1.0 / fps);
35
36 bool retval2 = al_init_image_addon();
37 if (!retval2)
38 return 0;
39 buffer = al_create_bitmap(256, 192);
40 if (!buffer)
41 return 0;
42 bck = al_load_bitmap("background.bmp");
43 right = al_load_bitmap("right.bmp");
44 if (!bck || !right)
45 return 0;
46 al_set_app_name("Metriod Game");
47 al_set_window_title(screen, "Metriod Game");
48 event_queue = al_create_event_queue();
49 al_register_event_source(event_queue, al_get_keyboard_event_source());
50 al_register_event_source(event_queue, al_get_timer_event_source(timer));
51 al_start_timer(timer);
52 while (1)
53 {
54 al_set_target_bitmap(buffer);
55 al_draw_bitmap(bck, 0, 0, 0);
56 al_set_target_bitmap(buffer);
57 al_convert_mask_to_alpha(right, al_map_rgb(255, 0, 255));
58 al_draw_bitmap_region(right, xpos, 0, 37, 40, x, y, 0);
59 al_set_target_bitmap(al_get_backbuffer(screen));
60 al_draw_bitmap(buffer, 0, 0, 0);
61 al_flip_display();
62 ALLEGRO_EVENT ev;
63 al_wait_for_event(event_queue, &ev);
64 if (ev.keyboard.keycode == ALLEGRO_KEY_ESCAPE)
65 {
66 al_destroy_timer(timer);
67 return 0; // End the game!
68 }
69
70
71 if (ev.type == ALLEGRO_EVENT_TIMER)
72 {
73 redraw = true;
74
75 if (rightpress)
76 {
77 x += 4;
78
79 if (xpos == 405)
80 {
81 al_rest(0.001);
82 xpos = 0;
83
84 }
85 else if (xpos == 0)
86 {
87 al_rest(0.001);
88
89 xpos = 37;
90
91 }
92 else if (xpos == 37)
93 {
94 al_rest(0.001);
95
96 xpos = 75;
97 }
98 else if (xpos == 75)
99 {
100 al_rest(0.001);
101
102 xpos = 117;
103 }
104 else if (xpos == 117)
105 {
106 al_rest(0.001);
107
108 xpos = 159;
109 }
110 else if (xpos == 159)
111 {
112 al_rest(0.001);
113
114 xpos = 202;
115 }
116 else if (xpos == 202)
117 {
118 al_rest(0.001);
119
120 xpos = 237;
121 }
122 else if (xpos == 237)
123 {
124 al_rest(0.001);
125
126 xpos = 276;
127 }
128 else if (xpos == 276)
129 {
130 al_rest(0.001);
131
132 xpos = 317;
133 }
134 else if (xpos == 317)
135 {
136 al_rest(0.001);
137
138 xpos = 359;
139 }
140 else if (xpos == 359)
141 {
142 al_rest(0.001);
143
144 xpos = 0;
145 }
146 rightpress = false;
147 }
148 }
149 else
150 {
151 if (ev.keyboard.keycode == ALLEGRO_KEY_RIGHT)
152 {
153 rightpress = true;
154 rightwaslast = true;
155 }
156 else
157 {
158
159 if (ev.keyboard.keycode != ALLEGRO_KEY_UP && ev.keyboard.keycode != ALLEGRO_KEY_DOWN)
160 {
161 if (rightwaslast)
162 {
163
164 if (rightwaslast)
165 {
166 xpos = 405;
167 }
168 else if (leftwaslast)
169 {
170 xpos = 468;
171 }
172
173 }
174 }
175 }
176
177
178 }
179 if (redraw && al_is_event_queue_empty(event_queue))
180 {
181 redraw = false;
182 }
183
184
185
186 }
187 return 0;
188}
|
Mark Oates
Member #1,146
March 2001
|
put your code in <code></code> -- |
cpp_4_life
Member #12,389
November 2010
|
Sorry about that, some other forums use the [code] syntax. |
Edgar Reynaldo
Major Reynaldo
May 2007
|
Well, for one thing, you are checking ev.keyboard.keycode when you don't know for sure that the ev.type was ALLEGRO_EVENT_KEY_DOWN or ALLEGRO_EVENT_KEY_UP. At best, you get lucky, and at worst, you access random garbage due to other data being in the union. Another thing, you only need to call al_convert_mask_to_alpha on your right bitmap once. Don't call it over and over again in your drawing loop. What is the purpose of all of these blocks? else if (xpos == blah) { al_rest(0.001); xpos = blah2; } Organize your code into logical sections : 1ALLEGRO_EVENT ev;
2al_wait_for_event(event_queue , &ev);
3switch(ev.type) {
4 case ALLEGRO_EVENT_KEY_DOWN :
5 if (ev.keyboard.keycode == ALLEGRO_KEY_RIGHT) {rightpress = true;}
6 if (ev.keyboard.keycode == ALLEGRO_KEY_LEFT) {leftpress = true;}
7 break;
8 case ALLEGRO_EVENT_KEY_UP :
9 if (ev.keyboard.keycode == ALLEGRO_KEY_RIGHT) {rightpress = false;}
10 if (ev.keyboard.keycode == ALLEGRO_KEY_LEFT) {leftpress = false;}
11 break;
12 case ALLEGRO_EVENT_TIMER :
13 redraw = true;
14 break;
15}
16
17if (rightpress) {
18 x += 4;
19 if (x > blah) {x = blah;}
20}
21if (leftpress) {
22 x -= 4;
23 if (x < blah2) {x = blah2;}
24}
25
26
27if (redraw) {
28 draw_stuff();
29}
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 |
cpp_4_life
Member #12,389
November 2010
|
Thanks for the post, the purpose of those blocks is to animate the sprite because it moves through each of the different sprites positions in the sprite sheet. By the way the, your pseudo code has helped my code be more organized but it has worsened the situation. It seems that my character now doesn't move smoothly anymore instead it runs in its standing position. I did some debugging and it seems that the rightpress and the leftpress from your pseudo code example keeps being false. |
Thomas Fjellstrom
Member #476
June 2000
|
You do not need to use explicit double buffering in Allegro 5, and on some hardware, drawing to ALLEGRO_BITMAPs (that are not a ALLEGRO_DISPLAY backbuffer) is rather slow, so in most cases you do NOT want to double buffer like that. Especially considering you end up with 2 or more hardware buffers, which is why the al_flip_display call is even needed. -- |
cpp_4_life
Member #12,389
November 2010
|
OMG, sorry for posting that your code was faulty, but in fact after doing some indepth scan I by accident had a line of code in the xpos block that kept the rightpress false. So again sorry for wasting your precious time here is the code where I fortuitously found the little mistake that caused a hell of a problem: 1if (ev.type == ALLEGRO_EVENT_TIMER)
2 72 {
3 73 redraw = true;
4 74
5 75 if (rightpress)
6 76 {
7 77 x += 4;
8 78
9 79 if (xpos == 405)
10 80 {
11 81 al_rest(0.001);
12 82 xpos = 0;
13 83
14 84 }
15 85 else if (xpos == 0)
16 86 {
17 87 al_rest(0.001);
18 88
19 89 xpos = 37;
20 90
21 91 }
22 92 else if (xpos == 37)
23 93 {
24 94 al_rest(0.001);
25 95
26 96 xpos = 75;
27 97 }
28 98 else if (xpos == 75)
29 99 {
30 100 al_rest(0.001);
31 101
32 102 xpos = 117;
33 103 }
34 104 else if (xpos == 117)
35 105 {
36 106 al_rest(0.001);
37 107
38 108 xpos = 159;
39 109 }
40 110 else if (xpos == 159)
41 111 {
42 112 al_rest(0.001);
43 113
44 114 xpos = 202;
45 115 }
46 116 else if (xpos == 202)
47 117 {
48 118 al_rest(0.001);
49 119
50 120 xpos = 237;
51 121 }
52 122 else if (xpos == 237)
53 123 {
54 124 al_rest(0.001);
55 125
56 126 xpos = 276;
57 127 }
58 128 else if (xpos == 276)
59 129 {
60 130 al_rest(0.001);
61 131
62 132 xpos = 317;
63 133 }
64 134 else if (xpos == 317)
65 135 {
66 136 al_rest(0.001);
67 137
68 138 xpos = 359;
69 139 }
70 140 else if (xpos == 359)
71 141 {
72 142 al_rest(0.001);
73 143
74 144 xpos = 0;
75 145 }
76 146 rightpress = false; // This was causing the problem I don't know how it got there
77 147 }
78 148 }
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
I didn't realize you were using xpos to set the 'frame' of your sprite. I would make a separate animation class, give your object a map<state , Animation*> and then set the state when it needs to change : 1
2class Animation {
3protected :
4 ALLEGRO_BITMAP** frames;
5
6 double duration;
7 double frames_per_sec;
8 double frametime;
9 int num_frames;
10 int frame_num;
11public :
12 Animation(int nframes , double total_time) :
13 frames(0),
14 duration(total_time),
15 frames_per_sec(0.0),
16 frametime(0.0),
17 num_frames(nframes),
18 frame_num(0)
19 {
20 frames_per_sec = (double)num_frames/duration;
21 frames = new ALLEGRO_BITMAP*[num_frames];
22 }
23 void SetFrame(int frame_number , ALLEGRO_BITMAP* bmp) {
24 if ((frame_number >= 0) && (frame_number < num_frames)) {
25 frames[frame_number] = bmp;
26 }
27 }
28 void SetFrameTime(double new_time);
29 void AdvanceFrameTime(double delta_time);
30};
31
32enum ANIM_STATE {
33 STAND_LEFT = 0,
34 STAND_RIGHT = 1,
35 WALK_LEFT = 2,
36 WALK_RIGHT = 3,
37 RUN_LEFT = 4,
38 RUN_RIGHT = 5
39};
40
41#include <map>
42using std::map;
43
44class Object {
45protected :
46 map<ANIM_STATE , Animation*> anim_state_map;
47 Animation* current_animation;
48pubilc :
49 void AddAnimationState(ANIM_STATE state , Animation* animation) {
50 anim_state_map[state] = animation;
51 }
52 void SetAnimationState(ANIM_STATE state) {
53 current_animation = anim_state_map[state];
54 current_animation->SetFrameTime(0.0);
55 }
56 void Update(double tsec) {
57 current_animation->AdvanceFrameTime(tsec);
58 }
59}
cpp_4_life said: I did some debugging and it seems that the rightpress and the leftpress from your pseudo code example keeps being false. Well, I don't see why that would be true. Add in a print statement under the ALLEGRO_KEY_DOWN case and make sure you are getting keypresses in the first place. There is one thing wrong with what I posted though, it will process if(rightpress) and if(leftpress) once for each event. To prevent that, process the events in a loop and don't break out of the loop until your redraw flag is set. 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 |
Thomas Fjellstrom
Member #476
June 2000
|
cpp_4_life said: OMG, sorry for posting that your code was faulty, but in fact after doing some indepth scan I by accident had a line of code in the xpos block that kept the rightpress false. So again sorry for wasting your precious time Don't worry about it. Most of us aren't really all that high and mighty. -- |
|