1 | /******************************************************************************************* |
2 | * |
3 | * raylib - sample game: asteroids |
4 | * |
5 | * Sample game developed by Ian Eito, Albert Martos and Ramon Santamaria |
6 | * |
7 | * This game has been created using raylib v1.3 (www.raylib.com) |
8 | * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) |
9 | * |
10 | * Copyright (c) 2015 Ramon Santamaria (@raysan5) |
11 | * |
12 | ********************************************************************************************/ |
13 | |
14 | #include "raylib.h" |
15 | |
16 | #include <math.h> |
17 | |
18 | #if defined(PLATFORM_WEB) |
19 | #include <emscripten/emscripten.h> |
20 | #endif |
21 | |
22 | //---------------------------------------------------------------------------------- |
23 | // Some Defines |
24 | //---------------------------------------------------------------------------------- |
25 | #define PLAYER_BASE_SIZE 20.0f |
26 | #define PLAYER_SPEED 6.0f |
27 | #define PLAYER_MAX_SHOOTS 10 |
28 | |
29 | #define METEORS_SPEED 2 |
30 | #define MAX_BIG_METEORS 4 |
31 | #define MAX_MEDIUM_METEORS 8 |
32 | #define MAX_SMALL_METEORS 16 |
33 | |
34 | //---------------------------------------------------------------------------------- |
35 | // Types and Structures Definition |
36 | //---------------------------------------------------------------------------------- |
37 | typedef struct Player { |
38 | Vector2 position; |
39 | Vector2 speed; |
40 | float acceleration; |
41 | float rotation; |
42 | Vector3 collider; |
43 | Color color; |
44 | } Player; |
45 | |
46 | typedef struct Shoot { |
47 | Vector2 position; |
48 | Vector2 speed; |
49 | float radius; |
50 | float rotation; |
51 | int lifeSpawn; |
52 | bool active; |
53 | Color color; |
54 | } Shoot; |
55 | |
56 | typedef struct Meteor { |
57 | Vector2 position; |
58 | Vector2 speed; |
59 | float radius; |
60 | bool active; |
61 | Color color; |
62 | } Meteor; |
63 | |
64 | //------------------------------------------------------------------------------------ |
65 | // Global Variables Declaration |
66 | //------------------------------------------------------------------------------------ |
67 | static const int screenWidth = 800; |
68 | static const int screenHeight = 450; |
69 | |
70 | static bool gameOver = false; |
71 | static bool pause = false; |
72 | static bool victory = false; |
73 | |
74 | // NOTE: Defined triangle is isosceles with common angles of 70 degrees. |
75 | static float shipHeight = 0.0f; |
76 | |
77 | static Player player = { 0 }; |
78 | static Shoot shoot[PLAYER_MAX_SHOOTS] = { 0 }; |
79 | static Meteor bigMeteor[MAX_BIG_METEORS] = { 0 }; |
80 | static Meteor mediumMeteor[MAX_MEDIUM_METEORS] = { 0 }; |
81 | static Meteor smallMeteor[MAX_SMALL_METEORS] = { 0 }; |
82 | |
83 | static int midMeteorsCount = 0; |
84 | static int smallMeteorsCount = 0; |
85 | static int destroyedMeteorsCount = 0; |
86 | |
87 | //------------------------------------------------------------------------------------ |
88 | // Module Functions Declaration (local) |
89 | //------------------------------------------------------------------------------------ |
90 | static void InitGame(void); // Initialize game |
91 | static void UpdateGame(void); // Update game (one frame) |
92 | static void DrawGame(void); // Draw game (one frame) |
93 | static void UnloadGame(void); // Unload game |
94 | static void UpdateDrawFrame(void); // Update and Draw (one frame) |
95 | |
96 | //------------------------------------------------------------------------------------ |
97 | // Program main entry point |
98 | //------------------------------------------------------------------------------------ |
99 | int main(void) |
100 | { |
101 | // Initialization (Note windowTitle is unused on Android) |
102 | //--------------------------------------------------------- |
103 | InitWindow(screenWidth, screenHeight, "sample game: asteroids" ); |
104 | |
105 | InitGame(); |
106 | |
107 | #if defined(PLATFORM_WEB) |
108 | emscripten_set_main_loop(UpdateDrawFrame, 0, 1); |
109 | #else |
110 | SetTargetFPS(60); |
111 | //-------------------------------------------------------------------------------------- |
112 | |
113 | // Main game loop |
114 | while (!WindowShouldClose()) // Detect window close button or ESC key |
115 | { |
116 | // Update and Draw |
117 | //---------------------------------------------------------------------------------- |
118 | UpdateDrawFrame(); |
119 | //---------------------------------------------------------------------------------- |
120 | } |
121 | #endif |
122 | // De-Initialization |
123 | //-------------------------------------------------------------------------------------- |
124 | UnloadGame(); // Unload loaded data (textures, sounds, models...) |
125 | |
126 | CloseWindow(); // Close window and OpenGL context |
127 | //-------------------------------------------------------------------------------------- |
128 | |
129 | return 0; |
130 | } |
131 | |
132 | //------------------------------------------------------------------------------------ |
133 | // Module Functions Definitions (local) |
134 | //------------------------------------------------------------------------------------ |
135 | |
136 | // Initialize game variables |
137 | void InitGame(void) |
138 | { |
139 | int posx, posy; |
140 | int velx, vely; |
141 | bool correctRange = false; |
142 | victory = false; |
143 | pause = false; |
144 | |
145 | shipHeight = (PLAYER_BASE_SIZE/2)/tanf(20*DEG2RAD); |
146 | |
147 | // Initialization player |
148 | player.position = (Vector2){screenWidth/2, screenHeight/2 - shipHeight/2}; |
149 | player.speed = (Vector2){0, 0}; |
150 | player.acceleration = 0; |
151 | player.rotation = 0; |
152 | player.collider = (Vector3){player.position.x + sin(player.rotation*DEG2RAD)*(shipHeight/2.5f), player.position.y - cos(player.rotation*DEG2RAD)*(shipHeight/2.5f), 12}; |
153 | player.color = LIGHTGRAY; |
154 | |
155 | destroyedMeteorsCount = 0; |
156 | |
157 | // Initialization shoot |
158 | for (int i = 0; i < PLAYER_MAX_SHOOTS; i++) |
159 | { |
160 | shoot[i].position = (Vector2){0, 0}; |
161 | shoot[i].speed = (Vector2){0, 0}; |
162 | shoot[i].radius = 2; |
163 | shoot[i].active = false; |
164 | shoot[i].lifeSpawn = 0; |
165 | shoot[i].color = WHITE; |
166 | } |
167 | |
168 | for (int i = 0; i < MAX_BIG_METEORS; i++) |
169 | { |
170 | posx = GetRandomValue(0, screenWidth); |
171 | |
172 | while(!correctRange) |
173 | { |
174 | if (posx > screenWidth/2 - 150 && posx < screenWidth/2 + 150) posx = GetRandomValue(0, screenWidth); |
175 | else correctRange = true; |
176 | } |
177 | |
178 | correctRange = false; |
179 | |
180 | posy = GetRandomValue(0, screenHeight); |
181 | |
182 | while(!correctRange) |
183 | { |
184 | if (posy > screenHeight/2 - 150 && posy < screenHeight/2 + 150) posy = GetRandomValue(0, screenHeight); |
185 | else correctRange = true; |
186 | } |
187 | |
188 | bigMeteor[i].position = (Vector2){posx, posy}; |
189 | |
190 | correctRange = false; |
191 | velx = GetRandomValue(-METEORS_SPEED, METEORS_SPEED); |
192 | vely = GetRandomValue(-METEORS_SPEED, METEORS_SPEED); |
193 | |
194 | while(!correctRange) |
195 | { |
196 | if (velx == 0 && vely == 0) |
197 | { |
198 | velx = GetRandomValue(-METEORS_SPEED, METEORS_SPEED); |
199 | vely = GetRandomValue(-METEORS_SPEED, METEORS_SPEED); |
200 | } |
201 | else correctRange = true; |
202 | } |
203 | |
204 | bigMeteor[i].speed = (Vector2){velx, vely}; |
205 | bigMeteor[i].radius = 40; |
206 | bigMeteor[i].active = true; |
207 | bigMeteor[i].color = BLUE; |
208 | } |
209 | |
210 | for (int i = 0; i < MAX_MEDIUM_METEORS; i++) |
211 | { |
212 | mediumMeteor[i].position = (Vector2){-100, -100}; |
213 | mediumMeteor[i].speed = (Vector2){0,0}; |
214 | mediumMeteor[i].radius = 20; |
215 | mediumMeteor[i].active = false; |
216 | mediumMeteor[i].color = BLUE; |
217 | } |
218 | |
219 | for (int i = 0; i < MAX_SMALL_METEORS; i++) |
220 | { |
221 | smallMeteor[i].position = (Vector2){-100, -100}; |
222 | smallMeteor[i].speed = (Vector2){0,0}; |
223 | smallMeteor[i].radius = 10; |
224 | smallMeteor[i].active = false; |
225 | smallMeteor[i].color = BLUE; |
226 | } |
227 | |
228 | midMeteorsCount = 0; |
229 | smallMeteorsCount = 0; |
230 | } |
231 | |
232 | // Update game (one frame) |
233 | void UpdateGame(void) |
234 | { |
235 | if (!gameOver) |
236 | { |
237 | if (IsKeyPressed('P')) pause = !pause; |
238 | |
239 | if (!pause) |
240 | { |
241 | // Player logic: rotation |
242 | if (IsKeyDown(KEY_LEFT)) player.rotation -= 5; |
243 | if (IsKeyDown(KEY_RIGHT)) player.rotation += 5; |
244 | |
245 | // Player logic: speed |
246 | player.speed.x = sin(player.rotation*DEG2RAD)*PLAYER_SPEED; |
247 | player.speed.y = cos(player.rotation*DEG2RAD)*PLAYER_SPEED; |
248 | |
249 | // Player logic: acceleration |
250 | if (IsKeyDown(KEY_UP)) |
251 | { |
252 | if (player.acceleration < 1) player.acceleration += 0.04f; |
253 | } |
254 | else |
255 | { |
256 | if (player.acceleration > 0) player.acceleration -= 0.02f; |
257 | else if (player.acceleration < 0) player.acceleration = 0; |
258 | } |
259 | if (IsKeyDown(KEY_DOWN)) |
260 | { |
261 | if (player.acceleration > 0) player.acceleration -= 0.04f; |
262 | else if (player.acceleration < 0) player.acceleration = 0; |
263 | } |
264 | |
265 | // Player logic: movement |
266 | player.position.x += (player.speed.x*player.acceleration); |
267 | player.position.y -= (player.speed.y*player.acceleration); |
268 | |
269 | // Collision logic: player vs walls |
270 | if (player.position.x > screenWidth + shipHeight) player.position.x = -(shipHeight); |
271 | else if (player.position.x < -(shipHeight)) player.position.x = screenWidth + shipHeight; |
272 | if (player.position.y > (screenHeight + shipHeight)) player.position.y = -(shipHeight); |
273 | else if (player.position.y < -(shipHeight)) player.position.y = screenHeight + shipHeight; |
274 | |
275 | // Player shoot logic |
276 | if (IsKeyPressed(KEY_SPACE)) |
277 | { |
278 | for (int i = 0; i < PLAYER_MAX_SHOOTS; i++) |
279 | { |
280 | if (!shoot[i].active) |
281 | { |
282 | shoot[i].position = (Vector2){ player.position.x + sin(player.rotation*DEG2RAD)*(shipHeight), player.position.y - cos(player.rotation*DEG2RAD)*(shipHeight) }; |
283 | shoot[i].active = true; |
284 | shoot[i].speed.x = 1.5*sin(player.rotation*DEG2RAD)*PLAYER_SPEED; |
285 | shoot[i].speed.y = 1.5*cos(player.rotation*DEG2RAD)*PLAYER_SPEED; |
286 | shoot[i].rotation = player.rotation; |
287 | break; |
288 | } |
289 | } |
290 | } |
291 | |
292 | // Shoot life timer |
293 | for (int i = 0; i < PLAYER_MAX_SHOOTS; i++) |
294 | { |
295 | if (shoot[i].active) shoot[i].lifeSpawn++; |
296 | } |
297 | |
298 | // Shot logic |
299 | for (int i = 0; i < PLAYER_MAX_SHOOTS; i++) |
300 | { |
301 | if (shoot[i].active) |
302 | { |
303 | // Movement |
304 | shoot[i].position.x += shoot[i].speed.x; |
305 | shoot[i].position.y -= shoot[i].speed.y; |
306 | |
307 | // Collision logic: shoot vs walls |
308 | if (shoot[i].position.x > screenWidth + shoot[i].radius) |
309 | { |
310 | shoot[i].active = false; |
311 | shoot[i].lifeSpawn = 0; |
312 | } |
313 | else if (shoot[i].position.x < 0 - shoot[i].radius) |
314 | { |
315 | shoot[i].active = false; |
316 | shoot[i].lifeSpawn = 0; |
317 | } |
318 | if (shoot[i].position.y > screenHeight + shoot[i].radius) |
319 | { |
320 | shoot[i].active = false; |
321 | shoot[i].lifeSpawn = 0; |
322 | } |
323 | else if (shoot[i].position.y < 0 - shoot[i].radius) |
324 | { |
325 | shoot[i].active = false; |
326 | shoot[i].lifeSpawn = 0; |
327 | } |
328 | |
329 | // Life of shoot |
330 | if (shoot[i].lifeSpawn >= 60) |
331 | { |
332 | shoot[i].position = (Vector2){0, 0}; |
333 | shoot[i].speed = (Vector2){0, 0}; |
334 | shoot[i].lifeSpawn = 0; |
335 | shoot[i].active = false; |
336 | } |
337 | } |
338 | } |
339 | |
340 | // Collision logic: player vs meteors |
341 | player.collider = (Vector3){player.position.x + sin(player.rotation*DEG2RAD)*(shipHeight/2.5f), player.position.y - cos(player.rotation*DEG2RAD)*(shipHeight/2.5f), 12}; |
342 | |
343 | for (int a = 0; a < MAX_BIG_METEORS; a++) |
344 | { |
345 | if (CheckCollisionCircles((Vector2){player.collider.x, player.collider.y}, player.collider.z, bigMeteor[a].position, bigMeteor[a].radius) && bigMeteor[a].active) gameOver = true; |
346 | } |
347 | |
348 | for (int a = 0; a < MAX_MEDIUM_METEORS; a++) |
349 | { |
350 | if (CheckCollisionCircles((Vector2){player.collider.x, player.collider.y}, player.collider.z, mediumMeteor[a].position, mediumMeteor[a].radius) && mediumMeteor[a].active) gameOver = true; |
351 | } |
352 | |
353 | for (int a = 0; a < MAX_SMALL_METEORS; a++) |
354 | { |
355 | if (CheckCollisionCircles((Vector2){player.collider.x, player.collider.y}, player.collider.z, smallMeteor[a].position, smallMeteor[a].radius) && smallMeteor[a].active) gameOver = true; |
356 | } |
357 | |
358 | // Meteors logic: big meteors |
359 | for (int i = 0; i < MAX_BIG_METEORS; i++) |
360 | { |
361 | if (bigMeteor[i].active) |
362 | { |
363 | // Movement |
364 | bigMeteor[i].position.x += bigMeteor[i].speed.x; |
365 | bigMeteor[i].position.y += bigMeteor[i].speed.y; |
366 | |
367 | // Collision logic: meteor vs wall |
368 | if (bigMeteor[i].position.x > screenWidth + bigMeteor[i].radius) bigMeteor[i].position.x = -(bigMeteor[i].radius); |
369 | else if (bigMeteor[i].position.x < 0 - bigMeteor[i].radius) bigMeteor[i].position.x = screenWidth + bigMeteor[i].radius; |
370 | if (bigMeteor[i].position.y > screenHeight + bigMeteor[i].radius) bigMeteor[i].position.y = -(bigMeteor[i].radius); |
371 | else if (bigMeteor[i].position.y < 0 - bigMeteor[i].radius) bigMeteor[i].position.y = screenHeight + bigMeteor[i].radius; |
372 | } |
373 | } |
374 | |
375 | // Meteors logic: medium meteors |
376 | for (int i = 0; i < MAX_MEDIUM_METEORS; i++) |
377 | { |
378 | if (mediumMeteor[i].active) |
379 | { |
380 | // Movement |
381 | mediumMeteor[i].position.x += mediumMeteor[i].speed.x; |
382 | mediumMeteor[i].position.y += mediumMeteor[i].speed.y; |
383 | |
384 | // Collision logic: meteor vs wall |
385 | if (mediumMeteor[i].position.x > screenWidth + mediumMeteor[i].radius) mediumMeteor[i].position.x = -(mediumMeteor[i].radius); |
386 | else if (mediumMeteor[i].position.x < 0 - mediumMeteor[i].radius) mediumMeteor[i].position.x = screenWidth + mediumMeteor[i].radius; |
387 | if (mediumMeteor[i].position.y > screenHeight + mediumMeteor[i].radius) mediumMeteor[i].position.y = -(mediumMeteor[i].radius); |
388 | else if (mediumMeteor[i].position.y < 0 - mediumMeteor[i].radius) mediumMeteor[i].position.y = screenHeight + mediumMeteor[i].radius; |
389 | } |
390 | } |
391 | |
392 | // Meteors logic: small meteors |
393 | for (int i = 0; i < MAX_SMALL_METEORS; i++) |
394 | { |
395 | if (smallMeteor[i].active) |
396 | { |
397 | // Movement |
398 | smallMeteor[i].position.x += smallMeteor[i].speed.x; |
399 | smallMeteor[i].position.y += smallMeteor[i].speed.y; |
400 | |
401 | // Collision logic: meteor vs wall |
402 | if (smallMeteor[i].position.x > screenWidth + smallMeteor[i].radius) smallMeteor[i].position.x = -(smallMeteor[i].radius); |
403 | else if (smallMeteor[i].position.x < 0 - smallMeteor[i].radius) smallMeteor[i].position.x = screenWidth + smallMeteor[i].radius; |
404 | if (smallMeteor[i].position.y > screenHeight + smallMeteor[i].radius) smallMeteor[i].position.y = -(smallMeteor[i].radius); |
405 | else if (smallMeteor[i].position.y < 0 - smallMeteor[i].radius) smallMeteor[i].position.y = screenHeight + smallMeteor[i].radius; |
406 | } |
407 | } |
408 | |
409 | // Collision logic: player-shoots vs meteors |
410 | for (int i = 0; i < PLAYER_MAX_SHOOTS; i++) |
411 | { |
412 | if ((shoot[i].active)) |
413 | { |
414 | for (int a = 0; a < MAX_BIG_METEORS; a++) |
415 | { |
416 | if (bigMeteor[a].active && CheckCollisionCircles(shoot[i].position, shoot[i].radius, bigMeteor[a].position, bigMeteor[a].radius)) |
417 | { |
418 | shoot[i].active = false; |
419 | shoot[i].lifeSpawn = 0; |
420 | bigMeteor[a].active = false; |
421 | destroyedMeteorsCount++; |
422 | |
423 | for (int j = 0; j < 2; j ++) |
424 | { |
425 | if (midMeteorsCount%2 == 0) |
426 | { |
427 | mediumMeteor[midMeteorsCount].position = (Vector2){bigMeteor[a].position.x, bigMeteor[a].position.y}; |
428 | mediumMeteor[midMeteorsCount].speed = (Vector2){cos(shoot[i].rotation*DEG2RAD)*METEORS_SPEED*-1, sin(shoot[i].rotation*DEG2RAD)*METEORS_SPEED*-1}; |
429 | } |
430 | else |
431 | { |
432 | mediumMeteor[midMeteorsCount].position = (Vector2){bigMeteor[a].position.x, bigMeteor[a].position.y}; |
433 | mediumMeteor[midMeteorsCount].speed = (Vector2){cos(shoot[i].rotation*DEG2RAD)*METEORS_SPEED, sin(shoot[i].rotation*DEG2RAD)*METEORS_SPEED}; |
434 | } |
435 | |
436 | mediumMeteor[midMeteorsCount].active = true; |
437 | midMeteorsCount ++; |
438 | } |
439 | //bigMeteor[a].position = (Vector2){-100, -100}; |
440 | bigMeteor[a].color = RED; |
441 | a = MAX_BIG_METEORS; |
442 | } |
443 | } |
444 | |
445 | for (int b = 0; b < MAX_MEDIUM_METEORS; b++) |
446 | { |
447 | if (mediumMeteor[b].active && CheckCollisionCircles(shoot[i].position, shoot[i].radius, mediumMeteor[b].position, mediumMeteor[b].radius)) |
448 | { |
449 | shoot[i].active = false; |
450 | shoot[i].lifeSpawn = 0; |
451 | mediumMeteor[b].active = false; |
452 | destroyedMeteorsCount++; |
453 | |
454 | for (int j = 0; j < 2; j ++) |
455 | { |
456 | if (smallMeteorsCount%2 == 0) |
457 | { |
458 | smallMeteor[smallMeteorsCount].position = (Vector2){mediumMeteor[b].position.x, mediumMeteor[b].position.y}; |
459 | smallMeteor[smallMeteorsCount].speed = (Vector2){cos(shoot[i].rotation*DEG2RAD)*METEORS_SPEED*-1, sin(shoot[i].rotation*DEG2RAD)*METEORS_SPEED*-1}; |
460 | } |
461 | else |
462 | { |
463 | smallMeteor[smallMeteorsCount].position = (Vector2){mediumMeteor[b].position.x, mediumMeteor[b].position.y}; |
464 | smallMeteor[smallMeteorsCount].speed = (Vector2){cos(shoot[i].rotation*DEG2RAD)*METEORS_SPEED, sin(shoot[i].rotation*DEG2RAD)*METEORS_SPEED}; |
465 | } |
466 | |
467 | smallMeteor[smallMeteorsCount].active = true; |
468 | smallMeteorsCount ++; |
469 | } |
470 | //mediumMeteor[b].position = (Vector2){-100, -100}; |
471 | mediumMeteor[b].color = GREEN; |
472 | b = MAX_MEDIUM_METEORS; |
473 | } |
474 | } |
475 | |
476 | for (int c = 0; c < MAX_SMALL_METEORS; c++) |
477 | { |
478 | if (smallMeteor[c].active && CheckCollisionCircles(shoot[i].position, shoot[i].radius, smallMeteor[c].position, smallMeteor[c].radius)) |
479 | { |
480 | shoot[i].active = false; |
481 | shoot[i].lifeSpawn = 0; |
482 | smallMeteor[c].active = false; |
483 | destroyedMeteorsCount++; |
484 | smallMeteor[c].color = YELLOW; |
485 | // smallMeteor[c].position = (Vector2){-100, -100}; |
486 | c = MAX_SMALL_METEORS; |
487 | } |
488 | } |
489 | } |
490 | } |
491 | } |
492 | |
493 | if (destroyedMeteorsCount == MAX_BIG_METEORS + MAX_MEDIUM_METEORS + MAX_SMALL_METEORS) victory = true; |
494 | } |
495 | else |
496 | { |
497 | if (IsKeyPressed(KEY_ENTER)) |
498 | { |
499 | InitGame(); |
500 | gameOver = false; |
501 | } |
502 | } |
503 | } |
504 | |
505 | // Draw game (one frame) |
506 | void DrawGame(void) |
507 | { |
508 | BeginDrawing(); |
509 | |
510 | ClearBackground(RAYWHITE); |
511 | |
512 | if (!gameOver) |
513 | { |
514 | // Draw spaceship |
515 | Vector2 v1 = { player.position.x + sinf(player.rotation*DEG2RAD)*(shipHeight), player.position.y - cosf(player.rotation*DEG2RAD)*(shipHeight) }; |
516 | Vector2 v2 = { player.position.x - cosf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2), player.position.y - sinf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2) }; |
517 | Vector2 v3 = { player.position.x + cosf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2), player.position.y + sinf(player.rotation*DEG2RAD)*(PLAYER_BASE_SIZE/2) }; |
518 | DrawTriangle(v1, v2, v3, MAROON); |
519 | |
520 | // Draw meteors |
521 | for (int i = 0; i < MAX_BIG_METEORS; i++) |
522 | { |
523 | if (bigMeteor[i].active) DrawCircleV(bigMeteor[i].position, bigMeteor[i].radius, DARKGRAY); |
524 | else DrawCircleV(bigMeteor[i].position, bigMeteor[i].radius, Fade(LIGHTGRAY, 0.3f)); |
525 | } |
526 | |
527 | for (int i = 0; i < MAX_MEDIUM_METEORS; i++) |
528 | { |
529 | if (mediumMeteor[i].active) DrawCircleV(mediumMeteor[i].position, mediumMeteor[i].radius, GRAY); |
530 | else DrawCircleV(mediumMeteor[i].position, mediumMeteor[i].radius, Fade(LIGHTGRAY, 0.3f)); |
531 | } |
532 | |
533 | for (int i = 0; i < MAX_SMALL_METEORS; i++) |
534 | { |
535 | if (smallMeteor[i].active) DrawCircleV(smallMeteor[i].position, smallMeteor[i].radius, GRAY); |
536 | else DrawCircleV(smallMeteor[i].position, smallMeteor[i].radius, Fade(LIGHTGRAY, 0.3f)); |
537 | } |
538 | |
539 | // Draw shoot |
540 | for (int i = 0; i < PLAYER_MAX_SHOOTS; i++) |
541 | { |
542 | if (shoot[i].active) DrawCircleV(shoot[i].position, shoot[i].radius, BLACK); |
543 | } |
544 | |
545 | if (victory) DrawText("VICTORY" , screenWidth/2 - MeasureText("VICTORY" , 20)/2, screenHeight/2, 20, LIGHTGRAY); |
546 | |
547 | if (pause) DrawText("GAME PAUSED" , screenWidth/2 - MeasureText("GAME PAUSED" , 40)/2, screenHeight/2 - 40, 40, GRAY); |
548 | } |
549 | else DrawText("PRESS [ENTER] TO PLAY AGAIN" , GetScreenWidth()/2 - MeasureText("PRESS [ENTER] TO PLAY AGAIN" , 20)/2, GetScreenHeight()/2 - 50, 20, GRAY); |
550 | |
551 | EndDrawing(); |
552 | } |
553 | |
554 | // Unload game variables |
555 | void UnloadGame(void) |
556 | { |
557 | // TODO: Unload all dynamic loaded data (textures, sounds, models...) |
558 | } |
559 | |
560 | // Update and Draw (one frame) |
561 | void UpdateDrawFrame(void) |
562 | { |
563 | UpdateGame(); |
564 | DrawGame(); |
565 | } |
566 | |