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.

544 lines
20 KiB

8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
8 years ago
  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.6 (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. #include <math.h> // Used for sinf()
  23. #if defined(PLATFORM_WEB)
  24. #include <emscripten/emscripten.h>
  25. #endif
  26. #define MAX_ENEMIES 10
  27. typedef enum { TITLE = 0, GAMEPLAY, ENDING } GameScreen;
  28. //----------------------------------------------------------------------------------
  29. // Global Variables Definition
  30. //----------------------------------------------------------------------------------
  31. const int screenWidth = 1280;
  32. const int screenHeight = 720;
  33. Texture2D sky;
  34. Texture2D mountains;
  35. Texture2D sea;
  36. Texture2D title;
  37. Texture2D turtle;
  38. Texture2D gamera;
  39. Texture2D shark;
  40. Texture2D orca;
  41. Texture2D swhale;
  42. Texture2D fish;
  43. Texture2D gframe;
  44. Font font;
  45. Sound eat;
  46. Sound die;
  47. Sound growl;
  48. Music music;
  49. // Define scrolling variables
  50. int backScrolling = 0;
  51. int seaScrolling = 0;
  52. // Define current screen
  53. GameScreen currentScreen = 0;
  54. // Define player variables
  55. int playerRail = 1;
  56. Rectangle playerBounds;
  57. bool gameraMode = false;
  58. // Define enemies variables
  59. Rectangle enemyBounds[MAX_ENEMIES];
  60. int enemyRail[MAX_ENEMIES];
  61. int enemyType[MAX_ENEMIES];
  62. bool enemyActive[MAX_ENEMIES];
  63. float enemySpeed = 10;
  64. // Define additional game variables
  65. int score = 0;
  66. float distance = 0.0f;
  67. int hiscore = 0;
  68. float hidistance = 0.0f;
  69. int foodBar = 0;
  70. int framesCounter = 0;
  71. unsigned char blue = 200;
  72. float timeCounter = 0;
  73. //----------------------------------------------------------------------------------
  74. // Module Functions Declaration
  75. //----------------------------------------------------------------------------------
  76. void UpdateDrawFrame(void); // Update and Draw one frame
  77. //----------------------------------------------------------------------------------
  78. // Main Enry Point
  79. //----------------------------------------------------------------------------------
  80. int main()
  81. {
  82. // Initialization
  83. //--------------------------------------------------------------------------------------
  84. // Init window
  85. InitWindow(screenWidth, screenHeight, "Dr. Turtle & Mr. GAMERA");
  86. // Initialize audio device
  87. InitAudioDevice();
  88. // Load game resources: textures
  89. sky = LoadTexture("resources/sky.png");
  90. mountains = LoadTexture("resources/mountains.png");
  91. sea = LoadTexture("resources/sea.png");
  92. title = LoadTexture("resources/title.png");
  93. turtle = LoadTexture("resources/turtle.png");
  94. gamera = LoadTexture("resources/gamera.png");
  95. shark = LoadTexture("resources/shark.png");
  96. orca = LoadTexture("resources/orca.png");
  97. swhale = LoadTexture("resources/swhale.png");
  98. fish = LoadTexture("resources/fish.png");
  99. gframe = LoadTexture("resources/gframe.png");
  100. // Load game resources: fonts
  101. font = LoadFont("resources/komika.png");
  102. // Load game resources: sounds
  103. eat = LoadSound("resources/eat.wav");
  104. die = LoadSound("resources/die.wav");
  105. growl = LoadSound("resources/gamera.wav");
  106. // Load music stream and start playing music
  107. music = LoadMusicStream("resources/speeding.ogg");
  108. PlayMusicStream(music);
  109. playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
  110. // Init enemies variables
  111. for (int i = 0; i < MAX_ENEMIES; i++)
  112. {
  113. // Define enemy type (all same probability)
  114. //enemyType[i] = GetRandomValue(0, 3);
  115. // Probability system for enemies type
  116. int enemyProb = GetRandomValue(0, 100);
  117. if (enemyProb < 30) enemyType[i] = 0;
  118. else if (enemyProb < 60) enemyType[i] = 1;
  119. else if (enemyProb < 90) enemyType[i] = 2;
  120. else enemyType[i] = 3;
  121. // define enemy rail
  122. enemyRail[i] = GetRandomValue(0, 4);
  123. // Make sure not two consecutive enemies in the same row
  124. if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
  125. enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
  126. enemyActive[i] = false;
  127. }
  128. #if defined(PLATFORM_WEB)
  129. emscripten_set_main_loop(UpdateDrawFrame, 0, 1);
  130. #else
  131. SetTargetFPS(60); // Set our game to run at 60 frames-per-second
  132. //--------------------------------------------------------------------------------------
  133. // Main game loop
  134. while (!WindowShouldClose()) // Detect window close button or ESC key
  135. {
  136. UpdateDrawFrame();
  137. }
  138. #endif
  139. // De-Initialization
  140. //--------------------------------------------------------------------------------------
  141. // Unload textures
  142. UnloadTexture(sky);
  143. UnloadTexture(mountains);
  144. UnloadTexture(sea);
  145. UnloadTexture(gframe);
  146. UnloadTexture(title);
  147. UnloadTexture(turtle);
  148. UnloadTexture(shark);
  149. UnloadTexture(orca);
  150. UnloadTexture(swhale);
  151. UnloadTexture(fish);
  152. UnloadTexture(gamera);
  153. // Unload font texture
  154. UnloadFont(font);
  155. // Unload sounds
  156. UnloadSound(eat);
  157. UnloadSound(die);
  158. UnloadSound(growl);
  159. UnloadMusicStream(music); // Unload music
  160. CloseAudioDevice(); // Close audio device
  161. CloseWindow(); // Close window and OpenGL context
  162. //--------------------------------------------------------------------------------------
  163. return 0;
  164. }
  165. //----------------------------------------------------------------------------------
  166. // Module Functions Definition
  167. //----------------------------------------------------------------------------------
  168. void UpdateDrawFrame(void)
  169. {
  170. // Update
  171. //----------------------------------------------------------------------------------
  172. UpdateMusicStream(music); // Refill music stream buffers (if required)
  173. framesCounter++;
  174. // Sea color tint effect
  175. blue = 210 + 25 * sinf(timeCounter);
  176. timeCounter += 0.01;
  177. // Game screens management
  178. switch (currentScreen)
  179. {
  180. case TITLE:
  181. {
  182. // Sea scrolling
  183. seaScrolling -= 2;
  184. if (seaScrolling <= -screenWidth) seaScrolling = 0;
  185. // Press enter to change to gameplay screen
  186. if (IsKeyPressed(KEY_ENTER))
  187. {
  188. currentScreen = GAMEPLAY;
  189. framesCounter = 0;
  190. }
  191. } break;
  192. case GAMEPLAY:
  193. {
  194. // Background scrolling logic
  195. backScrolling--;
  196. if (backScrolling <= -screenWidth) backScrolling = 0;
  197. // Sea scrolling logic
  198. seaScrolling -= (enemySpeed - 2);
  199. if (seaScrolling <= -screenWidth) seaScrolling = 0;
  200. // Player movement logic
  201. if (IsKeyPressed(KEY_DOWN)) playerRail++;
  202. else if (IsKeyPressed(KEY_UP)) playerRail--;
  203. // Check player not out of rails
  204. if (playerRail > 4) playerRail = 4;
  205. else if (playerRail < 0) playerRail = 0;
  206. // Update player bounds
  207. playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
  208. // Enemies activation logic (every 40 frames)
  209. if (framesCounter > 40)
  210. {
  211. for (int i = 0; i < MAX_ENEMIES; i++)
  212. {
  213. if (enemyActive[i] == false)
  214. {
  215. enemyActive[i] = true;
  216. i = MAX_ENEMIES;
  217. }
  218. }
  219. framesCounter = 0;
  220. }
  221. // Enemies logic
  222. for (int i = 0; i < MAX_ENEMIES; i++)
  223. {
  224. if (enemyActive[i])
  225. {
  226. enemyBounds[i].x -= enemySpeed;
  227. }
  228. // Check enemies out of screen
  229. if (enemyBounds[i].x <= 0 - 128)
  230. {
  231. enemyActive[i] = false;
  232. enemyType[i] = GetRandomValue(0, 3);
  233. enemyRail[i] = GetRandomValue(0, 4);
  234. // Make sure not two consecutive enemies in the same row
  235. if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
  236. enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
  237. }
  238. }
  239. if (!gameraMode) enemySpeed += 0.005;
  240. // Check collision player vs enemies
  241. for (int i = 0; i < MAX_ENEMIES; i++)
  242. {
  243. if (enemyActive[i])
  244. {
  245. if (CheckCollisionRecs(playerBounds, enemyBounds[i]))
  246. {
  247. if (enemyType[i] < 3) // Bad enemies
  248. {
  249. if (gameraMode)
  250. {
  251. if (enemyType[i] == 0) score += 50;
  252. else if (enemyType[i] == 1) score += 150;
  253. else if (enemyType[i] == 2) score += 300;
  254. foodBar += 15;
  255. enemyActive[i] = false;
  256. // After enemy deactivation, reset enemy parameters to be reused
  257. enemyType[i] = GetRandomValue(0, 3);
  258. enemyRail[i] = GetRandomValue(0, 4);
  259. // Make sure not two consecutive enemies in the same row
  260. if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
  261. enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
  262. PlaySound(eat);
  263. }
  264. else
  265. {
  266. // Player die logic
  267. PlaySound(die);
  268. currentScreen = ENDING;
  269. framesCounter = 0;
  270. // Save hiscore and hidistance for next game
  271. if (score > hiscore) hiscore = score;
  272. if (distance > hidistance) hidistance = distance;
  273. }
  274. }
  275. else // Sweet fish
  276. {
  277. enemyActive[i] = false;
  278. enemyType[i] = GetRandomValue(0, 3);
  279. enemyRail[i] = GetRandomValue(0, 4);
  280. // Make sure not two consecutive enemies in the same row
  281. if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
  282. enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
  283. if (!gameraMode) foodBar += 80;
  284. else foodBar += 25;
  285. score += 10;
  286. if (foodBar == 400)
  287. {
  288. gameraMode = true;
  289. PlaySound(growl);
  290. }
  291. PlaySound(eat);
  292. }
  293. }
  294. }
  295. }
  296. // Gamera mode logic
  297. if (gameraMode)
  298. {
  299. foodBar--;
  300. if (foodBar <= 0)
  301. {
  302. gameraMode = false;
  303. enemySpeed -= 2;
  304. if (enemySpeed < 10) enemySpeed = 10;
  305. }
  306. }
  307. // Update distance counter
  308. distance += 0.5f;
  309. } break;
  310. case ENDING:
  311. {
  312. // Press enter to play again
  313. if (IsKeyPressed(KEY_ENTER))
  314. {
  315. currentScreen = GAMEPLAY;
  316. // Reset player
  317. playerRail = 1;
  318. playerBounds = (Rectangle){ 30 + 14, playerRail*120 + 90 + 14, 100, 100 };
  319. gameraMode = false;
  320. // Reset enemies data
  321. for (int i = 0; i < MAX_ENEMIES; i++)
  322. {
  323. int enemyProb = GetRandomValue(0, 100);
  324. if (enemyProb < 30) enemyType[i] = 0;
  325. else if (enemyProb < 60) enemyType[i] = 1;
  326. else if (enemyProb < 90) enemyType[i] = 2;
  327. else enemyType[i] = 3;
  328. //enemyType[i] = GetRandomValue(0, 3);
  329. enemyRail[i] = GetRandomValue(0, 4);
  330. // Make sure not two consecutive enemies in the same row
  331. if (i > 0) while (enemyRail[i] == enemyRail[i - 1]) enemyRail[i] = GetRandomValue(0, 4);
  332. enemyBounds[i] = (Rectangle){ screenWidth + 14, 120*enemyRail[i] + 90 + 14, 100, 100 };
  333. enemyActive[i] = false;
  334. }
  335. enemySpeed = 10;
  336. // Reset game variables
  337. score = 0;
  338. distance = 0.0;
  339. foodBar = 0;
  340. framesCounter = 0;
  341. }
  342. } break;
  343. default: break;
  344. }
  345. //----------------------------------------------------------------------------------
  346. // Draw
  347. //----------------------------------------------------------------------------------
  348. BeginDrawing();
  349. ClearBackground(RAYWHITE);
  350. // Draw background (common to all screens)
  351. DrawTexture(sky, 0, 0, WHITE);
  352. DrawTexture(mountains, backScrolling, 0, WHITE);
  353. DrawTexture(mountains, screenWidth + backScrolling, 0, WHITE);
  354. if (!gameraMode)
  355. {
  356. DrawTexture(sea, seaScrolling, 0, (Color){ 16, 189, blue, 255});
  357. DrawTexture(sea, screenWidth + seaScrolling, 0, (Color){ 16, 189, blue, 255});
  358. }
  359. else
  360. {
  361. DrawTexture(sea, seaScrolling, 0, (Color){ 255, 113, 66, 255});
  362. DrawTexture(sea, screenWidth + seaScrolling, 0, (Color){ 255, 113, 66, 255});
  363. }
  364. switch (currentScreen)
  365. {
  366. case TITLE:
  367. {
  368. // Draw title
  369. DrawTexture(title, screenWidth/2 - title.width/2, screenHeight/2 - title.height/2 - 80, WHITE);
  370. // Draw blinking text
  371. if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER", (Vector2){ screenWidth/2 - 150, 480 }, font.baseSize, 1, WHITE);
  372. } break;
  373. case GAMEPLAY:
  374. {
  375. // Draw water lines
  376. for (int i = 0; i < 5; i++) DrawRectangle(0, i*120 + 120, screenWidth, 110, Fade(SKYBLUE, 0.1f));
  377. // Draw player
  378. if (!gameraMode) DrawTexture(turtle, playerBounds.x - 14, playerBounds.y - 14, WHITE);
  379. else DrawTexture(gamera, playerBounds.x - 64, playerBounds.y - 64, WHITE);
  380. // Draw player bounding box
  381. //if (!gameraMode) DrawRectangleRec(playerBounds, Fade(GREEN, 0.4f));
  382. //else DrawRectangleRec(playerBounds, Fade(ORANGE, 0.4f));
  383. // Draw enemies
  384. for (int i = 0; i < MAX_ENEMIES; i++)
  385. {
  386. if (enemyActive[i])
  387. {
  388. // Draw enemies
  389. switch(enemyType[i])
  390. {
  391. case 0: DrawTexture(shark, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
  392. case 1: DrawTexture(orca, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
  393. case 2: DrawTexture(swhale, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
  394. case 3: DrawTexture(fish, enemyBounds[i].x - 14, enemyBounds[i].y - 14, WHITE); break;
  395. default: break;
  396. }
  397. // Draw enemies bounding boxes
  398. /*
  399. switch(enemyType[i])
  400. {
  401. case 0: DrawRectangleRec(enemyBounds[i], Fade(RED, 0.5f)); break;
  402. case 1: DrawRectangleRec(enemyBounds[i], Fade(RED, 0.5f)); break;
  403. case 2: DrawRectangleRec(enemyBounds[i], Fade(RED, 0.5f)); break;
  404. case 3: DrawRectangleRec(enemyBounds[i], Fade(GREEN, 0.5f)); break;
  405. default: break;
  406. }
  407. */
  408. }
  409. }
  410. // Draw gameplay interface
  411. DrawRectangle(20, 20, 400, 40, Fade(GRAY, 0.4f));
  412. DrawRectangle(20, 20, foodBar, 40, ORANGE);
  413. DrawRectangleLines(20, 20, 400, 40, BLACK);
  414. DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ screenWidth - 300, 20 }, font.baseSize, -2, ORANGE);
  415. DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 550, 20 }, font.baseSize, -2, ORANGE);
  416. if (gameraMode)
  417. {
  418. DrawText("GAMERA MODE", 60, 22, 40, GRAY);
  419. DrawTexture(gframe, 0, 0, Fade(WHITE, 0.5f));
  420. }
  421. } break;
  422. case ENDING:
  423. {
  424. // Draw a transparent black rectangle that covers all screen
  425. DrawRectangle(0, 0, screenWidth, screenHeight, Fade(BLACK, 0.4f));
  426. DrawTextEx(font, "GAME OVER", (Vector2){ 300, 160 }, font.baseSize*3, -2, MAROON);
  427. DrawTextEx(font, FormatText("SCORE: %04i", score), (Vector2){ 680, 350 }, font.baseSize, -2, GOLD);
  428. DrawTextEx(font, FormatText("DISTANCE: %04i", (int)distance), (Vector2){ 290, 350 }, font.baseSize, -2, GOLD);
  429. DrawTextEx(font, FormatText("HISCORE: %04i", hiscore), (Vector2){ 665, 400 }, font.baseSize, -2, ORANGE);
  430. DrawTextEx(font, FormatText("HIDISTANCE: %04i", (int)hidistance), (Vector2){ 270, 400 }, font.baseSize, -2, ORANGE);
  431. // Draw blinking text
  432. if ((framesCounter/30) % 2) DrawTextEx(font, "PRESS ENTER to REPLAY", (Vector2){ screenWidth/2 - 250, 520 }, font.baseSize, -2, LIGHTGRAY);
  433. } break;
  434. default: break;
  435. }
  436. EndDrawing();
  437. //----------------------------------------------------------------------------------
  438. }