![]() |
|
My first game! (pong) |
Havacore
Member #12,591
February 2011
![]() |
I just got into allegro this week and by the looks of it, allegro 5 is brand new and so their are very few tutorials for it (at least as far as what I can find). After going through the few tutorials on the allegro.cc wiki, I decided to say to heck with it and try to make pong, and I've actually gone quite a bit further than I thought I would. Now here is the problem, I've managed to get 3 bitmaps: 2 paddles and a bouncer. I got the two paddles mapped to the keyboard so I can move them up and down, and the bouncer is happily bouncing around all over the place. Now I'm trying to make the bouncer bounce off the paddles. I've included my code, the logic for the bouncing starts at line 132. I've got the bouncer bouncing at the same x-coordinate as the paddles, which means it bounces even when it's not hitting the paddle, no good! BTW, I'm new to the forum, so let me know if this isn't the place to post this, since it's kind of a coding question along with a concept one.
|
J-Gamer
Member #12,491
January 2011
![]() |
Make line 141: " There are plenty of wonderful ideas in The Bible, but God isn't one of them." - Derezo |
Havacore
Member #12,591
February 2011
![]() |
Great! The bouncer is now bouncing off the paddles! Now as far as changes go from allegro4 to 5, should I be able to figure out the rest of what I need from reading examples from allegro 4 for things like, a scoreboard, restarting the board when the bouncer hits the edge of the screen, a title screen etc? Thanks for the help btw!
|
Mark Oates
Member #1,146
March 2001
![]() |
Quote: My first game! Yay! Rather than create bitmaps for the paddles and fill them with color, you could just draw them with primitives instead. Bust out some rounded rectangles, add a little shine-shine! {"name":"603455","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/a\/1a49b8bc2a314928768582ec86377c39.png","w":672,"h":530,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/a\/1a49b8bc2a314928768582ec86377c39"} I made some examples: 1void draw_paddle(float x, float y)
2{
3 // fill
4 al_draw_filled_rounded_rectangle(x, y,
5 x+paddle_width, y+paddle_height, 6, 6, al_color_html("729fcf"));
6 // outline
7 al_draw_rounded_rectangle(x, y,
8 x+paddle_width, y+paddle_height, 6, 6, al_color_html("b5edff"), 1.0);
9 // shine
10 al_draw_filled_rounded_rectangle(x, y,
11 x+paddle_width/2, y+paddle_height-10, 6, 6, al_color_html("8abbef"));
12}
13
14void draw_ball(float x, float y)
15{
16 // fill
17 al_draw_filled_circle(x, y, bouncer_size, al_color_html("6be97d"));
18 // shadow
19 al_draw_filled_circle(x+bouncer_size/4, y+bouncer_size/4,
20 bouncer_size/3*2, al_color_html("59ce76"));
21 // shine
22 al_draw_filled_circle(x-bouncer_size/3, y-bouncer_size/3,
23 bouncer_size/4, al_color_html("9bffaa"));
24}
I used #include <allegro5/allegro_primitives.h> #include <allegro5/allegro_color.h> and don't forget to call al_init_primitives_addon(). Also, I used al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST); al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST); before setting up the display to make the lines draw smoothly. -- |
Havacore
Member #12,591
February 2011
![]() |
Ok I can't for the life of me figure out how you did that. I've never used primitives before, and all I have to work off of is the allegro5 manual. Do you still draw a bitmap and then draw the primitive on top of it? It makes sense to me to put the draw_paddle function in another file to avoid clutter but does that mean that I should put the al_init_primitives_addon() in both .cc files? Basically, how do I go about implementing those primitives into my code? Do I just add the draw_paddle function at the end of the main loop where I draw the bitmaps?
|
Mark Oates
Member #1,146
March 2001
![]() |
I'll do a step by step from your original code attachment. 1. First, I added #include <allegro5/allegro_primitives.h> #include <allegro5/allegro_color.h> just below your #include <allegro5/allegro.h>. All allegro_color does is gives me the function al_color_html(). You could just as easily take this out and use al_map_rgba_f() or other similar function for your colors. 2. Those two functions I made, draw_paddle(float x, float y) and draw_ball(float x, float y) (same as they are in the last post), I placed them just before main. This is also below your constants and enums. Usually my code structure works out like this: # includes 3. before you create the display, (eg. before display = al_create_display(SCREEN_W, SCREEN_H);, I added three lines and al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST); al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST); al_init_primitives_addon(); can go anywhere after al_init(), and it's best to keep it with the rest of your init()s if you have more. 4. Then, way down where you have al_draw_bitmap(right_paddle, right_paddle_x, right_paddle_y, 0); al_draw_bitmap(left_paddle, left_paddle_x, left_paddle_y, 0); al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0); I commented those out and put in: //al_draw_bitmap(right_paddle, right_paddle_x, right_paddle_y, 0); //al_draw_bitmap(left_paddle, left_paddle_x, left_paddle_y, 0); //al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0); draw_paddle(right_paddle_x, right_paddle_y); draw_paddle(left_paddle_x, left_paddle_y); draw_ball(bouncer_x, bouncer_y); 5. Profit! 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;
16
17enum MYKEYS {
18 KEY_UP, KEY_DOWN, KEY_W, KEY_S
19};
20
21
22/* functions */
23
24void draw_paddle(float x, float y)
25{
26 // fill
27 al_draw_filled_rounded_rectangle(x, y,
28 x+paddle_width, y+paddle_height, 3, 3, al_color_html("729fcf"));
29 // outline
30 al_draw_rounded_rectangle(x, y,
31 x+paddle_width, y+paddle_height, 3, 3, al_color_html("b5edff"), 1.0);
32 // shine
33 al_draw_filled_rounded_rectangle(x, y,
34 x+paddle_width/2, y+paddle_height-10, 3, 3, al_color_html("8abbef"));
35}
36
37void draw_ball(float x, float y)
38{
39 // fill
40 al_draw_filled_circle(x, y, bouncer_size, al_color_html("6be97d"));
41 // shadow
42 al_draw_filled_circle(x+bouncer_size/4, y+bouncer_size/4, bouncer_size/3*2, al_color_html("59ce76"));
43 // shine
44 al_draw_filled_circle(x-bouncer_size/3, y-bouncer_size/3, bouncer_size/4, al_color_html("9bffaa"));
45}
46
47
48
49
50int main(int argc, char **argv)
51{
52 ALLEGRO_DISPLAY *display = NULL;
53 ALLEGRO_EVENT_QUEUE *event_queue = NULL;
54 ALLEGRO_TIMER *timer = NULL;
55 ALLEGRO_BITMAP *right_paddle = NULL;
56 ALLEGRO_BITMAP *left_paddle = NULL;
57 ALLEGRO_BITMAP *bouncer = NULL;
58
59 float right_paddle_x = (SCREEN_W * 4/5) - (paddle_width / 2.0);
60 float right_paddle_y = (SCREEN_H / 2.0) - (paddle_height / 2.0);
61
62 float left_paddle_x = (SCREEN_W * 1/5) - (paddle_width / 2.0);
63 float left_paddle_y = (SCREEN_H / 2.0) - (paddle_height / 2.0);
64
65 float bouncer_x = SCREEN_W / 2.0 - bouncer_size / 2.0;
66 float bouncer_y = SCREEN_H / 2.0 - bouncer_size / 2.0;
67 float bouncer_dx = 4.0, bouncer_dy = -4.0;
68
69 bool key[4] = {false, false, false, false };
70 bool redraw = true;
71 bool doexit = false;
72
73 if(!al_init()) {
74 fprintf(stderr, "failed to initialized allegro\n");
75 return -1;
76 }
77
78 if(!al_install_keyboard()) {
79 fprintf(stderr, "failed to install keyboard\n");
80 return -1;
81 }
82
83
84 al_init_primitives_addon();
85
86 al_set_new_display_option(ALLEGRO_SAMPLE_BUFFERS, 1, ALLEGRO_SUGGEST);
87 al_set_new_display_option(ALLEGRO_SAMPLES, 4, ALLEGRO_SUGGEST);
88
89
90 //initialize display (w, h)
91 display = al_create_display(SCREEN_W, SCREEN_H);
92 if(!display) {
93 fprintf(stderr, "failed to create display\n");
94 return -1;
95 }
96
97 timer = al_create_timer(1.0/FPS);
98 if(!timer) {
99 fprintf(stderr, "failed to create timer\n");
100 return -1;
101 }
102
103 right_paddle = al_create_bitmap(paddle_width, paddle_height);
104 if(!right_paddle) {
105 fprintf(stderr, "failed to create right paddle bitmap\n");
106 return -1;
107 }
108
109 left_paddle = al_create_bitmap(paddle_width, paddle_height);
110 if(!left_paddle) {
111 fprintf(stderr, "failed to create left paddle bitmap\n");
112 return -1;
113 }
114 bouncer = al_create_bitmap(bouncer_size, bouncer_size);
115 if(!bouncer) {
116 fprintf(stderr, "failed to create bouncer bitmap\n");
117 return -1;
118 }
119
120 al_set_target_bitmap(left_paddle);
121 al_clear_to_color(al_map_rgb (0,255,0));
122
123 al_set_target_bitmap(right_paddle);
124 al_clear_to_color(al_map_rgb (0,255,0));
125
126 al_set_target_bitmap(bouncer);
127 al_clear_to_color(al_map_rgb (0,0,255));
128
129 al_set_target_bitmap(al_get_backbuffer(display));
130
131 event_queue = al_create_event_queue();
132 if(!event_queue) {
133 fprintf(stderr, "failed to create event queue\n");
134 return -1;
135 }
136
137 al_register_event_source(event_queue, al_get_display_event_source(display));
138
139 al_register_event_source(event_queue, al_get_timer_event_source(timer));
140
141 al_register_event_source(event_queue, al_get_keyboard_event_source());
142
143 al_clear_to_color(al_map_rgb(0, 0, 0));
144
145 al_flip_display();
146
147 al_start_timer(timer);
148
149 while(!doexit)
150 {
151 ALLEGRO_EVENT ev;
152
153 al_wait_for_event(event_queue, &ev);
154
155 if(ev.type == ALLEGRO_EVENT_TIMER) {
156
157 //logic for moving the paddles on input
158 if(key[KEY_UP] && right_paddle_y >= 4.0) {
159 right_paddle_y -= 4.0;
160 }
161
162 if(key[KEY_DOWN] && right_paddle_y <= SCREEN_H - paddle_height - 4.0){
163 right_paddle_y += 4.0;
164 }
165
166 if(key[KEY_W] && left_paddle_y >= 4.0) {
167 left_paddle_y -= 4.0;
168 }
169
170 if(key[KEY_S] && left_paddle_y <= SCREEN_H - paddle_height - 4.0){
171 left_paddle_y += 4.0;
172 }
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 if(bouncer_x == left_paddle_x + (paddle_width / 2.0) || bouncer_x == right_paddle_x - (paddle_width / 2.0)) {
184 bouncer_dx = -bouncer_dx;
185 }
186
187
188 bouncer_x += bouncer_dx;
189 bouncer_y += bouncer_dy;
190
191 redraw = true;
192 }
193
194 else if(ev.type == ALLEGRO_EVENT_DISPLAY_CLOSE) {
195 break;
196 }
197
198 else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) {
199 switch(ev.keyboard.keycode) {
200 case ALLEGRO_KEY_UP:
201 key[KEY_UP] = true;
202 break;
203
204 case ALLEGRO_KEY_DOWN:
205 key[KEY_DOWN] = true;
206 break;
207
208 case ALLEGRO_KEY_W:
209 key[KEY_W] = true;
210 break;
211
212 case ALLEGRO_KEY_S:
213 key[KEY_S] = true;
214 break;
215 }
216 }
217
218 else if(ev.type == ALLEGRO_EVENT_KEY_UP) {
219 switch(ev.keyboard.keycode) {
220 case ALLEGRO_KEY_UP:
221 key[KEY_UP] = false;
222 break;
223
224 case ALLEGRO_KEY_DOWN:
225 key[KEY_DOWN] = false;
226 break;
227
228 case ALLEGRO_KEY_W:
229 key[KEY_W] = false;
230 break;
231
232 case ALLEGRO_KEY_S:
233 key[KEY_S] = false;
234 break;
235
236 case ALLEGRO_KEY_ESCAPE:
237 doexit = true;
238 break;
239 }
240 }
241
242 if(redraw && al_is_event_queue_empty(event_queue)) {
243 redraw = false;
244
245 al_clear_to_color(al_map_rgb(0,0,0));
246
247 draw_paddle(right_paddle_x, right_paddle_y);
248 draw_paddle(left_paddle_x, left_paddle_y);
249 draw_ball(bouncer_x, bouncer_y);
250
251 //al_draw_bitmap(right_paddle, right_paddle_x, right_paddle_y, 0);
252 //al_draw_bitmap(left_paddle, left_paddle_x, left_paddle_y, 0);
253 //al_draw_bitmap(bouncer, bouncer_x, bouncer_y, 0);
254
255 al_flip_display();
256 }
257 }
258
259 al_destroy_bitmap(bouncer);
260 al_destroy_bitmap(right_paddle);
261 al_destroy_bitmap(left_paddle);
262 al_destroy_timer(timer);
263 al_destroy_display(display);
264 al_destroy_event_queue(event_queue);
265
266 return 0;
267}
Havacore said: Do you still draw a bitmap and then draw the primitive on top of it? Nope. Primitives draw themselves. Of course, you're drawing the primitives to the display, which technically is a bitmap. But you don't need to have any extra surfaces to render primitives. Quote: It makes sense to me to put the draw_paddle function in another file to avoid clutter but does that mean that I should put the al_init_primitives_addon() in both .cc files? al_init_primitives_addon() is like al_init(). You only need to call it once when you setup your program and you're good to go. Quote: Do I just add the draw_paddle function at the end of the main loop where I draw the bitmaps? Yeaup. -- |
Havacore
Member #12,591
February 2011
![]() |
Now I'm trying to figure out how to add font so that I can add in a scoreboard. I took a look at the code in the allegro wiki on how to do fonts, but I can't seem to compile it properly. Here is the error jason@Wally:~/Documents/game dev/allegro wiki lessons/lesson 6$ gcc lesson6fonts.cc -o lesson $(pkg-config --libs allegro-5.0 allegro_font-5.0 allegro_ttf-5.0) Looking at this terminal panic, it's looking for the fonts config in a folder called jason/Documents/games, which doesn't exist. My allegro folder is in Documents/game dev/allegro-5.0/etc...
|
Michael Faerber
Member #4,800
July 2004
![]() |
Do you mean that page? Anyway, it seems that the compilation is not the problem, but loading the font is. Have you tried putting the font file into the directory where you call your program from? This would most probably be the directory where you have your executable. -- |
Havacore
Member #12,591
February 2011
![]() |
Just tried that, but it didn't work
|
Neil Roy
Member #2,229
April 2002
![]() |
Which front end/compiler are you using? CodeBlocks likes to create a bin folder for your executable, but keep the root folder for your project by default. Also, what is the code you're using to try and initialize the font? --- |
Havacore
Member #12,591
February 2011
![]() |
I'm using gcc The code that I'm using is from the allegro wiki Just trying to get that code to work so that I can implement it into my game
|
|