|
How can I draw multiple bitmaps to the backbuffer at the same time? |
Anatta
Member #16,686
June 2017
|
Hello everyone, I've just finished the Allegro 5 API Tutorials. I decide to write a simple snake game to strengthen what I've learnt. But I hit a big wall just after I get start I tried to draw 2 bitmaps to the backbuffer but after flipping the display, just only 1 bitmap (head) showed up. I went back to the tutorials but cannot find the way, then do a lot of searches but helpless. 1 al_set_target_bitmap(head);
2 al_clear_to_color(al_map_rgb(255, 255, 255));
3
4 al_set_target_bitmap(food);
5 al_clear_to_color(al_map_rgb(0, 255, 0));
6
7 al_set_target_backbuffer(disp);
8 al_clear_to_color(al_map_rgb(0, 0, 0));
9
10 al_flip_display();
Full code: 1// Compiled with C++14 // Using Allegro 5 API //
2//////////////////////////////////////////////////////////////////////////
3//---------------------------- libraries ---------------------------------
4#include "allegro5\allegro.h"
5#include "allegro5\allegro_native_dialog.h"
6#include <random>
7//---------------------------- constants ---------------------------------
8#define W 1218
9#define H 685
10#define FPS 61
11//---------------------------- global vars -------------------------------
12ALLEGRO_TIMER* timer {nullptr};
13ALLEGRO_EVENT_QUEUE* evque {nullptr};
14ALLEGRO_DISPLAY* disp {nullptr};
15bool redraw {false};
16bool quit {false};
17 // snake's head
18ALLEGRO_BITMAP* head {nullptr};
19float heads {16};
20float headx {W / 2 - heads / 2};
21float heady {H / 2 - heads / 2};
22float headd {4};
23 // food
24ALLEGRO_BITMAP* food {nullptr};
25float foods {16};
26float foodx {W / 3 - foods / 3};
27float foody {H / 3 - foods / 3};
28 // control keys
29enum CTRL_KEYS {LEFT, UP, RIGHT, DOWN};
30bool key[4] {{false}};
31 // random miscs
32std::random_device rd;
33std::mt19937 gen(rd());
34std::uniform_int_distribution<int> disx(0, W - 1);
35std::uniform_int_distribution<int> disy(0, H - 1);
36 // score
37int score {0};
38//---------------------------- functions ---------------------------------
39int init_all();
40void reg_all();
41void setup_first_frame();
42void game_loop();
43void clean_up();
44//============================ main ======================================
45int main() {
46 if (init_all() < 0) {
47 return -1;
48 }
49 reg_all();
50 setup_first_frame();
51 game_loop();
52 clean_up();
53 return 0;
54}
55//========================================================================
56int init_all() {
57 if (!al_init()) {
58 al_show_native_message_box(disp, "Error!", "Error:",
59 "Failed to initialize Allegro!", nullptr,
60 ALLEGRO_MESSAGEBOX_ERROR);
61 return -1;
62 }
63 timer = al_create_timer(0.99 / FPS);
64 if (!timer) {
65 al_show_native_message_box(disp, "Error!", "Error:",
66 "Failed to initialize timer!", nullptr,
67 ALLEGRO_MESSAGEBOX_ERROR);
68 return -1;
69 }
70 evque = al_create_event_queue();
71 if (!evque) {
72 al_show_native_message_box(disp, "Error!", "Error:",
73 "Failed to initialize event queue!", nullptr,
74 ALLEGRO_MESSAGEBOX_ERROR);
75 al_destroy_timer(timer);
76 return -1;
77 }
78 disp = al_create_display(W, H);
79 if (!disp) {
80 al_show_native_message_box(disp, "Error!", "Error:",
81 "Failed to initialize display!", nullptr,
82 ALLEGRO_MESSAGEBOX_ERROR);
83 al_destroy_timer(timer);
84 al_destroy_event_queue(evque);
85 return -1;
86 }
87 head = al_create_bitmap(heads, heads);
88 if (!head) {
89 al_show_native_message_box(disp, "Error!", "Error:",
90 "Failed to initialize head bitmap!", nullptr,
91 ALLEGRO_MESSAGEBOX_ERROR);
92 al_destroy_timer(timer);
93 al_destroy_event_queue(evque);
94 al_destroy_display(disp);
95 return -1;
96 }
97 al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP);
98 food = al_create_bitmap(foods, foods);
99 if (!food) {
100 al_show_native_message_box(disp, "Error!", "Error:",
101 "Failed to initialize food bitmap!", nullptr,
102 ALLEGRO_MESSAGEBOX_ERROR);
103 al_destroy_timer(timer);
104 al_destroy_event_queue(evque);
105 al_destroy_display(disp);
106 al_destroy_bitmap(head);
107 return -1;
108 }
109 al_set_new_bitmap_flags(ALLEGRO_VIDEO_BITMAP);
110 if (!al_install_keyboard()) {
111 al_show_native_message_box(disp, "Error!", "Error:",
112 "Failed to initialize keyboard!", nullptr,
113 ALLEGRO_MESSAGEBOX_ERROR);
114 al_destroy_timer(timer);
115 al_destroy_event_queue(evque);
116 al_destroy_display(disp);
117 al_destroy_bitmap(head);
118 al_destroy_bitmap(food);
119 return -1;
120 }
121 return 0;
122}
123
124void reg_all() {
125 al_register_event_source(evque, al_get_timer_event_source(timer));
126 al_register_event_source(evque, al_get_display_event_source(disp));
127 al_register_event_source(evque, al_get_keyboard_event_source());
128}
129
130void setup_first_frame() {
131 al_set_target_bitmap(head);
132 al_clear_to_color(al_map_rgb(255, 255, 255));
133 al_set_target_bitmap(food);
134 al_clear_to_color(al_map_rgb(0, 255, 0));
135 al_set_target_backbuffer(disp);
136 al_clear_to_color(al_map_rgb(0, 0, 0));
137 al_flip_display();
138}
139
140void game_loop() {
141 al_start_timer(timer);
142 while (!quit) {
143 ALLEGRO_EVENT ev;
144 al_wait_for_event(evque, &ev);
145 if (ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
146 break;
147 } else if (ev.type == ALLEGRO_EVENT_KEY_DOWN) {
148 switch (ev.keyboard.keycode) {
149 case ALLEGRO_KEY_A:
150 case ALLEGRO_KEY_LEFT:
151 if (key[RIGHT]) {
152 key[LEFT] = false;
153 } else {
154 key[LEFT] = true;
155 }
156 key[UP] = false;
157 key[DOWN] = false;
158 break;
159 case ALLEGRO_KEY_W:
160 case ALLEGRO_KEY_UP:
161 if (key[DOWN]) {
162 key[UP] = false;
163 } else {
164 key[UP] = true;
165 }
166 key[LEFT] = false;
167 key[RIGHT] = false;
168 break;
169 case ALLEGRO_KEY_D:
170 case ALLEGRO_KEY_RIGHT:
171 if (key[LEFT]) {
172 key[RIGHT] = false;
173 } else {
174 key[RIGHT] = true;
175 }
176 key[UP] = false;
177 key[DOWN] = false;
178 break;
179 case ALLEGRO_KEY_S:
180 case ALLEGRO_KEY_DOWN:
181 if (key[UP]) {
182 key[DOWN] = false;
183 } else {
184 key[DOWN] = true;
185 }
186 key[LEFT] = false;
187 key[RIGHT] = false;
188 break;
189 default:
190 quit = true;
191 break;
192 }
193 } else if (ev.type == ALLEGRO_EVENT_TIMER) {
194 al_clear_to_color(al_map_rgb(0, 0, 0));
195 if (key[LEFT] && headx >= headd) {
196 headx -= headd;
197 } else if (key[UP] && heady >= headd) {
198 heady -= headd;
199 } else if (key[RIGHT] && headx <= W - 1 - heads - headd) {
200 headx += headd;
201 } else if (key[DOWN] && heady <= H - 1 - heads - headd) {
202 heady += headd;
203 }
204 al_draw_bitmap(head, headx, heady, 0);
205 if ((headx + heads == foodx && heady == foody) ||
206 (heady + heads == foody && headx == foodx) ||
207 (headx - foods == foodx && heady == foody) ||
208 (heady - foods == foody && headx == foodx)) {
209 ++score;
210 foodx = disx(gen);
211 foody = disx(gen);
212 al_draw_bitmap(food, foodx, foody, 0);
213 }
214 redraw = true;
215 }
216 if (redraw && al_is_event_queue_empty(evque)) {
217 al_flip_display();
218 redraw = false;
219 }
220 }
221}
222
223void clean_up() {
224 al_destroy_timer(timer);
225 al_destroy_event_queue(evque);
226 al_destroy_display(disp);
227 al_destroy_bitmap(head);
228 al_destroy_bitmap(food);
229}
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
You're mixing drawing and logic. Learn to break that habit and separate the two and you'll be much better off. Anatta said:
1/// LOGIC GOES HERE
2 } else if (ev.type == ALLEGRO_EVENT_TIMER) {
3 al_clear_to_color(al_map_rgb(0, 0, 0));
4 if (key[LEFT] && headx >= headd) {
5 headx -= headd;
6 } else if (key[UP] && heady >= headd) {
7 heady -= headd;
8 } else if (key[RIGHT] && headx <= W - 1 - heads - headd) {
9 headx += headd;
10 } else if (key[DOWN] && heady <= H - 1 - heads - headd) {
11 heady += headd;
12 }
13 /// you're drawing inside logic
15 if ((headx + heads == foodx && heady == foody) ||
16 (heady + heads == foody && headx == foodx) ||
17 (headx - foods == foodx && heady == foody) ||
18 (heady - foods == foody && headx == foodx)) {
19 ++score;
20 foodx = disx(gen);
21 foody = disx(gen);
22 /// you're drawing inside logic
24 }
25 redraw = true;
26 }
27/// DRAWING GOES HERE
28 if (redraw && al_is_event_queue_empty(evque)) {
29 al_flip_display();
30 redraw = false;
31 }
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 |
Anatta
Member #16,686
June 2017
|
Hi! Thank you for the advice. I've just fixed it. 1 } else if (ev.type == ALLEGRO_EVENT_TIMER) {
2 if (key[LEFT] && headx >= headd) {
3 headx -= headd;
4 } else if (key[UP] && heady >= headd) {
5 heady -= headd;
6 } else if (key[RIGHT] && headx <= W - 1 - heads - headd) {
7 headx += headd;
8 } else if (key[DOWN] && heady <= H - 1 - heads - headd) {
9 heady += headd;
10 }
11 if ((headx + heads == foodx && heady == foody) ||
12 (heady + heads == foody && headx == foodx) ||
13 (headx - foods == foodx && heady == foody) ||
14 (heady - foods == foody && headx == foodx)) {
15 ++score;
16 foodx = disx(gen);
17 foody = disx(gen);
18 food_eaten = true;
19 }
20 redraw = true;
21 }
22 // draw
23 if (redraw && al_is_event_queue_empty(evque)) {
24 al_clear_to_color(al_map_rgb(0, 0, 0));
25 al_draw_bitmap(head, headx, heady, 0);
26 if (food_eaten) {
27 al_draw_bitmap(food, foodx, foody, 0);
28 food_eaten = false;
29 }
30 al_flip_display();
31 redraw = false;
32 }
But still haven't figured out how to draw 2 bitmaps at same time to backbuffer 1// after this function I only see head bitmap on the black screen.
2void setup_first_frame() {
3 al_set_target_bitmap(head);
4 al_clear_to_color(al_map_rgb(255, 255, 255));
5
6 al_set_target_bitmap(food);
7 al_clear_to_color(al_map_rgb(0, 255, 0));
8
9 al_set_target_backbuffer(disp);
10 al_clear_to_color(al_map_rgb(0, 0, 0));
11
12 al_flip_display();
13}
|
Edgar Reynaldo
Major Reynaldo
May 2007
|
Well, is 'food_eaten' true? For how long? Currently it should disappear right away, and only show up when you eat it. Consider your logic. 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 |
Anatta
Member #16,686
June 2017
|
Thank you I've figured out. 1 } else if (ev.type == ALLEGRO_EVENT_TIMER) {
2 if (key[LEFT] && headx >= headd) {
3 headx -= headd;
4 } else if (key[UP] && heady >= headd) {
5 heady -= headd;
6 } else if (key[RIGHT] && headx <= W - 1 - heads - headd) {
7 headx += headd;
8 } else if (key[DOWN] && heady <= H - 1 - heads - headd) {
9 heady += headd;
10 }
11 if (is_collide_head_food()) {
12 ++score;
13 foodx = disx(gen);
14 foody = disy(gen);
15 }
16 redraw = true;
17 }
18 if (redraw && al_is_event_queue_empty(evque)) {
19 al_clear_to_color(al_map_rgb(0, 0, 0));
20 al_draw_bitmap(head, headx, heady, 0);
21 al_draw_bitmap(food, foodx, foody, 0);
22 al_flip_display();
23 redraw = false;
24 }
|
|