You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

392 lines
15 KiB

  1. /*******************************************************************************************
  2. *
  3. * raylib game - Dr. Turtle & Mr. Gamera
  4. *
  5. * Welcome to raylib!
  6. *
  7. * To test examples, just press F6 and execute raylib_compile_execute script
  8. * Note that compiled executable is placed in the same folder as .c file
  9. *
  10. * You can find all basic examples on C:\raylib\raylib\examples folder or
  11. * raylib official webpage: www.raylib.com
  12. *
  13. * Enjoy using raylib. :)
  14. *
  15. * This game has been created using raylib 1.1 (www.raylib.com)
  16. * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details)
  17. *
  18. * Copyright (c) 2014 Ramon Santamaria (@raysan5)
  19. *
  20. ********************************************************************************************/
  21. #include "raylib.h"
  22. #define MAX_ENEMIES 10
  23. typedef enum { TITLE, GAMEPLAY, ENDING } GameScreen;
  24. int main()
  25. {
  26. // Initialization
  27. //--------------------------------------------------------------------------------------
  28. const int screenWidth = 1280;
  29. const int screenHeight = 720;
  30. // Init window
  31. InitWindow(screenWidth, screenHeight, "Dr. Turtle & Mr. GAMERA");
  32. // Load game resources: textures
  33. Texture2D sky = LoadTexture("resources/sky.png");
  34. Texture2D mountains = LoadTexture("resources/mountains.png");
  35. Texture2D sea = LoadTexture("resources/sea.png");
  36. Texture2D title = LoadTexture("resources/title.png");
  37. Texture2D turtle = LoadTexture("resources/turtle.png");
  38. Texture2D gamera = LoadTexture("resources/gamera.png");
  39. Texture2D shark = LoadTexture("resources/shark.png");
  40. Texture2D orca = LoadTexture("resources/orca.png");
  41. Texture2D swhale = LoadTexture("resources/swhale.png");
  42. Texture2D fish = LoadTexture("resources/fish.png");
  43. // Define scrolling variables
  44. int backScrolling = 0;
  45. int seaScrolling = 0;
  46. // Define current screen
  47. GameScreen currentScreen = TITLE;
  48. // Define player variables
  49. int playerRail = 1;
  50. Rectangle playerBounds = { 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
  51. bool gameraMode = false;
  52. // Define enemies variables
  53. Rectangle enemyBounds[MAX_ENEMIES];
  54. int enemyRail[MAX_ENEMIES];
  55. int enemyType[MAX_ENEMIES];
  56. bool enemyActive[MAX_ENEMIES];
  57. float enemySpeed = 10;
  58. // Init enemies variables
  59. for (int i = 0; i < MAX_ENEMIES; i++)
  60. {
  61. // Define enemy type (all same probability)
  62. enemyType[i] = GetRandomValue(0, 3);
  63. // Define enemy rail
  64. enemyRail[i] = GetRandomValue(0, 4);
  65. // Define enemy bounding box
  66. enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
  67. enemyActive[i] = false;
  68. }
  69. // Define additional game variables
  70. int foodBar = 0;
  71. int framesCounter = 0;
  72. SetTargetFPS(60); // Setup game frames per second
  73. //--------------------------------------------------------------------------------------
  74. // Main game loop
  75. while (!WindowShouldClose()) // Detect window close button or ESC key
  76. {
  77. // Update
  78. //----------------------------------------------------------------------------------
  79. framesCounter++;
  80. // Game screens management
  81. switch (currentScreen)
  82. {
  83. case TITLE:
  84. {
  85. // Sea scrolling
  86. seaScrolling -= 2;
  87. if (seaScrolling <= -screenWidth) seaScrolling = 0;
  88. // Press enter to change to gameplay screen
  89. if (IsKeyPressed(KEY_ENTER))
  90. {
  91. currentScreen = GAMEPLAY;
  92. framesCounter = 0;
  93. }
  94. } break;
  95. case GAMEPLAY:
  96. {
  97. // Background scrolling logic
  98. backScrolling--;
  99. if (backScrolling <= -screenWidth) backScrolling = 0;
  100. // Sea scrolling logic
  101. seaScrolling -= (enemySpeed - 2);
  102. if (seaScrolling <= -screenWidth) seaScrolling = 0;
  103. // Player movement logic
  104. if (IsKeyPressed(KEY_DOWN)) playerRail++;
  105. else if (IsKeyPressed(KEY_UP)) playerRail--;
  106. // Check player not out of rails
  107. if (playerRail > 4) playerRail = 4;
  108. else if (playerRail < 0) playerRail = 0;
  109. // Update player bounds
  110. playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
  111. // Enemies activation logic (every 40 frames)
  112. if (framesCounter > 40)
  113. {
  114. for (int i = 0; i < MAX_ENEMIES; i++)
  115. {
  116. if (enemyActive[i] == false)
  117. {
  118. enemyActive[i] = true;
  119. i = MAX_ENEMIES;
  120. }
  121. }
  122. framesCounter = 0;
  123. }
  124. // Enemies logic
  125. for (int i = 0; i < MAX_ENEMIES; i++)
  126. {
  127. if (enemyActive[i])
  128. {
  129. enemyBounds[i].x -= enemySpeed;
  130. }
  131. // Check enemies out of screen
  132. if (enemyBounds[i].x <= 0 - 128)
  133. {
  134. enemyType[i] = GetRandomValue(0, 3);
  135. enemyRail[i] = GetRandomValue(0, 4);
  136. enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
  137. enemyActive[i] = false;
  138. }
  139. }
  140. // Enemies speed increase every frame
  141. if (!gameraMode) enemySpeed += 0.005;
  142. // Check collision player vs enemies
  143. for (int i = 0; i < MAX_ENEMIES; i++)
  144. {
  145. if (enemyActive[i])
  146. {
  147. if (CheckCollisionRecs(playerBounds, enemyBounds[i]))
  148. {
  149. if (enemyType[i] < 3) // Bad enemies
  150. {
  151. if (gameraMode)
  152. {
  153. foodBar += 15;
  154. // After enemy deactivation, reset enemy parameters to be reused
  155. enemyType[i] = GetRandomValue(0, 3);
  156. enemyRail[i] = GetRandomValue(0, 4);
  157. enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
  158. enemyActive[i] = false;
  159. }
  160. else
  161. {
  162. // Player die logic
  163. currentScreen = ENDING;
  164. framesCounter = 0;
  165. }
  166. }
  167. else // Sweet fish
  168. {
  169. enemyActive[i] = false;
  170. enemyType[i] = GetRandomValue(0, 3);
  171. enemyRail[i] = GetRandomValue(0, 4);
  172. enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
  173. if (!gameraMode) foodBar += 80;
  174. else foodBar += 25;
  175. if (foodBar == 400)
  176. {
  177. gameraMode = true;
  178. }
  179. }
  180. }
  181. }
  182. }
  183. // Gamera mode logic
  184. if (gameraMode)
  185. {
  186. foodBar--;
  187. if (foodBar <= 0)
  188. {
  189. gameraMode = false;
  190. enemySpeed -= 2;
  191. if (enemySpeed < 10) enemySpeed = 10;
  192. }
  193. }
  194. } break;
  195. case ENDING:
  196. {
  197. // Press enter to play again
  198. if (IsKeyPressed(KEY_ENTER))
  199. {
  200. currentScreen = GAMEPLAY;
  201. // Reset player
  202. playerRail = 1;
  203. playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
  204. gameraMode = false;
  205. // Reset enemies data
  206. for (int i = 0; i < MAX_ENEMIES; i++)
  207. {
  208. enemyType[i] = GetRandomValue(0, 3);
  209. enemyRail[i] = GetRandomValue(0, 4);
  210. enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
  211. enemyActive[i] = false;
  212. }
  213. enemySpeed = 10;
  214. // Reset game variables
  215. foodBar = 0;
  216. framesCounter = 0;
  217. }
  218. } break;
  219. default: break;
  220. }
  221. //----------------------------------------------------------------------------------
  222. // Draw
  223. //----------------------------------------------------------------------------------
  224. BeginDrawing();
  225. ClearBackground(RAYWHITE);
  226. // Draw background (common to all screens)
  227. DrawTexture(sky, 0, 0, WHITE);
  228. DrawTexture(mountains, backScrolling, 0, WHITE);
  229. DrawTexture(mountains, screenWidth + backScrolling, 0, WHITE);
  230. if (!gameraMode)
  231. {
  232. DrawTexture(sea, seaScrolling, 0, BLUE);
  233. DrawTexture(sea, screenWidth + seaScrolling, 0, BLUE);
  234. }
  235. else
  236. {
  237. DrawTexture(sea, seaScrolling, 0, RED);
  238. DrawTexture(sea, screenWidth + seaScrolling, 0, RED);
  239. }
  240. switch (currentScreen)
  241. {
  242. case TITLE:
  243. {
  244. // Draw title
  245. DrawTexture(title, screenWidth/2 - title.width/2, screenHeight/2 - title.height/2 - 80, WHITE);
  246. // Draw blinking text
  247. if ((framesCounter/30) % 2) DrawText("PRESS ENTER", 480, 480, 40, BLACK);
  248. } break;
  249. case GAMEPLAY:
  250. {
  251. // Draw water lines
  252. for (int i = 0; i < 5; i++) DrawRectangle(0, i*120 + 120, screenWidth, 110, Fade(SKYBLUE, 0.1f));
  253. // Draw player
  254. if (!gameraMode) DrawTexture(turtle, playerBounds.x - 14, playerBounds.y - 14, WHITE);
  255. else DrawTexture(gamera, playerBounds.x - 64, playerBounds.y - 64, WHITE);
  256. // Draw player bounding box
  257. //if (!gameraMode) DrawRectangleRec(playerBounds, Fade(GREEN, 0.4f));
  258. //else DrawRectangleRec(playerBounds, Fade(ORANGE, 0.4f));
  259. // Draw enemies
  260. for (int i = 0; i < MAX_ENEMIES; i++)
  261. {
  262. if (enemyActive[i])
  263. {
  264. // Draw enemies
  265. /*
  266. switch(enemyType[i])
  267. {
  268. case 0: DrawTexture(shark, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
  269. case 1: DrawTexture(orca, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
  270. case 2: DrawTexture(swhale, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
  271. case 3: DrawTexture(fish, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
  272. default: break;
  273. }
  274. */
  275. // Draw enemies bounding boxes
  276. switch(enemyType[i])
  277. {
  278. case 0: DrawRectangleRec(enemyBounds[i], RED); break;
  279. case 1: DrawRectangleRec(enemyBounds[i], RED); break;
  280. case 2: DrawRectangleRec(enemyBounds[i], RED); break;
  281. case 3: DrawRectangleRec(enemyBounds[i], GREEN); break;
  282. default: break;
  283. }
  284. }
  285. }
  286. // Draw gameplay interface
  287. // Draw food bar
  288. DrawRectangle(20, 20, 400, 40, Fade(GRAY, 0.4f));
  289. DrawRectangle(20, 20, foodBar, 40, ORANGE);
  290. DrawRectangleLines(20, 20, 400, 40, BLACK);
  291. if (gameraMode)
  292. {
  293. DrawText("GAMERA MODE", 60, 22, 40, GRAY);
  294. }
  295. } break;
  296. case ENDING:
  297. {
  298. // Draw a transparent black rectangle that covers all screen
  299. DrawRectangle(0, 0, screenWidth, screenHeight, Fade(BLACK, 0.4f));
  300. DrawText("GAME OVER", 300, 200, 100, MAROON);
  301. // Draw blinking text
  302. if ((framesCounter/30) % 2) DrawText("PRESS ENTER to REPLAY", 400, 420, 30, LIGHTGRAY);
  303. } break;
  304. default: break;
  305. }
  306. EndDrawing();
  307. //----------------------------------------------------------------------------------
  308. }
  309. // De-Initialization
  310. //--------------------------------------------------------------------------------------
  311. // Unload textures
  312. UnloadTexture(sky);
  313. UnloadTexture(mountains);
  314. UnloadTexture(sea);
  315. UnloadTexture(title);
  316. UnloadTexture(turtle);
  317. UnloadTexture(gamera);
  318. UnloadTexture(shark);
  319. UnloadTexture(orca);
  320. UnloadTexture(swhale);
  321. UnloadTexture(fish);
  322. CloseWindow(); // Close window and OpenGL context
  323. //--------------------------------------------------------------------------------------
  324. return 0;
  325. }