#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() { 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 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; } fileName = "res/bonus.wav"; bonusSample = olc::SOUND::LoadAudioSample(fileName, &pack); if (bonusSample < 0) { std::cerr << "[Load bonus] 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()) originalSourceCode.push_back(line); } fileName = "res/hover.wav"; hoverSample = olc::SOUND::LoadAudioSample(fileName, &pack); if (hoverSample < 0) { std::cerr << "[Load hover] File " << fileName << " is not found" << std::endl; return false; } fileName = "res/click.wav"; clickSample = olc::SOUND::LoadAudioSample(fileName, &pack); if (clickSample < 0) { std::cerr << "[Load click] File " << fileName << " is not found" << std::endl; return false; } fileName = "res/music.wav"; bgMusic = olc::SOUND::LoadAudioSample(fileName, &pack); if (bgMusic < 0) { std::cerr << "[Load music] File " << fileName << " is not found" << std::endl; return false; } totalLines = originalSourceCode.size(); // Free Memory pack.ClearPack(); // Creating entities ResetGame(); SwitchState(STATE_MAIN_MENU); olc::SOUND::PlaySample(bgMusic, true); return true; } bool Debuggers::OnUserUpdate(float fElapsedTime) { #ifdef _DEBUG if (debug) { 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 bool result = false; switch (state) { case STATE_GAME: case STATE_MAIN_MENU: result = GamePlay(fElapsedTime); break; case STATE_PAUSE_MENU: result = PauseMenu(fElapsedTime); break; case STATE_HELP: result = HelpMenu(fElapsedTime); break; case STATE_GAME_OVER: result = GameOver(fElapsedTime); break; default: break; } for (auto& button : buttons) { button->Draw(); if (button->Update()) { break; } } return result; } void Debuggers::DrawMenu() { DrawLogo(); std::string resumeText = state == STATE_PAUSE_MENU ? "Continue" : "Start"; if (buttons.size() > 0) { buttons.front()->SetText(resumeText); } } void Debuggers::DrawSourceCode() { 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; } } void Debuggers::DrawLogo() { SetPixelMode(olc::Pixel::ALPHA); FillRect(0, 0, ScreenWidth(), ScreenHeight(), { 0, 0, 0, 128 }); SetPixelMode(olc::Pixel::NORMAL); DrawString(ScreenWidth() / 2 - 144, 32, "DEBUGGERS", olc::YELLOW, 4); DrawString(ScreenWidth() - 128, 64, "by Pabloader"); DrawString(ScreenWidth() - 17 * 8 - 2, ScreenHeight() - 10, "OLC Code Jam 2019"); } void Debuggers::SwitchState(GameState newState) { prevState = state; ClearButtons(); switch (newState) { case STATE_GAME: if (state == STATE_MAIN_MENU || state == STATE_GAME_OVER) { ResetGame(); SpawnPlayer(); } break; case STATE_MAIN_MENU: ResetGame(); SpawnProgrammer(); // fallthrough case STATE_PAUSE_MENU: buttons.push_back(new Button(this, ScreenWidth() / 2 - 64, 100, 128, 16, "Start", STATE_GAME)); buttons.push_back(new Button(this, ScreenWidth() / 2 - 64, 132, 128, 16, "Help", STATE_HELP)); buttons.push_back(new Button(this, ScreenWidth() / 2 - 64, 164, 128, 16, "Quit", STATE_QUIT)); break; case STATE_HELP: buttons.push_back(new Button(this, 16, 64, 64, 16, "Back", prevState)); break; case STATE_GAME_OVER: buttons.push_back(new Button(this, ScreenWidth() / 2 - 64, ScreenHeight() / 2 + 40, 128, 16, "Try again", STATE_GAME)); buttons.push_back(new Button(this, ScreenWidth() / 2 - 64, ScreenHeight() / 2 + 72, 128, 16, "Main menu", STATE_MAIN_MENU)); break; default: break; } state = newState; } void Debuggers::ResetGame() { ClearButtons(); for (auto& i : programmers) { delete i; } programmers.clear(); for (auto& i : bugs) { i->Kill(); } for (auto& i : bonuses) { i->Kill(); } bonusesCatched.clear(); bugsCatched = 0; bugsCatchedByPlayer = 0; bugsMissed = 0; sourceCode = originalSourceCode; } void Debuggers::ClearButtons() { for (auto& i : buttons) { delete i; } buttons.clear(); } void Debuggers::SpawnBug() { auto bug = CreateBug(); bug->ResetPosition(); } void Debuggers::SpawnBugParticles(Bug* bug) { for (auto i = 0; i < 4; i++) { auto particle = CreateBugParticle(); particle->ResetPosition(); particle->ResetParticle(bug, i); } } void Debuggers::SpawnBonus() { auto bonus = CreateBonus(); bonus->ResetPosition(); } void Debuggers::SpawnPlayer() { auto programmer = new Player(this); programmers.push_front(programmer); } 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; } BugParticle* Debuggers::CreateBugParticle() { for (auto particle : particles) { if (!particle->IsActive() || !particle->IsAlive()) return particle; } auto particle = new BugParticle(this); particles.push_back(particle); return particle; } 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; } }