1/**
2* Project - Allegro Pong
3* Author - packetpirate
4* Last Update - 04/21/2011 1:11 AM
5**/
6
7#include <stdio.h>
8#include <allegro5/allegro.h>
9#include <allegro5/allegro_font.h>
10#include <allegro5/allegro_ttf.h>
11#include <sstream>
12using std::stringstream
;
13#include <string>
14using std::string
;
15
16const int FPS
= 60;
17const int SCREEN_W = 1024;
18const int SCREEN_H = 480;
19
20const int PONG_PADDLE_W
= 20;
21const int PONG_PADDLE_H
= 100;
22
23const float PADDLE_ONE_X
= 40 + (PONG_PADDLE_W
/ 2.
0);
24const float PADDLE_TWO_X
= SCREEN_W - 60 - (PONG_PADDLE_W
/ 2.
0);
25
26const int BALL_SIZE
= 16;
27
28const int GOAL_H
= 480;
29const int GOAL_W
= 20;
30
31const int DIVIDER_H
= 480;
32const int DIVIDER_W
= 20;
33
34enum myKeys
{
35 KEY_UP, KEY_DOWN, KEY_W, KEY_S
36};
37
38int main
(int argc,
char** argv
)
39{
40 ALLEGRO_DISPLAY *display
= NULL
;
41 ALLEGRO_TIMER *timer
= NULL
;
42 ALLEGRO_EVENT_QUEUE *event_queue
= NULL
;
43
44 ALLEGRO_BITMAP *paddle_one
= NULL
;
45 float paddle_one_y
= SCREEN_H / 2.
0 - PONG_PADDLE_H
/ 2.
0;
46 float paddle_one_bb_top
= paddle_one_y
- (PONG_PADDLE_H
/ 2.
0) - 5;
47 float paddle_one_bb_bottom
= paddle_one_y
+ (PONG_PADDLE_H
/ 2.
0) + 5;
48 float paddle_one_bb_right
= PADDLE_ONE_X
+ (PONG_PADDLE_W
/ 2.
0) + 15;
49
50 ALLEGRO_BITMAP *paddle_two
= NULL
;
51 float paddle_two_y
= SCREEN_H / 2.
0 - PONG_PADDLE_H
/ 2.
0;
52 float paddle_two_bb_top
= paddle_two_y
- (PONG_PADDLE_H
/ 2.
0) - 5;
53 float paddle_two_bb_bottom
= paddle_two_y
+ (PONG_PADDLE_H
/ 2.
0) + 5;
54 float paddle_two_bb_left
= SCREEN_W - 65 - PONG_PADDLE_W
;
55
56 ALLEGRO_BITMAP *ball
= NULL
;
57 float ball_x
= SCREEN_W / 2.
0 - BALL_SIZE
/ 2.
0;
58 float ball_y
= SCREEN_H / 2.
0 - BALL_SIZE
/ 2.
0;
59 float ball_dx
= -4.
0, ball_dy
= 4.
0;
60
61 ALLEGRO_BITMAP *left_goal
= NULL
;
62 float goal_left_x
= GOAL_W
/ 2.
0 - 10;
63 float goal_left_y
= 0;
64 float goal_left_bb
= goal_left_x
+ (GOAL_W
/ 2.
0) + 5;
65
66 ALLEGRO_BITMAP *right_goal
= NULL
;
67 float goal_right_x
= SCREEN_W - 10 - (GOAL_W
/ 2.
0);
68 float goal_right_y
= 0;
69 float goal_right_bb
= goal_right_x
- (GOAL_W
/ 2.
0) + 5;
70
71 ALLEGRO_BITMAP *divider
= NULL
;
72 float divider_x
= (SCREEN_W / 2.
0) - 10;
73 float divider_y
= 0;
74
75 bool key[4] = {false,
false,
false,
false};
76
77 bool redraw
= true;
78 bool exit = false;
79
80 // Initialize Allegro
81 if(!al_init()) {
82 fprintf(stderr,
"Error initializing Allegro!\n");
83 return -1;
84 }
85
86 al_init_font_addon();
87 al_init_ttf_addon();
88
89 // Initialize player score variables and font objects.
90 ALLEGRO_FONT *p1_score_font
= al_load_ttf_font("pirulen.ttf",
72,
0);
91 int player_1_score
= 0;
92
93 ALLEGRO_FONT *p2_score_font
= al_load_ttf_font("pirulen.ttf",
72,
0);
94 int player_2_score
= 0;
95
96 // Install the keyboard.
97 if(!al_install_keyboard()) {
98 fprintf(stderr,
"Error installing keyboard!\n");
99 return -1;
100 }
101
102 // Create the timer.
103 timer
= al_create_timer(1.
0 / FPS
);
104 if(!timer
) {
105 fprintf(stderr,
"Failed to create timer!\n");
106 return -1;
107 }
108
109 // Create the display.
110 display
= al_create_display(SCREEN_W,
SCREEN_H);
111 if(!display
) {
112 fprintf(stderr,
"Could not create display!\n");
113 return -1;
114 }
115
116 // Create Pong Paddle One
117 paddle_one
= al_create_bitmap(PONG_PADDLE_W, PONG_PADDLE_H
);
118 if(!paddle_one
) {
119 fprintf(stderr,
"Failed to create Pong Paddle One!\n");
120 al_destroy_display(display
);
121 al_destroy_timer(timer
);
122 return -1;
123 }
124
125 // Set color of Pong Paddle One
126 al_set_target_bitmap(paddle_one
);
127 al_clear_to_color(al_map_rgb(255,
255,
255));
128 al_set_target_bitmap(al_get_backbuffer(display
));
129
130 // Create Pong Paddle Two
131 paddle_two
= al_create_bitmap(PONG_PADDLE_W, PONG_PADDLE_H
);
132 if(!paddle_two
) {
133 fprintf(stderr,
"Failed to create Pong Paddle Two!\n");
134 al_destroy_bitmap(paddle_one
);
135 al_destroy_display(display
);
136 al_destroy_timer(timer
);
137 return -1;
138 }
139
140 // Set the color of Pong Paddle Two
141 al_set_target_bitmap(paddle_two
);
142 al_clear_to_color(al_map_rgb(255,
255,
255));
143 al_set_target_bitmap(al_get_backbuffer(display
));
144
145 // Create the Ball
146 ball
= al_create_bitmap(BALL_SIZE, BALL_SIZE
);
147 if(!ball
) {
148 fprintf(stderr,
"Failed to create ball!\n");
149 al_destroy_bitmap(paddle_one
);
150 al_destroy_bitmap(paddle_two
);
151 al_destroy_display(display
);
152 al_destroy_timer(timer
);
153 return -1;
154 }
155
156 // Set the color of the ball.
157 al_set_target_bitmap(ball
);
158 al_clear_to_color(al_map_rgb(255,
0,
0));
159 al_set_target_bitmap(al_get_backbuffer(display
));
160
161 // Create the Left Goal
162 left_goal
= al_create_bitmap(GOAL_W, GOAL_H
);
163 if(!left_goal
) {
164 fprintf(stderr,
"Failed to create left goal!\n");
165 al_destroy_bitmap(paddle_one
);
166 al_destroy_bitmap(paddle_two
);
167 al_destroy_bitmap(ball
);
168 al_destroy_display(display
);
169 al_destroy_timer(timer
);
170 return -1;
171 }
172
173 // Set the color of the left goal.
174 al_set_target_bitmap(left_goal
);
175 al_clear_to_color(al_map_rgb(0,
200,
255));
176 al_set_target_bitmap(al_get_backbuffer(display
));
177
178 // Create the Right Goal
179 right_goal
= al_create_bitmap(GOAL_W, GOAL_H
);
180 if(!right_goal
) {
181 fprintf(stderr,
"Failed to create right goal!\n");
182 al_destroy_bitmap(paddle_one
);
183 al_destroy_bitmap(paddle_two
);
184 al_destroy_bitmap(ball
);
185 al_destroy_bitmap(left_goal
);
186 al_destroy_display(display
);
187 al_destroy_timer(timer
);
188 return -1;
189 }
190
191 // Set the color of the right goal.
192 al_set_target_bitmap(right_goal
);
193 al_clear_to_color(al_map_rgb(0,
200,
255));
194 al_set_target_bitmap(al_get_backbuffer(display
));
195
196 // Create the Divider
197 divider
= al_create_bitmap(DIVIDER_W, DIVIDER_H
);
198 if(!divider
) {
199 fprintf(stderr,
"Failed to create divider!\n");
200 al_destroy_bitmap(paddle_one
);
201 al_destroy_bitmap(paddle_two
);
202 al_destroy_bitmap(ball
);
203 al_destroy_bitmap(left_goal
);
204 al_destroy_bitmap(right_goal
);
205 al_destroy_display(display
);
206 al_destroy_timer(timer
);
207 return -1;
208 }
209
210 // Set the color of the divider.
211 al_set_target_bitmap(divider
);
212 al_clear_to_color(al_map_rgb(255,
255,
255));
213 al_set_target_bitmap(al_get_backbuffer(display
));
214
215 event_queue
= al_create_event_queue();
216 if(!event_queue
) {
217 fprintf(stderr,
"Error creating event queue!\n");
218 al_destroy_bitmap(paddle_one
);
219 al_destroy_bitmap(paddle_two
);
220 al_destroy_bitmap(ball
);
221 al_destroy_bitmap(left_goal
);
222 al_destroy_bitmap(right_goal
);
223 al_destroy_bitmap(divider
);
224 al_destroy_display(display
);
225 al_destroy_timer(timer
);
226 return -1;
227 }
228
229 al_register_event_source(event_queue,
al_get_display_event_source(display
));
230 al_register_event_source(event_queue,
al_get_timer_event_source(timer
));
231 al_register_event_source(event_queue,
al_get_keyboard_event_source());
232
233 al_clear_to_color(al_map_rgb(0,
0,
0));
234 al_flip_display();
235
236 al_start_timer(timer
);
237
238 while(!exit) {
239 ALLEGRO_EVENT ev
;
240 al_wait_for_event(event_queue,
&ev
);
241
242 if(ev.type
== ALLEGRO_EVENT_TIMER
) {
243 if(key[KEY_W
] && paddle_one_y
>= 4.
0) {
244 paddle_one_y
-= 4.
0;
245 paddle_one_bb_top
-= 4.
0;
246 paddle_one_bb_bottom
-= 4.
0;
247 }
248 if(key[KEY_S
] && paddle_one_y
<= SCREEN_H - PONG_PADDLE_H
- 4.
0) {
249 paddle_one_y
+= 4.
0;
250 paddle_one_bb_bottom
+= 4.
0;
251 paddle_one_bb_top
+= 4.
0;
252 }
253 if(key[KEY_UP
] && paddle_two_y
>= 4.
0) {
254 paddle_two_y
-= 4.
0;
255 paddle_two_bb_top
-= 4.
0;
256 paddle_two_bb_bottom
-= 4.
0;
257 }
258 if(key[KEY_DOWN
] && paddle_two_y
<= SCREEN_H - PONG_PADDLE_H
- 4.
0) {
259 paddle_two_y
+= 4.
0;
260 paddle_two_bb_bottom
+= 4.
0;
261 paddle_two_bb_top
+= 4.
0;
262 }
263
264 if(ball_y
< 0 || ball_y
> SCREEN_H - BALL_SIZE
) {
265 ball_dy
= -ball_dy
;
266 }
267
268 // Check to see if there is a collision with the left paddle.
269 if((ball_x
<= paddle_one_bb_right
)&&(ball_y
> paddle_one_bb_top
)&&(ball_y
< paddle_one_bb_bottom
)) {
270 ball_dx
= -ball_dx
;
271 }
272 // Check to see if there is a collision with the right paddle.
273 if((ball_x
>= paddle_two_bb_left
)&&(ball_y
> paddle_two_bb_top
)&&(ball_y
< paddle_two_bb_bottom
)) {
274 ball_dx
= -ball_dx
;
275 }
276
277 // Check to see if there is a collision with the left goal.
278 if(ball_x
<= goal_left_bb
) {
279 ball_dx
= -ball_dx
;
280 player_2_score
++;
281 }
282 // Check to see if there is a collision with the right goal.
283 if(ball_x
>= goal_right_bb
) {
284 ball_dx
= -ball_dx
;
285 player_1_score
++;
286 }
287
288 ball_x
+= ball_dx
;
289 ball_y
+= ball_dy
;
290
291 redraw
= true;
292 }
293 else if(ev.type
== ALLEGRO_KEY_ESCAPE
) {
294 break;
295 }
296 else if(ev.type
== ALLEGRO_EVENT_KEY_DOWN
) {
297 switch(ev.keyboard.keycode
) {
298 case ALLEGRO_KEY_W:
299 key[KEY_W
] = true;
300 break;
301 case ALLEGRO_KEY_S:
302 key[KEY_S
] = true;
303 break;
304 case ALLEGRO_KEY_UP:
305 key[KEY_UP
] = true;
306 break;
307 case ALLEGRO_KEY_DOWN:
308 key[KEY_DOWN
] = true;
309 break;
310 }
311 }
312 else if(ev.type
== ALLEGRO_EVENT_KEY_UP
) {
313 switch(ev.keyboard.keycode
) {
314 case ALLEGRO_KEY_W:
315 key[KEY_W
] = false;
316 break;
317 case ALLEGRO_KEY_S:
318 key[KEY_S
] = false;
319 break;
320 case ALLEGRO_KEY_UP:
321 key[KEY_UP
] = false;
322 break;
323 case ALLEGRO_KEY_DOWN:
324 key[KEY_DOWN
] = false;
325 break;
326 case ALLEGRO_KEY_ESCAPE:
327 exit = true;
328 break;
329 }
330 }
331
332 if(redraw
&& al_is_event_queue_empty(event_queue
)) {
333 redraw
= false;
334
335 string s1, s2
;
336
337 stringstream ss
;
338 ss
<< player_1_score
;
339 s1
= ss.str
();
340 ss.str
("");
341 ss
<< player_2_score
;
342 s2
= ss.str
();
343
344 al_clear_to_color(al_map_rgb(0,
0,
0));
345
346 al_draw_bitmap(paddle_one, PADDLE_ONE_X, paddle_one_y,
0);
347 al_draw_bitmap(paddle_two, PADDLE_TWO_X, paddle_two_y,
0);
348
349 al_draw_bitmap(divider, divider_x, divider_y,
0);
350
351 al_draw_text(p1_score_font,
al_map_rgb(255,
255,
255),
(SCREEN_W / 4.
0),
((SCREEN_H / 2.
0) - 36), ALLEGRO_ALIGN_CENTRE, s1.c_str
());
352 al_draw_text(p2_score_font,
al_map_rgb(255,
255,
255),
((SCREEN_W / 4.
0)*3.
0),
((SCREEN_H / 2.
0) - 36), ALLEGRO_ALIGN_CENTRE, s2.c_str
());
353
354 al_draw_bitmap(ball, ball_x, ball_y,
0);
355
356 al_draw_bitmap(left_goal, goal_left_x, goal_left_y,
0);
357 al_draw_bitmap(right_goal, goal_right_x, goal_right_y,
0);
358
359 al_flip_display();
360 }
361 }
362
363 al_destroy_bitmap(paddle_one
);
364 al_destroy_bitmap(paddle_two
);
365 al_destroy_bitmap(ball
);
366 al_destroy_timer(timer
);
367 al_destroy_display(display
);
368 al_destroy_event_queue(event_queue
);
369
370 return 0;
371}