void PhoenixEngine::ChangeState() { if(m_QueuedState == m_LoadingState) { m_CurrentState = m_LoadingState; return; } if(m_QueuedState != nullptr) { if(m_CurrentState != nullptr) { delete m_CurrentState; m_CurrentState = nullptr; } GameState* TemporaryState = m_QueuedState; ToggleLoading(true); TemporaryState->Init(); ToggleLoading(false); m_CurrentState = TemporaryState; Util::msgNote(Util::BuildString("State Loaded: %s", typeid(*m_CurrentState).name())); m_QueuedState = nullptr; } }
void Engine::ChangeState() { if(m_QueuedState == m_LoadingState) { m_CurrentState = m_LoadingState; return; } Util::PrintColor("Entering State ", WHITE); Util::PrintColor(Util::BuildString("%s\n", typeid(*m_QueuedState).name()), GREEN); if(m_QueuedState != nullptr) { if(m_CurrentState != nullptr) { delete m_CurrentState; m_CurrentState = nullptr; ImageManager::ClearCache(); } GameState* TemporaryState = m_QueuedState; ToggleLoading(true); TemporaryState->Init(); ToggleLoading(false); m_CurrentState = TemporaryState; m_QueuedState = nullptr; } }
void Game::Update() { //We have to store the update time and re-get it BEFORE passing it to the level // because the update function is the most time consuming; the time taken within // the function itself is not negligible, so we can't put the restart() after it //Also, we need to put this outside the "if(!paused)" block so that after the game // isn't paused, entities don't think that time passed within the pause //printf("Update length: %lld milliseconds\n", updateTimer.getElapsedTime()); sf::Time updateTime = updateTimer.getElapsedTime(); updateTimer.restart(); shakeTimer += updateTime; if(cheatCounter == 10) { s3.setBuffer(landBuf); s3.play(); levelManager.GetPlayer().AddSoul(); levelManager.GetPlayer().AddSoul(); levelManager.GetPlayer().AddSoul(); levelManager.GetPlayer().AddSoul(); hud.changeText("God mode enabled"); cheatCounter++; } else if(cheatCounter == 11) { levelManager.GetPlayer().AddFuel(100); levelManager.GetPlayer().AddHealth(100); levelManager.GetPlayer().AddHumanity(100); levelManager.GetPlayer().AddEnergy(100); } //Check win/lose conditions if(levelManager.HasLoadedLevel()) { bool win = levelManager.GetCurrentLevel().GetPlayer().GetRemainingSouls() == 0; bool lose = !levelManager.GetCurrentLevel().GetPlayer().IsAlive(); if(win || lose) { fadeoutTimer += updateTime; if(win) { fadeoutRect.setFillColor(sf::Color(255,255,255, (sf::Uint8)(255*fadeoutTimer.asMicroseconds()/(float)fadeoutTime.asMicroseconds()))); } else { fadeoutRect.setFillColor(sf::Color(0,0,0, (sf::Uint8)(255*fadeoutTimer.asMicroseconds()/(float)fadeoutTime.asMicroseconds()))); } if(fadeoutTimer >= fadeoutTime) { if(win) { s1.setBuffer(winBuf); s1.play(); } else { s1.setBuffer(loseBuf); s1.play(); } fadeoutTimer = sf::Time::Zero; shakeTimer = sf::Time::Zero; levelManager.Reset(); menus.WinLose(win); menus.SetVisible(true); } paused = true; } } else { fadeoutRect.setFillColor(sf::Color(0,0,0,0)); } if(!paused) { sf::Vector2f playerPos = levelManager.GetCurrentLevel().GetPlayer().GetPos(); sf::Vector2i levelSize = levelManager.GetCurrentLevel().GetSize(); sf::Vector2f viewSize = view.getSize(); sf::Vector2f viewPos = view.getCenter(); //If the level's about to transition, put up a loading screen if(levelManager.IsTransitioning()) { ToggleLoading(); levelManager.Update(updateTime); ToggleLoading(); } else { //Update the level levelManager.Update(updateTime); } //Update the HUD with values from the level levelManager.GetCurrentLevel().UpdateHUD(hud); //printf("player: (%g, %g) view: (%g, %g)\n", playerPos.x, playerPos.y, viewPos.x, viewPos.y); //Update the view to follow the player, but don't make it go offscreen if(playerPos.x - viewSize.x/2 >= 0 && playerPos.x + viewSize.x/2 <= levelSize.x) view.setCenter(sf::Vector2f(playerPos.x, viewPos.y)); else if(playerPos.x - viewSize.x/2 < 0) view.setCenter(sf::Vector2f(viewSize.x/2, viewPos.y)); else if(playerPos.x + viewSize.x/2 > levelSize.x) view.setCenter(sf::Vector2f(levelSize.x - viewSize.x/2, viewPos.y)); viewPos = view.getCenter(); if(playerPos.y - viewSize.y/2 >= 0 && playerPos.y + viewSize.y/2 <= levelSize.y) view.setCenter(sf::Vector2f(viewPos.x, playerPos.y)); else if(playerPos.y - viewSize.y/2 < 0) view.setCenter(sf::Vector2f(viewPos.x, viewSize.y/2)); else if(playerPos.y + viewSize.y/2 > levelSize.x) view.setCenter(sf::Vector2f(viewPos.x, levelSize.y - viewSize.y/2)); if(!shakeDone) { float shakeProp = 1 - (float)shakeTimer.asMicroseconds()/(float)shakeTime.asMicroseconds(); view.setCenter(sf::Vector2f(view.getCenter().x + getRandom()*8*shakeProp, view.getCenter().y + getRandom()*8*shakeProp)); s1.setVolume(1+99*shakeProp); //printf("%g, %g\n", shakeTimer.asSeconds(), shakeTime.asSeconds()); if(shakeProp <= 0.0f) { s1.stop(); shakeDone = true; } } window.setView(view); } }
void Game::Event() { // --- EVENT PROCESSING --- // Why is "event" a keyword in Visual Studio? We may never know... sf::Event anEvent; while(window.pollEvent(anEvent)) { //This event needs to go before the menu receives the input, so that // the window can still close if the menu's open if(anEvent.type == sf::Event::Closed) { Exit(); } //Pass the menu events and don't pass the game events if the menu is visible else if(menus.IsVisible()) { menus.HandleEvent(anEvent); //If the menu just turned invisible after handling an event, restart the // update timer so that entities don't think they were simulating while // the menu was up updateTimer.restart(); if(!menus.IsVisible()) { paused = false; } } //If no level was loaded before and we are now in the game, load a level if(!paused && !levelManager.HasLoadedLevel()) { ToggleLoading(); levelManager.LoadMap(firstLevel, firstSpawn); ToggleLoading(); s1.setBuffer(shakeBuf); s2.setBuffer(instructBuf); s3.setBuffer(landBuf); s1.play(); s2.play(); s3.play(); } switch(anEvent.type) { case sf::Event::Resized : menus.Resize(sf::Vector2f(anEvent.size.width, anEvent.size.height)); hud.Reposition(sf::Vector2f(0, window.getSize().y)); //Everything else is taken care of elsewhere break; case sf::Event::KeyPressed : //If the game is not paused, allow it to receive events if(!paused) { switch(anEvent.key.code) { //Note: The reason I don't move the player shape within these case statements is twofold: // 1.) Separation of getting input and actually performing the action is VERY important // (even though it was hella annoying in Hogan's class) // 2.) This event is for a key PRESS, so the player will only move once even if the // key is held down! Yes, there is a property on the window that allows keys to repeat // their presses if held down that I turned off earlier, but I did that because there's // a delay between getting the press and actually determining that the key is held down. case sf::Keyboard::W : levelManager.GetPlayer().MoveUp(true); break; case sf::Keyboard::S : levelManager.GetPlayer().MoveDown(true); break; case sf::Keyboard::A : levelManager.GetPlayer().MoveLeft(true); AddCheatCounter(9, -1); break; case sf::Keyboard::D : levelManager.GetPlayer().MoveRight(true); break; case sf::Keyboard::F : levelManager.GetPlayer().ToggleLighter(); break; case sf::Keyboard::E : levelManager.GetCurrentLevel().DoActivate(); break; case sf::Keyboard::Space : levelManager.GetPlayer().StartAttack(); break; case sf::Keyboard::LShift : case sf::Keyboard::RShift : levelManager.GetCurrentLevel().GetPlayer().Sprint(true); break; case sf::Keyboard::Escape : menus.SetVisible(true); paused = true; break; case sf::Keyboard::Up : AddCheatCounter(0, 1); break; case sf::Keyboard::Down : AddCheatCounter(2, 3); break; case sf::Keyboard::Left : AddCheatCounter(4, 6); break; case sf::Keyboard::Right : AddCheatCounter(5, 7); break; case sf::Keyboard::B : AddCheatCounter(8, -1); default: break; } } break; case sf::Event::KeyReleased : //If the game is not paused, allow it to receive events if(!paused) { switch(anEvent.key.code) { case sf::Keyboard::W : levelManager.GetPlayer().MoveUp(false); break; case sf::Keyboard::S : levelManager.GetPlayer().MoveDown(false); break; case sf::Keyboard::A : levelManager.GetPlayer().MoveLeft(false); break; case sf::Keyboard::D : levelManager.GetPlayer().MoveRight(false); break; case sf::Keyboard::LShift : case sf::Keyboard::RShift : levelManager.GetPlayer().Sprint(false); break; default: break; } break; } default : break; } } }