|
[A5] A question regarding set_target_bitmap and clear_to_color |
Ninjarobot
Member #12,640
March 2011
|
Hello! I will begin with some quick facts to help you understand my problem. For now I am trying to make a circle, used as a crosshair on the game screen and when I press Space the game will "drop sand"(basically paint the place the crosshair aims with a sandy colour). I would like to add that I am a beginner with Allegro so it's all Greek to me(well not really as I am Greek myself...). I am suspecting that I'm doing something insanely stupid but after 2 days of trying to figure it out I decided to give up and seek answers because Allegro5 is fairly new and there aren't many tutorials about it. What my problem is: From what I understood to redraw something you have to use al_set_target_bitmap to select it, then use al_clear_to_color to "wipe" it and then proceed to redraw it. This is why I select both the ball and the cursor individually, clear them and then select the backbuffer and draw them again. This however is causing the problem of B case. What am I doing wrong? Thanks in advance PS. I am aware some of my code is not needed. It is legacy code from Pong I didn't delete either because it wasn't needed yet or because I am planning to use/fix in the future, however any tips are welcome of course! 1#include <stdio.h>
2#include <allegro5/allegro.h>
3#include <allegro5/allegro_primitives.h>
4#include <allegro5/allegro_color.h>
5
6
7
8/* constants and definitions */
9
10const int SCREEN_W = 640;
11const int SCREEN_H = 480;
12const float FPS = 60;
13const int paddle_height = 96;
14const int paddle_width = 16;
15const int bouncer_size = 16;
16const int cursor_size=18;
17
18enum MYKEYS {
19 KEY_UP, KEY_DOWN, KEY_W, KEY_S,KEY_A,KEY_D,KEY_SPACE,KEY_P
20};
21
22/* functions */
23
24void draw_cursor(float x,float y)
25{
26 al_draw_circle(x , y, cursor_size, al_color_html("ff0000"), 2.0);
27}
28
29void drop_sand(float x,float y)
30{
31 al_draw_filled_circle( x, y, cursor_size-3, al_color_html("ffcc66"));
32}
33
34
35
36void draw_ball(float x, float y)
37{
38 // fill
39 al_draw_filled_circle(x, y, bouncer_size, al_color_html("6be97d"));
40 // shadow
41 al_draw_filled_circle(x+bouncer_size/4, y+bouncer_size/4, bouncer_size/3*2, al_color_html("59ce76"));
42 // shine
43 al_draw_filled_circle(x-bouncer_size/3, y-bouncer_size/3, bouncer_size/4, al_color_html("9bffaa"));
44}
45
46
47
48
49int main(int argc, char **argv)
50{
51 ALLEGRO_DISPLAY *display = NULL;
52 ALLEGRO_EVENT_QUEUE *event_queue = NULL;
53 ALLEGRO_TIMER *timer = NULL;
54 ALLEGRO_BITMAP *sand = NULL;
55 ALLEGRO_BITMAP *bouncer = NULL;
56 ALLEGRO_BITMAP *cursor= NULL;
57
58
59
60 float bouncer_x = SCREEN_W / 2.0 - bouncer_size / 2.0;
61 float bouncer_y = SCREEN_H / 2.0 - bouncer_size / 2.0;
62 float bouncer_dx = 4.0, bouncer_dy = -4.0;
63
64 float cursor_x=(SCREEN_W / 2.0);
65 float cursor_y=(SCREEN_H / 2.0);
66
67 bool key[8] = {false, false, false, false, false, false, false, false};
68 bool redraw = true;
69 bool doexit = false;
70
71 if(!al_init()) {
72 fprintf(stderr, "failed to initialized allegro\n");
73 return -1;
74 }
75
76 if(!al_install_keyboard()) {
77 fprintf(stderr, "failed to install keyboard\n");
78 return -1;
79 }
80
81
82 al_init_primitives_addon();
83
84 al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST);
85 al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST);
86
87
88 //initialize display (w, h)
89 display = al_create_display(SCREEN_W, SCREEN_H);
90 if(!display) {
91 fprintf(stderr, "failed to create display\n");
92 return -1;
93 }
94
95 timer = al_create_timer(1.0/FPS);
96 if(!timer) {
97 fprintf(stderr, "failed to create timer\n");
98 return -1;
99 }
100
101 draw_cursor(300,200);
102
103
104
105 cursor = al_create_bitmap(cursor_size,cursor_size);
106 sand = al_create_bitmap(cursor_size-3,cursor_size-3);
107 bouncer = al_create_bitmap(bouncer_size, bouncer_size);
108 if(!bouncer) {
109 fprintf(stderr, "failed to create bouncer bitmap\n");
110 return -1;
111 }
112
113
114
115 al_set_target_bitmap(bouncer);
116 al_clear_to_color(al_map_rgb (0,0,0));
117 al_set_target_bitmap(cursor);
118 al_clear_to_color(al_map_rgb (0,0,0));
119
120 al_set_target_bitmap(al_get_backbuffer(display));
121
122 event_queue = al_create_event_queue();
123 if(!event_queue) {
124 fprintf(stderr, "failed to create event queue\n");
125 return -1;
126 }
127
128 al_register_event_source(event_queue, al_get_display_event_source(display));
129
130 al_register_event_source(event_queue, al_get_timer_event_source(timer));
131
132 al_register_event_source(event_queue, al_get_keyboard_event_source());
133
134 al_clear_to_color(al_map_rgb(0, 0, 0));
135
136 al_flip_display();
137
138 al_start_timer(timer);
139
140 while(!doexit)
141 {
142 ALLEGRO_EVENT ev;
143
144 al_wait_for_event(event_queue, &ev);
145
146 if(ev.type == ALLEGRO_EVENT_TIMER) {
147
148 //DROP SAND
149 if (key[KEY_SPACE]==true)
150 {
151 drop_sand(cursor_x,cursor_y);
152 redraw=true;
153 }
154
155 //CURSOR
156 if (key[KEY_W] && cursor_y >= 22.0)
157 {
158 cursor_y -= 4.0;
159 }
160 if(key[KEY_S] && cursor_y <= SCREEN_H - cursor_size - 4.0)
161 {
162 cursor_y += 4.0;
163 }
164 if(key[KEY_A] && cursor_x >= 22.0)
165 {
166 cursor_x -= 4.0;
167 }
168 if(key[KEY_D] && cursor_x <= SCREEN_W - cursor_size - 4.0)
169 {
170 cursor_x += 4.0;
171 }
172 //CURSOR
173
174 //logic for the bouncer
175 if(bouncer_x < 0 || bouncer_x > SCREEN_W - bouncer_size) {
176 bouncer_dx = -bouncer_dx;
177 }
178
179 if(bouncer_y < 0 || bouncer_y > SCREEN_H - bouncer_size) {
180 bouncer_dy = -bouncer_dy;
181 }
182
183
184
185 bouncer_x += bouncer_dx;
186 bouncer_y += bouncer_dy;
187
188 redraw = true;
189 }
190
191 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
192 break;
193 }
194
195 else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) {
196 switch(ev.keyboard.keycode) {
197 case ALLEGRO_KEY_UP:
198 key[KEY_UP] = true;
199 break;
200
201 case ALLEGRO_KEY_DOWN:
202 key[KEY_DOWN] = true;
203 break;
204
205 case ALLEGRO_KEY_W:
206 key[KEY_W] = true;
207 break;
208
209 case ALLEGRO_KEY_S:
210 key[KEY_S] = true;
211 break;
212
213 case ALLEGRO_KEY_A:
214 key[KEY_A] = true;
215 break;
216
217 case ALLEGRO_KEY_D:
218 key[KEY_D] = true;
219 break;
220
221 case ALLEGRO_KEY_SPACE:
222 key[KEY_SPACE] = true;
223 break;
224 }
225 }
226
227 else if(ev.type == ALLEGRO_EVENT_KEY_UP) {
228 switch(ev.keyboard.keycode) {
229 case ALLEGRO_KEY_UP:
230 key[KEY_UP] = false;
231 break;
232
233 case ALLEGRO_KEY_DOWN:
234 key[KEY_DOWN] = false;
235 break;
236
237 case ALLEGRO_KEY_W:
238 key[KEY_W] = false;
239 break;
240
241 case ALLEGRO_KEY_S:
242 key[KEY_S] = false;
243 break;
244
245 case ALLEGRO_KEY_A:
246 key[KEY_A] = false;
247 break;
248
249 case ALLEGRO_KEY_D:
250 key[KEY_D] = false;
251 break;
252
253 case ALLEGRO_KEY_SPACE:
254 key[KEY_SPACE] = false;
255 break;
256
257 case ALLEGRO_KEY_ESCAPE:
258 doexit = true;
259 break;
260 }
261 }
262
263 if(redraw && al_is_event_queue_empty(event_queue)) {
264 redraw = false;
265 al_set_target_bitmap(cursor);
266 al_clear_to_color(al_map_rgb(0,0,0));
267
268 al_set_target_bitmap(bouncer);
269 al_clear_to_color(al_map_rgb(0,0,0));
270
271 al_set_target_bitmap(al_get_backbuffer(display));
272
273 draw_cursor(cursor_x,cursor_y);
274 draw_ball(bouncer_x, bouncer_y);
275
276
277 al_rest(0.02);
278
279 al_flip_display();
280 }
281 }
282 al_destroy_bitmap(cursor);
283 al_destroy_bitmap(bouncer);
284 al_destroy_bitmap(sand);
285 al_destroy_timer(timer);
286 al_destroy_display(display);
287 al_destroy_event_queue(event_queue);
288
289 return 0;
290}
|
Billybob
Member #3,136
January 2003
|
It looks like you're kind of making a painting app; like MS Paint, etc. In that case, you need an ALLEGRO_BITMAP that acts as a canvas for the user to draw to. So, let's get started. Add this towards the top of main, as another variable: ALLEGRO_BITMAP *canvas = NULL; Add this during initialization, probably right after creating the cursor, sand, bouncer bitmaps: canvas = al_create_bitmap(SCREEN_W, SCREEN_H); This creates a canvas the size of the screen. Add this after the code for clearing bouncer and cursor: al_set_target_bitmap(canvas); al_clear_to_color(al_map_rgb(0,0,0)); That clears the canvas to black. Inside the code where you call drop_sand do this instead: al_set_target_bitmap(canvas); drop_sand(cursor_x, cursor_y); al_set_target_bitmap(al_get_backbuffer(display)); redraw = true; This will draw the sand to the canvas. Now in the code where you redraw the screen (line 271 in the code you posted), modify to this: al_set_target_bitmap(al_get_backbuffer(display)); al_draw_bitmap(canvas, 0, 0, 0); // Draw the canvas over the entire screen draw_cursor(cursor_x, cursor_y); // Draw the cursor on top (on the screen) draw_ball(bouncer_x, bouncer_y); That will "refresh" the screen with the current canvas, and draw the cursor and ball. Right now, you're using the screen as your canvas. These new modifications just create an actual bitmap for the canvas, so you don't overwrite it every time
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
What are you planning to do with the sand after the user drops it? If you're using C++, you might want to have a container that keeps track of where the sand has been dropped. Or if you go with a canvas idea like BillyBob suggested, then you could read a pixel location and compare it to your sand color. 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 |
Ninjarobot
Member #12,640
March 2011
|
Thanks for the help, gonna try it in a while as I just woke up! As about the use of the sand, I guess I should have been more clear. My current goal is to only have a cursor and space to drop the sand as I said in the first post. However it's aimed to be a game where you have a secondary colour in the background(let's say blue)and you fill the coloured background with sand. I was even thinking of having a more complicated system like like : It should end up a precision game against time. |
|