#include "debuggers.h" #include #include #include #include #include namespace pabloader { std::string& rtrim(std::string& str, const std::string& chars = "\t\n\v\f\r ") { str.erase(str.find_last_not_of(chars) + 1); return str; } template <> float Debuggers::GetRandom(float from, float to) { if (from > to) { std::swap(from, to); } std::uniform_real_distribution dist(from, to); return dist(generator); } template <> int Debuggers::GetRandom(int from, int to) { if (from > to) { std::swap(from, to); } std::uniform_int_distribution dist(from, to - 1); return dist(generator); } bool Debuggers::OnUserCreate() { SetPixelMode(olc::Pixel::MASK); std::srand(std::time(0)); if (!olc::SOUND::InitialiseAudio()) { std::cerr << "Cannot init audio" << std::endl; return false; } if (!pack.LoadPack("debuggers.pgp")) { std::cerr << "Cannot load resource pack res/debuggers.pgp" << std::endl; return false; } // Load Player std::string fileName = "res/player.pgs"; if (!playerSprite.LoadFromPGESprFile(fileName, &pack)) { std::cerr << "[Load player] File " << fileName << " is not found" << std::endl; return false; } fileName = "res/fall.wav"; playerFallSample = olc::SOUND::LoadAudioSample(fileName, &pack); if (playerFallSample < 0) { std::cerr << "[Load fall] File " << fileName << " is not found" << std::endl; return false; } // Load enemies fileName = "res/enemies.pgs"; if (!enemiesSprite.LoadFromPGESprFile(fileName, &pack)) { std::cerr << "[Load enemies] File " << fileName << " is not found" << std::endl; return false; } fileName = "res/bug_fall.wav"; bugFallSample = olc::SOUND::LoadAudioSample(fileName, &pack); if (bugFallSample < 0) { std::cerr << "[Load bug fall] File " << fileName << " is not found" << std::endl; return false; } fileName = "res/bug_catch.wav"; bugCatchSample = olc::SOUND::LoadAudioSample(fileName, &pack); if (bugCatchSample < 0) { std::cerr << "[Load bug catch] File " << fileName << " is not found" << std::endl; return false; } // Load bonuses fileName = "res/bonuses.pgs"; if (!bonusesSprite.LoadFromPGESprFile(fileName, &pack)) { std::cerr << "[Load bonuses] File " << fileName << " is not found" << std::endl; return false; } // Load background fileName = "res/bg.pgs"; if (!backgroundSprite.LoadFromPGESprFile(fileName, &pack)) { std::cerr << "[Load background] File " << fileName << " is not found" << std::endl; return false; } fileName = "src/programmer.cpp"; auto streamBuffer = pack.GetStreamBuffer(fileName); if (streamBuffer.data == nullptr) { std::cerr << "[Load source] File " << fileName << " is not found" << std::endl; return false; } std::istream is(&streamBuffer); std::string line; while (std::getline(is, line)) { if (!rtrim(line).empty()) sourceCode.push_back(line); } totalLines = sourceCode.size(); // Free Memory pack.ClearPack(); // Creating entities auto player = new Player(this); programmers.push_back(player); return true; } bool Debuggers::OnUserUpdate(float fElapsedTime) { if (!IsFocused()) return true; if (sourceCode.size() == 0) { return GameOver(); } DrawSprite(0, 0, &backgroundSprite); uint32_t bugsSize = bugs.size(); auto aliveBugs = std::count_if(bugs.begin(), bugs.end(), [](Bug* bug) { return bug->IsActive() && bug->IsAlive(); }); Programmer* player = programmers.at(0); for (auto bug : bugs) { if (bug->IsActive()) { bug->Update(fElapsedTime); bug->Draw(); for (auto& programmer : programmers) { if (programmer->Collides(bug)) { bugsCatched++; if (programmer == player) { bugsCatchedByPlayer++; } bug->Kill(); olc::SOUND::PlaySample(bugCatchSample); SpawnBug(); } } } else if (bug->IsAlive()) { bugsMissed++; sourceCode.erase(sourceCode.begin()); SpawnBug(); olc::SOUND::PlaySample(bugFallSample); } } for (auto& bonus : bonuses) { if (bonus->IsActive()) { bonus->Update(fElapsedTime); bonus->Draw(); if (player->Collides(bonus)) { auto type = bonus->GetType(); if (type == BONUS_DOCUMENTATION) { if (aliveBugs > 1) { for (auto& bug : bugs) { if (bug->IsAlive() && bug->IsActive()) { bug->Kill(); break; } } } } else { bonusesCatched[type]++; } bonus->Kill(); // TODO play pickup sound } } else { bonus->Kill(); } } linesOfCode = (sourceCode.size() * 4 / totalLines) + 1; for (auto it = programmers.rbegin(); it != programmers.rend(); it++) { auto& programmer = *it; programmer->Think(); programmer->Update(fElapsedTime); programmer->Draw(); } if (bugsSize == 0 && player->IsOnGround()) { SpawnBug(); } auto programmersSize = programmers.size(); if (bugsCatchedByPlayer >= 15 * programmersSize * programmersSize && player->GetSkin() < programmersSize) { player->UpgradeLevel(); SpawnBug(); SpawnProgrammer(); } if (bugsCatched > 10 * bugsSize) { SpawnBug(); } if (GetRandom() < 0.01 * fElapsedTime) { SpawnBonus(); } #ifdef _DEBUG if (debug) { DrawString(1, 37, "Bg: " + std::to_string(bugs.size()) + " Ab: " + std::to_string(aliveBugs)); DrawString(1, 46, "Ps: " + std::to_string(programmers.size()) + " Bn: " + std::to_string(bonuses.size())); DrawString(1, 55, "Cp: " + std::to_string(bugsCatchedByPlayer)); DrawString(1, 64, "DBG: " + std::to_string(bonusesCatched[BONUS_DEBUGGER])); DrawString(1, 73, "UTS: " + std::to_string(bonusesCatched[BONUS_UNIT_TEST])); if (GetKey(olc::B).bPressed) { SpawnBug(); } if (GetKey(olc::N).bPressed) { SpawnBonus(); } if (GetKey(olc::P).bPressed) { SpawnProgrammer(); } } if (GetKey(olc::K0).bReleased) { debug = !debug; } #endif DrawString(1, 1, "A,S,D - move; SPACE - jump", olc::CYAN); DrawString(1, 10, "Don't let the bugs destroy your code!", olc::YELLOW); DrawString(1, 19, "Bugs catched: " + std::to_string(bugsCatched)); DrawString(1, 28, "Bugs missed: " + std::to_string(bugsMissed)); int y = GameScreenHeight(); FillRect(0, y - 1, ScreenWidth(), ScreenHeight() - y + 1, olc::VERY_DARK_GREY); for (auto& line : sourceCode) { DrawString(1, y, line); y += 10; if (y >= ScreenHeight()) break; } return true; } bool Debuggers::GameOver() { DrawSprite(0, 0, &backgroundSprite); DrawString(ScreenWidth() / 2 - 143, ScreenHeight() / 2 - 15, "GAME OVER", olc::BLACK, 4); DrawString(ScreenWidth() / 2 - 144, ScreenHeight() / 2 - 16, "GAME OVER", olc::RED, 4); DrawString(ScreenWidth() / 2 - 144, ScreenHeight() / 2 + 16, "Bugs catched: " + std::to_string(bugsCatched), olc::CYAN, 2); return true; } void Debuggers::SpawnBug() { auto bug = CreateBug(); bug->ResetPosition(); } void Debuggers::SpawnBonus() { auto bonus = CreateBonus(); bonus->ResetPosition(); } void Debuggers::SpawnProgrammer() { auto programmer = new Programmer(this); programmers.push_back(programmer); } Bug* Debuggers::CreateBug() { for (auto bug : bugs) { if (!bug->IsActive() || !bug->IsAlive()) return bug; } auto bug = new Bug(this); bugs.push_back(bug); return bug; } Bonus* Debuggers::CreateBonus() { for (auto bonus : bonuses) { if (!bonus->IsActive()) return bonus; } auto bonus = new Bonus(this); bonuses.push_back(bonus); return bonus; } bool Debuggers::OnUserDestroy() { olc::SOUND::DestroyAudio(); return true; } }