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.

403 lines
13 KiB

  1. /**********************************************************************************************
  2. *
  3. * raylib - Advance Game template
  4. *
  5. * Gameplay Screen Functions Definitions (Init, Update, Draw, Unload)
  6. *
  7. * Copyright (c) 2014 Ramon Santamaria (@raysan5)
  8. *
  9. * This software is provided "as-is", without any express or implied warranty. In no event
  10. * will the authors be held liable for any damages arising from the use of this software.
  11. *
  12. * Permission is granted to anyone to use this software for any purpose, including commercial
  13. * applications, and to alter it and redistribute it freely, subject to the following restrictions:
  14. *
  15. * 1. The origin of this software must not be misrepresented; you must not claim that you
  16. * wrote the original software. If you use this software in a product, an acknowledgment
  17. * in the product documentation would be appreciated but is not required.
  18. *
  19. * 2. Altered source versions must be plainly marked as such, and must not be misrepresented
  20. * as being the original software.
  21. *
  22. * 3. This notice may not be removed or altered from any source distribution.
  23. *
  24. **********************************************************************************************/
  25. #include "raylib.h"
  26. #include "screens.h"
  27. #include "../player.h"
  28. #include "../monster.h"
  29. #include <string.h>
  30. //----------------------------------------------------------------------------------
  31. // Global Variables Definition (local to this module)
  32. //----------------------------------------------------------------------------------
  33. // Gameplay screen global variables
  34. static int framesCounter;
  35. static int finishScreen;
  36. static Texture2D background;
  37. // Declare doors
  38. static Door doorCenter;
  39. static Door doorLeft;
  40. // Decalre monsters
  41. static Monster candle;
  42. static Monster picture;
  43. static Monster phone;
  44. static bool monsterHover = false;
  45. static int monsterCheck = -1; // Identify checking monster
  46. static const char message[256] = "WHEN WIND BLOWS, IT KNOWS THE DIRECTION\nLET IT GUIDE YOU!";
  47. static int msgPosX = 100;
  48. static int msgState = 0; // 0-writting, 1-wait, 2-choose
  49. static int lettersCounter = 0;
  50. static char msgBuffer[256] = { '\0' };
  51. static int msgCounter = 0;
  52. static bool searching = false;
  53. //----------------------------------------------------------------------------------
  54. // Gameplay Screen Functions Definition
  55. //----------------------------------------------------------------------------------
  56. // Gameplay Screen Initialization logic
  57. void InitLivingroomScreen(void)
  58. {
  59. ResetPlayer();
  60. // Reset Screen variables
  61. monsterHover = false;
  62. monsterCheck = -1;
  63. msgState = 0;
  64. msgCounter = 0;
  65. lettersCounter = 0;
  66. for (int i = 0; i < 256; i++) msgBuffer[i] = '\0';
  67. framesCounter = 0;
  68. finishScreen = 0;
  69. background = LoadTexture("resources/textures/background_livingroom.png");
  70. // Initialize doors
  71. doorLeft.position = (Vector2) { -45, 140};
  72. doorLeft.facing = 0;
  73. doorLeft.locked = true;
  74. doorLeft.frameRec =(Rectangle) {((doors.width/3)*doorLeft.facing), doors.height/2, doors.width/3, doors.height/2};
  75. doorLeft.bound = (Rectangle) { doorLeft.position.x, doorLeft.position.y, doors.width/3, doors.height/2};
  76. doorLeft.selected = false;
  77. doorCenter.position = (Vector2) { 830, 108 };
  78. doorCenter.facing = 1;
  79. doorCenter.locked = true;
  80. doorCenter.frameRec =(Rectangle) {((doors.width/3)*doorCenter.facing), doors.height/2, doors.width/3, doors.height/2};
  81. doorCenter.bound = (Rectangle) { doorCenter.position.x, doorCenter.position.y, doors.width/3, doors.height/2};
  82. doorCenter.selected = false;
  83. // Monster init: lamp
  84. candle.position = (Vector2){ 154, 256 };
  85. candle.texture = LoadTexture("resources/textures/monster_candle.png");
  86. candle.currentFrame = 0;
  87. candle.framesCounter = 0;
  88. candle.numFrames = 4;
  89. candle.bounds = (Rectangle){ candle.position.x + 90, candle.position.y + 30, 185, 340 };
  90. candle.frameRec = (Rectangle) { 0, 0, candle.texture.width/candle.numFrames, candle.texture.height };
  91. candle.selected = false;
  92. candle.active = false;
  93. candle.spooky = false;
  94. // Monster init: arc
  95. picture.position = (Vector2){ 504, 164 };
  96. picture.texture = LoadTexture("resources/textures/monster_picture.png");
  97. picture.currentFrame = 0;
  98. picture.framesCounter = 0;
  99. picture.numFrames = 4;
  100. picture.bounds = (Rectangle){ picture.position.x + 44, picture.position.y, 174, 264 };
  101. picture.frameRec = (Rectangle) { 0, 0, picture.texture.width/picture.numFrames, picture.texture.height };
  102. picture.selected = false;
  103. picture.active = false;
  104. picture.spooky = true;
  105. // Monster init: phone
  106. phone.position = (Vector2){ 1054, 404 };
  107. phone.texture = LoadTexture("resources/textures/monster_phone.png");
  108. phone.currentFrame = 0;
  109. phone.framesCounter = 0;
  110. phone.numFrames = 4;
  111. phone.bounds = (Rectangle){ phone.position.x + 64, phone.position.y +120, 100, 160 };
  112. phone.frameRec = (Rectangle) { 0, 0, phone.texture.width/phone.numFrames, phone.texture.height };
  113. phone.selected = false;
  114. phone.active = false;
  115. phone.spooky = true;
  116. }
  117. // Gameplay Screen Update logic
  118. void UpdateLivingroomScreen(void)
  119. {
  120. if (player.key)
  121. {
  122. // Door: left
  123. if ((CheckCollisionPointRec(GetMousePosition(), doorLeft.bound)) ||
  124. (CheckCollisionRecs(player.bounds, doorLeft.bound))) doorLeft.selected = true;
  125. else doorLeft.selected = false;
  126. if ((doorLeft.selected) && (CheckCollisionRecs(player.bounds, doorLeft.bound)))
  127. {
  128. if (((IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) && CheckCollisionPointRec(GetMousePosition(), doorLeft.bound)) || (IsKeyPressed(KEY_SPACE)))
  129. {
  130. if (doorLeft.locked)
  131. {
  132. doorLeft.frameRec.y = 0;
  133. doorLeft.locked = false;
  134. PlaySound(sndDoor);
  135. }
  136. else finishScreen = 1;
  137. }
  138. }
  139. // Door: center
  140. if ((CheckCollisionPointRec(GetMousePosition(), doorCenter.bound)) ||
  141. (CheckCollisionRecs(player.bounds, doorCenter.bound))) doorCenter.selected = true;
  142. else doorCenter.selected = false;
  143. if ((doorCenter.selected) && (CheckCollisionRecs(player.bounds, doorCenter.bound)))
  144. {
  145. if (((IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) && CheckCollisionPointRec(GetMousePosition(), doorCenter.bound)) || (IsKeyPressed(KEY_SPACE)))
  146. {
  147. if (doorCenter.locked)
  148. {
  149. doorCenter.frameRec.y = 0;
  150. doorCenter.locked = false;
  151. PlaySound(sndDoor);
  152. }
  153. else finishScreen = 2;
  154. }
  155. }
  156. }
  157. if (msgState > 2)
  158. {
  159. UpdatePlayer();
  160. // Monsters logic
  161. UpdateMonster(&candle);
  162. UpdateMonster(&picture);
  163. UpdateMonster(&phone);
  164. }
  165. // Check player hover monsters to interact
  166. if (((CheckCollisionRecs(player.bounds, candle.bounds)) && !candle.active) ||
  167. ((CheckCollisionRecs(player.bounds, picture.bounds)) && !picture.active) ||
  168. ((CheckCollisionRecs(player.bounds, phone.bounds)) && !phone.active)) monsterHover = true;
  169. else monsterHover = false;
  170. // Monters logic: candle
  171. if ((CheckCollisionRecs(player.bounds, candle.bounds)) && !candle.active)
  172. {
  173. candle.selected = true;
  174. if ((IsKeyPressed(KEY_SPACE)) ||
  175. ((IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) && (CheckCollisionPointRec(GetMousePosition(), candle.bounds))))
  176. {
  177. SearchKeyPlayer();
  178. searching = true;
  179. framesCounter = 0;
  180. monsterCheck = 1;
  181. }
  182. }
  183. else candle.selected = false;
  184. // Monters logic: picture
  185. if ((CheckCollisionRecs(player.bounds, picture.bounds)) && !picture.active)
  186. {
  187. picture.selected = true;
  188. if ((IsKeyPressed(KEY_SPACE)) ||
  189. ((IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) && (CheckCollisionPointRec(GetMousePosition(), picture.bounds))))
  190. {
  191. SearchKeyPlayer();
  192. searching = true;
  193. framesCounter = 0;
  194. monsterCheck = 2;
  195. }
  196. }
  197. else picture.selected = false;
  198. // Monters logic: phone
  199. if ((CheckCollisionRecs(player.bounds, phone.bounds)) && !phone.active)
  200. {
  201. phone.selected = true;
  202. if ((IsKeyPressed(KEY_SPACE)) ||
  203. ((IsMouseButtonPressed(MOUSE_LEFT_BUTTON)) && (CheckCollisionPointRec(GetMousePosition(), phone.bounds))))
  204. {
  205. SearchKeyPlayer();
  206. searching = true;
  207. framesCounter = 0;
  208. monsterCheck = 3;
  209. }
  210. }
  211. else phone.selected = false;
  212. if (searching)
  213. {
  214. framesCounter++;
  215. if (framesCounter > 180)
  216. {
  217. if (monsterCheck == 1)
  218. {
  219. if (candle.spooky)
  220. {
  221. ScarePlayer();
  222. PlaySound(sndScream);
  223. }
  224. else FindKeyPlayer();
  225. candle.active = true;
  226. candle.selected = false;
  227. }
  228. else if (monsterCheck == 2)
  229. {
  230. if (picture.spooky)
  231. {
  232. ScarePlayer();
  233. PlaySound(sndScream);
  234. }
  235. else FindKeyPlayer();
  236. picture.active = true;
  237. picture.selected = false;
  238. }
  239. else if (monsterCheck == 3)
  240. {
  241. if (phone.spooky)
  242. {
  243. ScarePlayer();
  244. PlaySound(sndScream);
  245. }
  246. else FindKeyPlayer();
  247. phone.active = true;
  248. phone.selected = false;
  249. }
  250. searching = false;
  251. framesCounter = 0;
  252. }
  253. }
  254. // Text animation
  255. framesCounter++;
  256. if ((framesCounter%2) == 0) lettersCounter++;
  257. if (msgState == 0)
  258. {
  259. if (lettersCounter <= (int)strlen(message)) strncpy(msgBuffer, message, lettersCounter);
  260. else
  261. {
  262. for (int i = 0; i < (int)strlen(msgBuffer); i++) msgBuffer[i] = '\0';
  263. lettersCounter = 0;
  264. msgState = 1;
  265. }
  266. if (IsKeyPressed(KEY_ENTER)) msgState = 1;
  267. }
  268. else if (msgState == 1)
  269. {
  270. msgCounter++;
  271. if ((IsKeyPressed(KEY_ENTER)) || (IsMouseButtonPressed(MOUSE_LEFT_BUTTON)))
  272. {
  273. msgState = 2;
  274. msgCounter = 0;
  275. }
  276. }
  277. else if (msgState == 2)
  278. {
  279. msgCounter++;
  280. if (msgCounter > 180) msgState = 3;
  281. }
  282. else msgCounter++;
  283. }
  284. // Gameplay Screen Draw logic
  285. void DrawLivingroomScreen(void)
  286. {
  287. DrawTexture(background, 0, 0, WHITE);
  288. // Draw monsters
  289. DrawMonster(picture, 0);
  290. DrawMonster(candle, 0);
  291. DrawMonster(phone, 0);
  292. // Draw door
  293. if (doorCenter.selected) DrawTextureRec(doors, doorCenter.frameRec, doorCenter.position, GREEN);
  294. else DrawTextureRec(doors, doorCenter.frameRec, doorCenter.position, WHITE);
  295. if (doorLeft.selected) DrawTextureRec(doors, doorLeft.frameRec, doorLeft.position, GREEN);
  296. else DrawTextureRec(doors, doorLeft.frameRec, doorLeft.position, WHITE);
  297. // Draw messsages
  298. if (msgState < 2) DrawRectangle(0, 40, GetScreenWidth(), 200, Fade(LIGHTGRAY, 0.5f));
  299. else if (msgState == 2) DrawRectangle(0, 80, GetScreenWidth(), 100, Fade(LIGHTGRAY, 0.5f));
  300. if (msgState == 0)
  301. {
  302. DrawTextEx(font, msgBuffer, (Vector2){ msgPosX, 80 }, font.baseSize, 2, WHITE);
  303. }
  304. else if (msgState == 1)
  305. {
  306. DrawTextEx(font, message, (Vector2){ msgPosX, 80 }, font.baseSize, 2, WHITE);
  307. if ((msgCounter/30)%2) DrawText("PRESS ENTER or CLICK", GetScreenWidth() - 280, 200, 20, BLACK);
  308. }
  309. else if (msgState == 2)
  310. {
  311. if ((msgCounter/30)%2)
  312. {
  313. DrawTextEx(font, "CHOOSE WISELY!", (Vector2){ 300, 95 }, font.baseSize*2, 2, WHITE);
  314. DrawRectangleRec(candle.bounds, Fade(RED, 0.6f));
  315. DrawRectangleRec(phone.bounds, Fade(RED, 0.6f));
  316. DrawRectangleRec(picture.bounds, Fade(RED, 0.6f));
  317. }
  318. }
  319. else
  320. {
  321. if ((monsterHover) && ((msgCounter/30)%2))
  322. {
  323. DrawRectangle(0, 0, GetScreenWidth(), 50, Fade(LIGHTGRAY, 0.5f));
  324. DrawText("PRESS SPACE or CLICK to INTERACT", 420, 15, 20, BLACK);
  325. }
  326. }
  327. DrawPlayer(); // NOTE: Also draws mouse pointer!
  328. }
  329. // Gameplay Screen Unload logic
  330. void UnloadLivingroomScreen(void)
  331. {
  332. // TODO: Unload GAMEPLAY screen variables here!
  333. UnloadTexture(background);
  334. UnloadMonster(candle);
  335. UnloadMonster(picture);
  336. UnloadMonster(phone);
  337. }
  338. // Gameplay Screen should finish?
  339. int FinishLivingroomScreen(void)
  340. {
  341. return finishScreen;
  342. }