説明なし
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

debuggers.cpp 9.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373
  1. #include "debuggers.h"
  2. #include <algorithm>
  3. #include <cmath>
  4. #include <ctime>
  5. #include <iostream>
  6. #include <random>
  7. namespace pabloader {
  8. std::string& rtrim(std::string& str, const std::string& chars = "\t\n\v\f\r ")
  9. {
  10. str.erase(str.find_last_not_of(chars) + 1);
  11. return str;
  12. }
  13. template <>
  14. float Debuggers::GetRandom<float>(float from, float to)
  15. {
  16. if (from > to) {
  17. std::swap(from, to);
  18. }
  19. std::uniform_real_distribution<float> dist(from, to);
  20. return dist(generator);
  21. }
  22. template <>
  23. int Debuggers::GetRandom<int>(int from, int to)
  24. {
  25. if (from > to) {
  26. std::swap(from, to);
  27. }
  28. std::uniform_int_distribution<int> dist(from, to - 1);
  29. return dist(generator);
  30. }
  31. bool Debuggers::OnUserCreate()
  32. {
  33. std::srand(std::time(0));
  34. if (!olc::SOUND::InitialiseAudio()) {
  35. std::cerr << "Cannot init audio" << std::endl;
  36. return false;
  37. }
  38. if (!pack.LoadPack("debuggers.pgp")) {
  39. std::cerr << "Cannot load resource pack debuggers.pgp" << std::endl;
  40. return false;
  41. }
  42. // Load Player
  43. std::string fileName = "res/player.pgs";
  44. if (!playerSprite.LoadFromPGESprFile(fileName, &pack)) {
  45. std::cerr << "[Load player] File " << fileName << " is not found" << std::endl;
  46. return false;
  47. }
  48. fileName = "res/fall.wav";
  49. playerFallSample = olc::SOUND::LoadAudioSample(fileName, &pack);
  50. if (playerFallSample < 0) {
  51. std::cerr << "[Load fall] File " << fileName << " is not found" << std::endl;
  52. return false;
  53. }
  54. // Load enemies
  55. fileName = "res/enemies.pgs";
  56. if (!enemiesSprite.LoadFromPGESprFile(fileName, &pack)) {
  57. std::cerr << "[Load enemies] File " << fileName << " is not found" << std::endl;
  58. return false;
  59. }
  60. fileName = "res/bug_fall.wav";
  61. bugFallSample = olc::SOUND::LoadAudioSample(fileName, &pack);
  62. if (bugFallSample < 0) {
  63. std::cerr << "[Load bug fall] File " << fileName << " is not found" << std::endl;
  64. return false;
  65. }
  66. fileName = "res/bug_catch.wav";
  67. bugCatchSample = olc::SOUND::LoadAudioSample(fileName, &pack);
  68. if (bugCatchSample < 0) {
  69. std::cerr << "[Load bug catch] File " << fileName << " is not found" << std::endl;
  70. return false;
  71. }
  72. // Load bonuses
  73. fileName = "res/bonuses.pgs";
  74. if (!bonusesSprite.LoadFromPGESprFile(fileName, &pack)) {
  75. std::cerr << "[Load bonuses] File " << fileName << " is not found" << std::endl;
  76. return false;
  77. }
  78. fileName = "res/bonus.wav";
  79. bonusSample = olc::SOUND::LoadAudioSample(fileName, &pack);
  80. if (bonusSample < 0) {
  81. std::cerr << "[Load bonus] File " << fileName << " is not found" << std::endl;
  82. return false;
  83. }
  84. // Load background
  85. fileName = "res/bg.pgs";
  86. if (!backgroundSprite.LoadFromPGESprFile(fileName, &pack)) {
  87. std::cerr << "[Load background] File " << fileName << " is not found" << std::endl;
  88. return false;
  89. }
  90. fileName = "src/programmer.cpp";
  91. auto streamBuffer = pack.GetStreamBuffer(fileName);
  92. if (streamBuffer.data == nullptr) {
  93. std::cerr << "[Load source] File " << fileName << " is not found" << std::endl;
  94. return false;
  95. }
  96. std::istream is(&streamBuffer);
  97. std::string line;
  98. while (std::getline(is, line)) {
  99. if (!rtrim(line).empty())
  100. originalSourceCode.push_back(line);
  101. }
  102. fileName = "res/hover.wav";
  103. hoverSample = olc::SOUND::LoadAudioSample(fileName, &pack);
  104. if (hoverSample < 0) {
  105. std::cerr << "[Load hover] File " << fileName << " is not found" << std::endl;
  106. return false;
  107. }
  108. fileName = "res/click.wav";
  109. clickSample = olc::SOUND::LoadAudioSample(fileName, &pack);
  110. if (clickSample < 0) {
  111. std::cerr << "[Load click] File " << fileName << " is not found" << std::endl;
  112. return false;
  113. }
  114. fileName = "res/music.wav";
  115. bgMusic = olc::SOUND::LoadAudioSample(fileName, &pack);
  116. if (bgMusic < 0) {
  117. std::cerr << "[Load music] File " << fileName << " is not found" << std::endl;
  118. return false;
  119. }
  120. totalLines = originalSourceCode.size();
  121. // Free Memory
  122. pack.ClearPack();
  123. // Creating entities
  124. ResetGame();
  125. SwitchState(STATE_MAIN_MENU);
  126. olc::SOUND::PlaySample(bgMusic, true);
  127. return true;
  128. }
  129. bool Debuggers::OnUserUpdate(float fElapsedTime)
  130. {
  131. #ifdef _DEBUG
  132. if (debug) {
  133. if (GetKey(olc::B).bPressed) {
  134. SpawnBug();
  135. }
  136. if (GetKey(olc::N).bPressed) {
  137. SpawnBonus();
  138. }
  139. if (GetKey(olc::P).bPressed) {
  140. SpawnProgrammer();
  141. }
  142. }
  143. if (GetKey(olc::K0).bReleased) {
  144. debug = !debug;
  145. }
  146. #endif
  147. bool result = false;
  148. switch (state) {
  149. case STATE_GAME:
  150. case STATE_MAIN_MENU:
  151. result = GamePlay(fElapsedTime);
  152. break;
  153. case STATE_PAUSE_MENU:
  154. result = PauseMenu(fElapsedTime);
  155. break;
  156. case STATE_HELP:
  157. result = HelpMenu(fElapsedTime);
  158. break;
  159. case STATE_GAME_OVER:
  160. result = GameOver(fElapsedTime);
  161. break;
  162. default:
  163. break;
  164. }
  165. for (auto& button : buttons) {
  166. button->Draw();
  167. if (button->Update()) {
  168. break;
  169. }
  170. }
  171. return result;
  172. }
  173. void Debuggers::DrawMenu()
  174. {
  175. DrawLogo();
  176. std::string resumeText = state == STATE_PAUSE_MENU ? "Continue" : "Start";
  177. if (buttons.size() > 0) {
  178. buttons.front()->SetText(resumeText);
  179. }
  180. }
  181. void Debuggers::DrawSourceCode()
  182. {
  183. int y = GameScreenHeight();
  184. FillRect(0, y - 1, ScreenWidth(), ScreenHeight() - y + 1, olc::VERY_DARK_GREY);
  185. for (auto& line : sourceCode) {
  186. DrawString(1, y, line);
  187. y += 10;
  188. if (y >= ScreenHeight())
  189. break;
  190. }
  191. }
  192. void Debuggers::DrawLogo()
  193. {
  194. SetPixelMode(olc::Pixel::ALPHA);
  195. FillRect(0, 0, ScreenWidth(), ScreenHeight(), { 0, 0, 0, 128 });
  196. SetPixelMode(olc::Pixel::NORMAL);
  197. DrawString(ScreenWidth() / 2 - 144, 32, "DEBUGGERS", olc::YELLOW, 4);
  198. DrawString(ScreenWidth() - 128, 64, "by Pabloader");
  199. DrawString(ScreenWidth() - 17 * 8 - 2, ScreenHeight() - 10, "OLC Code Jam 2019");
  200. }
  201. void Debuggers::SwitchState(GameState newState)
  202. {
  203. prevState = state;
  204. ClearButtons();
  205. switch (newState) {
  206. case STATE_GAME:
  207. if (state == STATE_MAIN_MENU || state == STATE_GAME_OVER) {
  208. ResetGame();
  209. SpawnPlayer();
  210. }
  211. break;
  212. case STATE_MAIN_MENU:
  213. ResetGame();
  214. SpawnProgrammer();
  215. // fallthrough
  216. case STATE_PAUSE_MENU:
  217. buttons.push_back(new Button(this, ScreenWidth() / 2 - 64, 100, 128, 16, "Start", STATE_GAME));
  218. buttons.push_back(new Button(this, ScreenWidth() / 2 - 64, 132, 128, 16, "Help", STATE_HELP));
  219. buttons.push_back(new Button(this, ScreenWidth() / 2 - 64, 164, 128, 16, "Quit", STATE_QUIT));
  220. break;
  221. case STATE_HELP:
  222. buttons.push_back(new Button(this, 16, 64, 64, 16, "Back", prevState));
  223. break;
  224. case STATE_GAME_OVER:
  225. buttons.push_back(new Button(this, ScreenWidth() / 2 - 64, ScreenHeight() / 2 + 40, 128, 16, "Try again", STATE_GAME));
  226. buttons.push_back(new Button(this, ScreenWidth() / 2 - 64, ScreenHeight() / 2 + 72, 128, 16, "Main menu", STATE_MAIN_MENU));
  227. break;
  228. default:
  229. break;
  230. }
  231. state = newState;
  232. }
  233. void Debuggers::ResetGame()
  234. {
  235. ClearButtons();
  236. for (auto& i : programmers) {
  237. delete i;
  238. }
  239. programmers.clear();
  240. for (auto& i : bugs) {
  241. i->Kill();
  242. }
  243. for (auto& i : bonuses) {
  244. i->Kill();
  245. }
  246. bonusesCatched.clear();
  247. bugsCatched = 0;
  248. bugsCatchedByPlayer = 0;
  249. bugsMissed = 0;
  250. sourceCode = originalSourceCode;
  251. }
  252. void Debuggers::ClearButtons()
  253. {
  254. for (auto& i : buttons) {
  255. delete i;
  256. }
  257. buttons.clear();
  258. }
  259. void Debuggers::SpawnBug()
  260. {
  261. auto bug = CreateBug();
  262. bug->ResetPosition();
  263. }
  264. void Debuggers::SpawnBugParticles(Bug* bug)
  265. {
  266. for (auto i = 0; i < 4; i++) {
  267. auto particle = CreateBugParticle();
  268. particle->ResetPosition();
  269. particle->ResetParticle(bug, i);
  270. }
  271. }
  272. void Debuggers::SpawnBonus()
  273. {
  274. auto bonus = CreateBonus();
  275. bonus->ResetPosition();
  276. }
  277. void Debuggers::SpawnPlayer()
  278. {
  279. auto programmer = new Player(this);
  280. programmers.push_front(programmer);
  281. }
  282. void Debuggers::SpawnProgrammer()
  283. {
  284. auto programmer = new Programmer(this);
  285. programmers.push_back(programmer);
  286. }
  287. Bug* Debuggers::CreateBug()
  288. {
  289. for (auto bug : bugs) {
  290. if (!bug->IsActive() || !bug->IsAlive())
  291. return bug;
  292. }
  293. auto bug = new Bug(this);
  294. bugs.push_back(bug);
  295. return bug;
  296. }
  297. BugParticle* Debuggers::CreateBugParticle()
  298. {
  299. for (auto particle : particles) {
  300. if (!particle->IsActive() || !particle->IsAlive())
  301. return particle;
  302. }
  303. auto particle = new BugParticle(this);
  304. particles.push_back(particle);
  305. return particle;
  306. }
  307. Bonus* Debuggers::CreateBonus()
  308. {
  309. for (auto bonus : bonuses) {
  310. if (!bonus->IsActive())
  311. return bonus;
  312. }
  313. auto bonus = new Bonus(this);
  314. bonuses.push_back(bonus);
  315. return bonus;
  316. }
  317. bool Debuggers::OnUserDestroy()
  318. {
  319. olc::SOUND::DestroyAudio();
  320. return true;
  321. }
  322. }