1
2#include <stdio.h>
3#include <math.h>
4#include <windows.h>
5#pragma comment(lib,"ws2_32.lib")
6
7#include "allegro5/allegro.h"
8#include "allegro5/allegro_image.h"
9#include "allegro5/allegro_native_dialog.h"
10#include <allegro5/allegro_font.h>
11#include <allegro5/allegro_ttf.h>
12
13#include "Main_loc.h"
14
15const float
16 FPS
= 60,
17 pi
= 3.
14159265;
18
19const int
20 SCREEN_W = 800,
21 SCREEN_H = 600,
22 GAME_AREA_W
= 600,
23 GAME_AREA_H
= 500,
24 GAME_AREA_OFFSX
= 45,
25 GAME_AREA_OFFSY
= 45,
26 GAME_AREA_BORDER_W
= 10,
27 GAME_AREA_BORDER_H
= 10,
28 TANK_SIZE
= 26,
29 TANK_OFFS_X
= 12,
30 TANK_OFFS_Y
= 12,
31 BULLET_OFFS_X
= 2,
32 BULLET_OFFS_Y
= 2,
33 TANK_SPEED
= 1,
34 BULLET_SPEED
= 3,
35 BULLET_COUNT
= 60,
36 INFO_TEXT_X
= 670,
37 PLAYER_TEXT_Y
= 60,
38 ENEMY_TEXT_Y
= 150,
39 ENEMY_DIST_OFFSET
= 25,
40 ENEMY_FIRE_OFFSET
= 200;
41
42bool CollDetectWalls
(objectData_st
*object_p
);
43
44bool CollDetectTanks
(float object1_x,
float object1_y, objectData_st
*object2_p
);
45
46bool CollDetectShot
(objectData_st
*shot_p, objectData_st
*tank_p
);
47
48bool MoveTank
(objectData_st
*tank1_p, objectData_st
*tank2_p,
bool *key_p
);
49
50bool SetEnemyDirectionRight
(objectData_st
*tank1_p, objectData_st
*tank2_p
);
51
52bool SetEnemyDirectionLeft
(objectData_st
*tank1_p, objectData_st
*tank2_p
);
53
54bool SetEnemyDirectionFwd
(objectData_st
*tank1_p, objectData_st
*tank2_p
);
55
56bool SetEnemyFire
(objectData_st
*tank1_p, objectData_st
*tank2_p
);
57
58int
59 main
(int argc,
char **argv
)
60 {
61 ALLEGRO_BITMAP
62 *backGround
= NULL
;
63
64 ALLEGRO_FONT
65 *font;
66
67 ALLEGRO_DISPLAY
68 *display
= NULL
;
69
70 ALLEGRO_EVENT_QUEUE
71 *event_queue
= NULL
;
72
73 ALLEGRO_EVENT
74 ev
;
75
76 ALLEGRO_KEYBOARD_STATE
77 kbdstate
;
78
79 ALLEGRO_TIMER
80 *timer
= NULL
;
81
82 bool
83 redraw
= true,
84 key[5] = { false,
false,
false,
false,
false },
85 enKey
[5] = { false,
false,
false,
false,
false },
86 doexit
= false;
87
88 char
89 tmpText
[255];
90
91 int
92 counter1
= 0,
93 counter2
= 0;
94
95 objectData_st
96 playerShot
=
97 {
98 NULL,
/* ALLEGRO_BITMAP *bitmap */
99 0.
0,
/* float x */
100 0.
0,
/* float y */
101 0.
0,
/* float angle */
102 0.
0,
/* float angle */
103 3.
0,
/* float speed */
104 0,
/* int cnt */
105 0,
/* int fireCnt */
106 0,
/* int points */
107 10,
/* type */
108 false,
/* bool active */
109 false /* bool hit */
110 },
111
112 playerTank
=
113 {
114 NULL,
/* ALLEGRO_BITMAP *bitmap */
115 (SCREEN_W / 2.
0 - TANK_SIZE
/ 2.
0),
/* float x */
116 (4.
0 * (SCREEN_H / 5.
0) - TANK_SIZE
/ 2.
0),
/* float y */
117 0.
0,
/* float angle */
118 0.
0,
/* float angle */
119 1.
0,
/* float speed */
120 0,
/* int cnt */
121 0,
/* int fireCnt */
122 0,
/* int points */
123 0,
/* type */
124 true,
/* bool active */
125 false /* bool hit */
126 },
127
128 enemyShot
=
129 {
130 NULL,
/* ALLEGRO_BITMAP *bitmap */
131 0.
0,
/* float x */
132 0.
0,
/* float y */
133 0.
0,
/* float angle */
134 0.
0,
/* float angle */
135 3.
0,
/* float speed */
136 0,
/* int cnt */
137 0,
/* int cnt */
138 0,
/* int points */
139 11,
/* type */
140 false,
/* bool active */
141 false /* bool hit */
142 },
143 enemyTank
=
144 {
145 NULL,
/* ALLEGRO_BITMAP *bitmap */
146 (SCREEN_W / 2.
0 - TANK_SIZE
/ 2.
0),
/* float x */
147 (1.
0 * (SCREEN_H / 5.
0) - TANK_SIZE
/ 2.
0),
/* float y */
148 pi,
/* float angle */
149 pi,
/* float angle */
150 1.
0,
/* float speed */
151 0,
/* int cnt */
152 0,
/* int cnt */
153 0,
/* int points */
154 1,
/* type */
155 true,
/* bool active */
156 false /* bool hit */
157 };
158
159 fprintf(stderr,
"Starting!\n");
160
161 /*******************************************/
162 /* Init Allegro */
163 if(!al_init())
164 {
165 fprintf(stderr,
"Failed to initialize allegro!\n");
166 }
167
168 /*******************************************/
169 /* Create timer */
170 timer
= al_create_timer(1.
0 / FPS
);
171 if(!timer
)
172 {
173 al_show_native_message_box(display,
"Error",
"Error",
"Failed to create timer!",
174 NULL, ALLEGRO_MESSAGEBOX_ERROR
);
175
176 al_destroy_timer(timer
);
177 return 0;
178
179 }
180
181 /*******************************************/
182 /* Init image addon */
183 if(!al_init_image_addon()) {
184 al_show_native_message_box(display,
"Error",
"Error",
"Failed to initialize al_init_image_addon!",
185 NULL, ALLEGRO_MESSAGEBOX_ERROR
);
186
187 al_destroy_timer(timer
);
188 return 0;
189 }
190
191 /*******************************************/
192 /* Start keyboard detection */
193 if(!al_install_keyboard()) {
194 al_show_native_message_box(display,
"Error",
"Error",
"Failed to initialize the keyboard!",
195 NULL, ALLEGRO_MESSAGEBOX_ERROR
);
196
197 al_destroy_timer(timer
);
198 return 0;
199 }
200
201 /*******************************************/
202 /* Create display */
203 display
= al_create_display(SCREEN_W,
SCREEN_H);
204 if(!display
)
205 {
206 al_show_native_message_box(display,
"Error",
"Error",
"Failed to create display!",
207 NULL, ALLEGRO_MESSAGEBOX_ERROR
);
208
209 al_destroy_display(display
);
210 al_destroy_timer(timer
);
211 return 0;
212 }
213
214 /*******************************************/
215 /* Text */
216 /* Create the info text */
217
218 /* initialize the font addon (really? ttf below...) */
219 al_init_font_addon();
220
221 /* initialize the ttf (True Type Font) addon */
222 al_init_ttf_addon();
223
224 font = al_load_ttf_font(".\\data\\pixlkrud.ttf",
18,
0 );
225
226 if (!font){
227 al_show_native_message_box(display,
"Error",
"Error",
"Failed to load 'pixlkrud.ttf!",
228 NULL, ALLEGRO_MESSAGEBOX_ERROR
);
229
230 al_destroy_font(font);
231 al_destroy_display(display
);
232 al_destroy_timer(timer
);
233 return 0;
234 }
235
236 /*******************************************/
237 /* Background bitmap */
238 /* Create bitmap picture background */
239 backGround
= al_load_bitmap(".\\data\\backGround.bmp");
240 if(!backGround
) {
241 al_show_native_message_box(display,
"Error",
"Error",
"Failed to load image background!",
242 NULL, ALLEGRO_MESSAGEBOX_ERROR
);
243
244 al_destroy_bitmap(backGround
);
245 al_destroy_font(font);
246 al_destroy_display(display
);
247 al_destroy_timer(timer
);
248 return 0;
249 }
250
251 /* Mask "Magic pink" */
252 al_set_target_bitmap(backGround
);
253 al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA
);
254 al_convert_mask_to_alpha(backGround,
al_map_rgba_f(1,
0,
1,
1));
255
256 /*******************************************/
257 /* Player bitmaps */
258 /* Create bitmap picture player playerShot */
259 playerShot.bitmap
= al_load_bitmap(".\\data\\Bullet.bmp");
260 if(!playerShot.bitmap
) {
261 al_show_native_message_box(display,
"Error",
"Error",
"Failed to load image playerShot.bitmap!",
262 NULL, ALLEGRO_MESSAGEBOX_ERROR
);
263
264 al_destroy_bitmap(playerShot.bitmap
);
265 al_destroy_bitmap(backGround
);
266 al_destroy_font(font);
267 al_destroy_display(display
);
268 al_destroy_timer(timer
);
269 return 0;
270 }
271
272 /* Mask "Magic pink" */
273 al_set_target_bitmap(playerShot.bitmap
);
274 al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA
);
275 al_convert_mask_to_alpha(playerShot.bitmap,
al_map_rgba_f(1,
0,
1,
1));
276
277 /* Create bitmap picture player tank */
278 playerTank.bitmap
= al_load_bitmap(".\\data\\TankBlack.bmp");
279 if(!playerTank.bitmap
) {
280 al_show_native_message_box(display,
"Error",
"Error",
"Failed to load image playerTank.bitmap!",
281 NULL, ALLEGRO_MESSAGEBOX_ERROR
);
282
283 al_destroy_bitmap(playerTank.bitmap
);
284 al_destroy_bitmap(playerShot.bitmap
);
285 al_destroy_bitmap(backGround
);
286 al_destroy_font(font);
287 al_destroy_display(display
);
288 al_destroy_timer(timer
);
289 return 0;
290 }
291
292 /* Mask "Magic pink" */
293 al_set_target_bitmap(playerTank.bitmap
);
294 al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA
);
295 al_convert_mask_to_alpha(playerTank.bitmap,
al_map_rgba_f(1,
0,
1,
1));
296
297 /*******************************************/
298 /* Enemy bitmaps */
299 /* Create bitmap picture enemy playerShot */
300 enemyShot.bitmap
= al_load_bitmap(".\\data\\Bullet.bmp");
301 if(!enemyShot.bitmap
) {
302 al_show_native_message_box(display,
"Error",
"Error",
"Failed to load image enemyShot.bitmap!",
303 NULL, ALLEGRO_MESSAGEBOX_ERROR
);
304
305 al_destroy_bitmap(enemyShot.bitmap
);
306 al_destroy_bitmap(playerTank.bitmap
);
307 al_destroy_bitmap(playerShot.bitmap
);
308 al_destroy_bitmap(backGround
);
309 al_destroy_font(font);
310 al_destroy_display(display
);
311 al_destroy_timer(timer
);
312 return 0;
313 }
314
315 /* Mask "Magic pink" */
316 al_set_target_bitmap(enemyShot.bitmap
);
317 al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA
);
318 al_convert_mask_to_alpha(enemyShot.bitmap,
al_map_rgba_f(1,
0,
1,
1));
319
320 /* Create bitmap picture enemy tank */
321 enemyTank.bitmap
= al_load_bitmap(".\\data\\TankRed.bmp");
322 if(!enemyTank.bitmap
) {
323 al_show_native_message_box(display,
"Error",
"Error",
"Failed to load image enemyTank.bitmap!",
324 NULL, ALLEGRO_MESSAGEBOX_ERROR
);
325
326 al_destroy_bitmap(enemyTank.bitmap
);
327 al_destroy_bitmap(enemyShot.bitmap
);
328 al_destroy_bitmap(playerTank.bitmap
);
329 al_destroy_bitmap(playerShot.bitmap
);
330 al_destroy_bitmap(backGround
);
331 al_destroy_font(font);
332 al_destroy_display(display
);
333 al_destroy_timer(timer
);
334 return 0;
335 }
336
337 /* Mask "Magic pink" */
338 al_set_target_bitmap(enemyTank.bitmap
);
339 al_set_blender(ALLEGRO_ADD, ALLEGRO_ONE, ALLEGRO_INVERSE_ALPHA
);
340 al_convert_mask_to_alpha(enemyTank.bitmap,
al_map_rgba_f(1,
0,
1,
1));
341
342 /* Create event queue */
343 event_queue
= al_create_event_queue();
344 if(!event_queue
)
345 {
346 al_destroy_event_queue(event_queue
);
347 al_destroy_bitmap(enemyTank.bitmap
);
348 al_destroy_bitmap(enemyShot.bitmap
);
349 al_destroy_bitmap(playerTank.bitmap
);
350 al_destroy_bitmap(playerShot.bitmap
);
351 al_destroy_bitmap(backGround
);
352 al_destroy_font(font);
353 al_destroy_display(display
);
354 al_destroy_timer(timer
);
355 return 0;
356 }
357
358 /* Display event */
359 al_register_event_source(event_queue,
al_get_display_event_source(display
));
360
361 /* Timer event */
362 al_register_event_source(event_queue,
al_get_timer_event_source(timer
));
363
364 /* Key event */
365 //al_register_event_source(event_queue, al_get_keyboard_event_source());
366
367 /* Clear screen to white */
368 al_set_target_bitmap(al_get_backbuffer(display
));
369 al_clear_to_color(al_map_rgb(255,
255,
255));
370 al_flip_display();
371
372 /* Start timer */
373 al_start_timer(timer
);
374
375 /* Draw window area */
376 al_set_target_backbuffer(display
);
377 al_clear_to_color(al_map_rgb(255,
255,
255));
378
379 /* Draw text */
380 al_draw_text(font,
al_map_rgb(200,
0,
0),
(SCREEN_W / 2),
(SCREEN_H / 2), ALLEGRO_ALIGN_CENTRE,
"Press fire when ready");
381
382 al_flip_display();
383
384 /* SPACE pressed */
385 do
386 {
387 al_get_keyboard_state(&kbdstate
);
388 } while (al_key_down(&kbdstate, ALLEGRO_KEY_SPACE
) != true);
389
390 /* SPACE released */
391 do
392 {
393 al_get_keyboard_state(&kbdstate
);
394 } while (al_key_down(&kbdstate, ALLEGRO_KEY_SPACE
) == true);
395
396
397 /*************/
398 /* MAIN LOOP */
399
400 fprintf(stderr,
"Starting main loop\n");
401 while(doexit
== false)
402 {
403 al_wait_for_event(event_queue,
&ev
);
404 if(ev.type
== ALLEGRO_EVENT_TIMER
)
405 {
406 /* Enemy tank - checked if turn left */
407 if (SetEnemyDirectionLeft
(&enemyTank,
&playerTank
))
408 {
409 enKey
[KEY_LEFT
] = true;
410 enKey
[KEY_RIGHT
] = false;
411 }
412 /* Enemy tank - checked if turn right */
413 else if (enKey
[KEY_RIGHT
] = SetEnemyDirectionRight
(&enemyTank,
&playerTank
))
414 {
415 enKey
[KEY_RIGHT
] = true;
416 enKey
[KEY_LEFT
] = false;
417 }
418
419 enKey
[KEY_UP
] = SetEnemyDirectionFwd
(&enemyTank,
&playerTank
);
420 enKey
[KEY_SPACE
] = SetEnemyFire
(&enemyTank,
&playerTank
);
421
422 /* TODO: Use keyb event! */
423 al_get_keyboard_state(&kbdstate
);
424 key[KEY_UP
] = al_key_down(&kbdstate, ALLEGRO_KEY_UP
);
425 key[KEY_DOWN
] = al_key_down(&kbdstate, ALLEGRO_KEY_DOWN
);
426 key[KEY_LEFT
] = al_key_down(&kbdstate, ALLEGRO_KEY_LEFT
);
427 key[KEY_RIGHT
] = al_key_down(&kbdstate, ALLEGRO_KEY_RIGHT
);
428 key[KEY_SPACE
] = al_key_down(&kbdstate, ALLEGRO_KEY_SPACE
);
429
430 if (al_key_down(&kbdstate, ALLEGRO_KEY_ESCAPE
))
431 {
432 /* Quit */
433 break;
434 }
435
436 enemyTank.active
= MoveTank
(&playerTank,
&enemyTank,
&key[0]);
437 playerTank.active
= MoveTank
(&enemyTank,
&playerTank,
&enKey
[0]);
438
439 /* Check if player FIRE */
440 if (key[KEY_SPACE
] && !playerShot.active
&& playerTank.active
)
441 {
442 /* Shoot! */
443 playerShot.x
= playerTank.x
;
444 playerShot.y
= playerTank.y
;
445 playerShot.movAngle
= playerTank.movAngle
;
446 playerShot.rotAngle
= playerShot.movAngle
;
447 playerShot.active
= true;
448 playerShot.cnt
= 0;
449 fprintf(stderr,
"Player shoot! playerShot.cnt = %d\n", playerShot.cnt
);
450 }
451
452 if (playerShot.active
&& playerShot.cnt
< BULLET_COUNT
)
453 {
454 /* Bullet's moving */
455 playerShot.y
-= playerShot.speed
* cos(playerShot.movAngle
);
456 playerShot.x
+= playerShot.speed
* sin(playerShot.movAngle
);
457 playerShot.cnt
+= 1;
458 }
459 else if(playerShot.active
)
460 {
461 /* Bullet reached end */
462 playerShot.cnt
= 0;
463 playerShot.active
= false;
464 }
465
466 /* Collision detection player bullet / enemy tank */
467 if (CollDetectShot
(&playerShot,
&enemyTank
) && playerShot.active
)
468 {
469 /* Collision */
470 fprintf(stderr,
"Collision (player shot - enemy tank)!\n\n");
471 playerShot.active
= false;
472 playerTank.active
= false;
473 playerTank.points
+= 1;
474
475 enemyTank.hit
= true;
476 enemyTank.active
= false;
477 enemyTank.movAngle
= playerShot.movAngle
;
478 enemyTank.speed
= BULLET_SPEED
;
479 }
480
481
482
483 /* Check if enemy FIRE */
484 if (enKey
[KEY_SPACE
] && !enemyShot.active
&& enemyTank.active
)
485 {
486 /* Shoot! */
487 enemyShot.x
= enemyTank.x
;
488 enemyShot.y
= enemyTank.y
;
489 enemyShot.movAngle
= enemyTank.movAngle
;
490 enemyShot.rotAngle
= enemyTank.movAngle
;
491 enemyShot.active
= true;
492 enemyShot.cnt
= 0;
493 fprintf(stderr,
"Enemy shoot! playerShot.cnt = %d\n", enemyShot.cnt
);
494 }
495
496 if (enemyShot.active
&& enemyShot.cnt
< BULLET_COUNT
)
497 {
498 /* Bullet's moving */
499 enemyShot.y
-= enemyShot.speed
* cos(enemyShot.movAngle
);
500 enemyShot.x
+= enemyShot.speed
* sin(enemyShot.movAngle
);
501 enemyShot.cnt
+= 1;
502 }
503 else if(enemyShot.active
)
504 {
505 /* Bullet reached end */
506 enemyShot.cnt
= 0;
507 enemyShot.active
= false;
508 }
509
510 /* Collision detection player bullet / enemy tank */
511 if (CollDetectShot
(&enemyShot,
&playerTank
) && enemyShot.active
)
512 {
513 /* Collision */
514 fprintf(stderr,
"Collision (enemy shot - player tank)!\n\n");
515 enemyShot.active
= false;
516 enemyTank.active
= false;
517 enemyTank.points
+= 1;
518
519 playerTank.hit
= true;
520 playerTank.active
= false;
521 playerTank.movAngle
= enemyShot.movAngle
;
522 playerTank.speed
= BULLET_SPEED
;
523 }
524
525 /* Collision detection outer walls (Y) */
526 (void) CollDetectWalls
(&playerTank
);
527
528 /* Collision detection outer walls */
529 (void) CollDetectWalls
(&enemyTank
);
530
531 redraw
= true;
532 }
533 else if(ev.type
== ALLEGRO_EVENT_DISPLAY_CLOSE
)
534 {
535 break;
536 }
537
538 if(redraw
&& al_is_event_queue_empty(event_queue
))
539 {
540 redraw
= false;
541
542 /* Draw window area */
543 al_set_target_backbuffer(display
);
544 al_clear_to_color(al_map_rgb(255,
255,
255));
545
546 /* Draw text */
547 al_draw_text(font,
al_map_rgb(200,
0,
0),
(SCREEN_W / 2),
(GAME_AREA_OFFSY
/ 2), ALLEGRO_ALIGN_CENTRE,
"T.A.N.K.S");
548
549 al_draw_text(font,
al_map_rgb(200,
0,
0), INFO_TEXT_X, PLAYER_TEXT_Y, ALLEGRO_ALIGN_LEFT,
"PLAYER");
550 sprintf(tmpText,
"%d", playerTank.points
);
551 al_draw_text(font,
al_map_rgb(200,
0,
0), INFO_TEXT_X, PLAYER_TEXT_Y
+ al_get_font_line_height(font), ALLEGRO_ALIGN_LEFT, tmpText
);
552
553 al_draw_text(font,
al_map_rgb(200,
0,
0), INFO_TEXT_X, ENEMY_TEXT_Y, ALLEGRO_ALIGN_LEFT,
"ENEMY");
554 sprintf(tmpText,
"%d", enemyTank.points
);
555 al_draw_text(font,
al_map_rgb(200,
0,
0), INFO_TEXT_X, ENEMY_TEXT_Y
+ al_get_font_line_height(font), ALLEGRO_ALIGN_LEFT, tmpText
);
556
557 /* Draw background */
558 al_draw_bitmap(backGround, GAME_AREA_OFFSX, GAME_AREA_OFFSY,
0);
559
560 /* Draw player */
561 al_draw_rotated_bitmap(playerTank.bitmap, TANK_OFFS_X, TANK_OFFS_Y, playerTank.x, playerTank.y, playerTank.rotAngle,
0);
562 if (playerShot.active
)
563 {
564 al_draw_rotated_bitmap(playerShot.bitmap, BULLET_OFFS_X, BULLET_OFFS_Y, playerShot.x, playerShot.y, playerShot.rotAngle,
0);
565 }
566
567 /* Draw enemy */
568 al_draw_rotated_bitmap(enemyTank.bitmap, TANK_OFFS_X, TANK_OFFS_Y, enemyTank.x, enemyTank.y, enemyTank.rotAngle,
0);
569 if (enemyShot.active
)
570 {
571 al_draw_rotated_bitmap(enemyShot.bitmap, BULLET_OFFS_X, BULLET_OFFS_Y, enemyShot.x, enemyShot.y, enemyShot.rotAngle,
0);
572 }
573
574 al_flip_display();
575 }
576 }
577
578 al_destroy_event_queue(event_queue
);
579 al_destroy_bitmap(enemyTank.bitmap
);
580 al_destroy_bitmap(enemyShot.bitmap
);
581 al_destroy_bitmap(playerTank.bitmap
);
582 al_destroy_bitmap(playerShot.bitmap
);
583 al_destroy_bitmap(backGround
);
584 al_destroy_font(font);
585 al_destroy_display(display
);
586 al_destroy_timer(timer
);
587
588 al_uninstall_system();
589
590 return 0;
591 }