1//global variables
2const int NUM_BULLETS
= 5;
3const int NUM_ENEMIES
= 5;
4const int NUM_EXPLOSIONS
= 5;
5enum STATE
{ TITLE, PLAYING, GAMEOVER, IDLE, CHASING, CONTINUE
};
6float CheckDistance
(Player
&player, Enemy enemy
[],
int size
);
7float AngleToTarget
(Enemy enemy
[],
int size, Player
&player
);
8
9Player player
;
10Enemy enemy
[NUM_ENEMIES
];
11
12//prototypes
13void InitPlayer
(Player
&player,
ALLEGRO_BITMAP *image
);
14void DrawPlayer
(Player
&player
);
15
16void InitEnemy
(Enemy enemy
[],
int size,
ALLEGRO_BITMAP *image,
ALLEGRO_SAMPLE *explode
);
17void DrawEnemy
(Enemy enemy
[],
int size
);
18void StartEnemy
(Enemy enemy
[],
int size
);
19void UpdateEnemy
(Enemy enemy
[],
int size
);
20void CollideEnemy
(Enemy enemy
[],
int size, Player
&player, Explosion explosions
[],
int eSize
);
21
22void ChangeState
(int &state,
int newState
);
23
24int main
()
25{
26 bool done
= false;
27 bool draw
= true;
28 int FPS
= 60;
29 int state
= -1;
30 int threshold
= 175;
31 enum KEYS
{ UP, LEFT, RIGHT, DOWN, SPACE
};
32 bool keys
[5] = { false,
false,
false,
false,
false };
33
34 if (!al_init())
35 {
36 al_show_native_message_box(0,
0,
"Error",
"Falied to initialize allegro",
0,
0);
37 return -1;
38 }
39
40 display
= al_create_display(ScreenWidth, ScreenHeight
);
41
42 if (!display
)
43 {
44 al_show_native_message_box(0,
0,
"Error",
"Falied to initialize the display",
0,
0);
45 return -1;
46 }
47
48 al_install_keyboard();
49 al_init_primitives_addon();
50 al_init_image_addon();
51 al_init_font_addon();
52 al_init_ttf_addon();
53 al_install_audio();
54 al_init_acodec_addon();
55
56 playerImage
= al_load_bitmap("Ship.png");
57 enemyImage
= al_load_bitmap("alien4.png");
58
59 ChangeState
(state, TITLE
);
60
61 srand(time(NULL
));
62 InitPlayer
(player, playerImage
);
63 InitBullet
(bullets, NUM_BULLETS, bulletImage, laser
);
64 InitEnemy
(enemy, NUM_ENEMIES, enemyImage, explode
);
65 InitExplosions
(explosions, NUM_EXPLOSIONS, explosion
);
66
67 font18
= al_load_font("arial.ttf",
18,
0);
68 timer
= al_create_timer(1.
0 / FPS
);
69 event_queue
= al_create_event_queue();
70
71 al_register_event_source(event_queue,
al_get_timer_event_source(timer
));
72 al_register_event_source(event_queue,
al_get_keyboard_event_source());
73 al_register_event_source(event_queue,
al_get_display_event_source(display
));
74
75 al_start_timer(timer
);
76
77 while (!done
)
78 {
79 ALLEGRO_EVENT ev
;
80 al_wait_for_event(event_queue,
&ev
);
81
82 if (ev.type
== ALLEGRO_EVENT_TIMER
)
83 {
84 draw
= true;
85
86 if (state
== TITLE
)
87 {
88
89 }
90 else if (state
== PLAYING
)
91 {
92 UpdateExplosions
(explosions, NUM_EXPLOSIONS
);
93 UpdateBullet
(bullets, NUM_BULLETS
);
94 StartEnemy
(enemy, NUM_ENEMIES
);
95 UpdateEnemy
(enemy, NUM_ENEMIES
);
96 CollideBullet
(bullets, NUM_BULLETS, enemy, NUM_ENEMIES, player, explosions, NUM_EXPLOSIONS
);
97 CollideEnemy
(enemy, NUM_ENEMIES, player, explosions, NUM_EXPLOSIONS
);
98
99 if (state
== IDLE
)
100 {
101 if (threshold
> CheckDistance
(player, enemy, NUM_ENEMIES
))
102 ChangeState
(state, CHASING
);
103 }
104 else if (state
== CHASING
)
105 {
106 if (threshold
< CheckDistance
(player, enemy, NUM_ENEMIES
))
107 ChangeState
(state, CONTINUE
);
108 else
109 {
110 float angle
= AngleToTarget
(enemy, NUM_ENEMIES, player
);
111 enemy
[NUM_ENEMIES
].y
+= (2 * sin(angle
));
112 enemy
[NUM_ENEMIES
].x
+= (2 * cos(angle
));
113 }
114 }
115 else if (state
== CONTINUE
)
116 {
117 UpdateEnemy
(enemy, NUM_ENEMIES
);
118 }
119 if (player.lives
<= 0)
120 ChangeState
(state, GAMEOVER
);
121 }
122 else if (state
== GAMEOVER
)
123 {
124
125 }
126 }
127
128 else if (ev.type
== ALLEGRO_EVENT_KEY_DOWN
)
129 {
130 switch (ev.keyboard.keycode
)
131 {
132 case ALLEGRO_KEY_DOWN:
133 keys
[DOWN
] = true;
134 break;
135 case ALLEGRO_KEY_LEFT:
136 keys
[LEFT
] = true;
137 break;
138 case ALLEGRO_KEY_RIGHT:
139 keys
[RIGHT
] = true;
140 break;
141 case ALLEGRO_KEY_UP:
142 keys
[UP
] = true;
143 break;
144 case ALLEGRO_KEY_ESCAPE:
145 done
= true;
146 break;
147 case ALLEGRO_KEY_SPACE:
148 keys
[SPACE
] = true;
149 if (state
== TITLE
)
150 ChangeState
(state, PLAYING
);
151 else if (state
== PLAYING
)
152 FireBullet
(bullets, NUM_BULLETS, player
);
153 else if (state
== GAMEOVER
)
154 ChangeState
(state, PLAYING
);
155 break;
156 }
157 }
158 else if (ev.type
== ALLEGRO_EVENT_KEY_UP
)
159 {
160 switch (ev.keyboard.keycode
)
161 {
162 case ALLEGRO_KEY_DOWN:
163 keys
[DOWN
] = false;
164 break;
165 case ALLEGRO_KEY_LEFT:
166 keys
[LEFT
] = false;
167 break;
168 case ALLEGRO_KEY_RIGHT:
169 keys
[RIGHT
] = false;
170 break;
171 case ALLEGRO_KEY_UP:
172 keys
[UP
] = false;
173 break;
174 case ALLEGRO_KEY_SPACE:
175 keys
[SPACE
] = false;
176 break;
177 }
178 }
179 else if (ev.type
== ALLEGRO_EVENT_DISPLAY_CLOSE
)
180 {
181 done
= true;
182 }
183
184 if (draw
&& al_is_event_queue_empty(event_queue
))
185 {
186 draw
= false;
187
188 if (state
== TITLE
)
189 {
190 al_draw_bitmap(Title,
0,
0,
0);
191 }
192 else if (state
== PLAYING
)
193 {
194 al_draw_bitmap(background,
0,
0,
0);
195 DrawPlayer
(player
);
196 DrawBullet
(bullets, NUM_BULLETS
);
197 DrawEnemy
(enemy, NUM_ENEMIES
);
198 DrawExplosions
(explosions, NUM_EXPLOSIONS
);
199
200 al_draw_textf(font18,
al_map_rgb(255,
0,
0),
5,
5,
0,
"Lives: %i", player.lives
);
201 al_draw_textf(font18,
al_map_rgb(255,
0,
0),
5,
580,
0,
"Score: %i", player.score
);
202 }
203 else if (state
== GAMEOVER
)
204 {
205 al_draw_bitmap(GameOver,
0,
0,
0);
206
207 al_draw_textf(font18,
al_map_rgb(255,
0,
0), ScreenWidth
/ 2, ScreenHeight
/ 2, ALLEGRO_ALIGN_CENTRE,
"Final Score: %i", player.score
);
208 }
209 al_flip_display();
210 al_clear_to_color(al_map_rgb(0,
0,
0));
211 }
212 }
213
214 al_destroy_display(display
);
215 al_destroy_event_queue(event_queue
);
216 al_destroy_timer(timer
);
217 al_destroy_bitmap(playerImage
);
218 al_destroy_bitmap(enemyImage
);
219
220 return 0;
221
222}
223void InitPlayer
(Player
&player,
ALLEGRO_BITMAP *image
= NULL
)
224{
225 player.ID
= PLAYER
;
226 player.x
= 55;
227 player.y
= ScreenHeight
/ 2;
228 player.lives
= 5;
229 player.speed
= 6;
230 player.boundx
= 25;
231 player.boundy
= 25;
232 player.score
= 0;
233 player.frameWidth
= 50;
234 player.frameHeight
= 50;
235
236 if (image
!= NULL
)
237 player.image
= image
;
238}
239void DrawPlayer
(Player
&player
)
240{
241 al_draw_bitmap(player.image, player.x
- player.frameWidth
/ 2, player.y
- player.frameHeight
/ 2,
0);
242}
243void InitEnemy
(Enemy enemy
[],
int size,
ALLEGRO_BITMAP *image
= NULL,
ALLEGRO_SAMPLE *explode
= NULL
)
244{
245 for (int i
= 0; i
< size
; i
++)
246 {
247 enemy
[i
].ID
= ENEMY
;
248 enemy
[i
].live
= false;
249 enemy
[i
].speed
= 4;
250 enemy
[i
].boundx
= 15;
251 enemy
[i
].boundy
= 15;
252
253 if (image
!= NULL
)
254 enemy
[i
].image
= image
;
255 if (explode
!= NULL
)
256 enemy
[i
].explode
= explode
;
257 }
258}
259void DrawEnemy
(Enemy enemy
[],
int size
)
260{
261 for (int i
= 0; i
< size
; i
++)
262 {
263 if (enemy
[i
].live
)
264 al_draw_bitmap(enemy
[i
].image, enemy
[i
].x
- 10, enemy
[i
].y
- 15,
0);
265 }
266}
267void StartEnemy
(Enemy enemy
[],
int size
)
268{
269 for (int i
= 0; i
< size
; i
++)
270 {
271 if (!enemy
[i
].live
)
272 {
273 if (rand() %
500 == 0)
274 {
275 enemy
[i
].live
= true;
276 enemy
[i
].x
= ScreenWidth
;
277 enemy
[i
].y
= 50 + rand() %
(ScreenHeight
- 100);
278
279 break;
280 }
281 }
282 }
283}
284void UpdateEnemy
(Enemy enemy
[],
int size
)
285{
286 for (int i
= 0; i
< size
; i
++)
287 {
288 if (enemy
[i
].live
)
289 {
290 enemy
[i
].x
-= enemy
[i
].speed
;
291 }
292 }
293}
294void CollideEnemy
(Enemy enemy
[],
int size, Player
&player, Explosion explosions
[],
int eSize
)
295{
296 for (int i
= 0; i
< size
; i
++)
297 {
298 if (enemy
[i
].live
)
299 {
300 if (enemy
[i
].x
- enemy
[i
].boundx
< player.x
+ player.boundx
&&
301 enemy
[i
].x
+ enemy
[i
].boundx
> player.x
- player.boundx
&&
302 enemy
[i
].y
- enemy
[i
].boundy
< player.y
+ player.boundy
&&
303 enemy
[i
].y
+ enemy
[i
].boundy
> player.y
- player.boundy
)
304 {
305 player.lives--
;
306 enemy
[i
].live
= false;
307 StartExplosions
(explosions, eSize, player.x, player.y
);
308 al_play_sample(enemy
[i
].explode,
0.
5,
0,
1, ALLEGRO_PLAYMODE_ONCE, NULL
);
309 }
310 else if (enemy
[i
].x
< 0)
311 {
312 enemy
[i
].live
= false;
313 }
314 }
315 }
316}
317float CheckDistance
(Player
&player, Enemy enemy
[],
int size
)
318{
319 for (int i
= 0; i
< size
; i
++)
320 {
321 if (enemy
[i
].live
)
322 return sqrt(pow((float)player.x
- enemy
[i
].x,
2) + pow((float)player.y
- enemy
[i
].y,
2));
323 }
324
325}
326float AngleToTarget
(Enemy enemy
[],
int size, Player
&player
)
327{
328 for (int i
= 0; i
< size
; i
++)
329 {
330 if (enemy
[i
].live
)
331 {
332 float deltaX
= (enemy
[i
].x
- player.x
);
333 float deltaY
= (enemy
[i
].y
- player.y
);
334 return atan2(deltaX, deltaY
);
335 }
336 }
337}
338
339void ChangeState
(int &state,
int newState
)
340{
341 if (state
== PLAYING
)
342 {
343 al_stop_sample_instance(SongInstance
);
344 }
345
346 state
= newState
;
347
348 if (state
== PLAYING
)
349 {
350 InitPlayer
(player
);
351 InitBullet
(bullets, NUM_BULLETS
);
352 InitEnemy
(enemy, NUM_ENEMIES
);
353 InitExplosions
(explosions, NUM_EXPLOSIONS
);
354
355 al_play_sample_instance(SongInstance
);
356 }
357
358}