#include "application.h" #include "core/inputtype.h" #include "core/editor.h" #include "mainmenu.h" #include "gamestate.h" #include "editorstate.h" #include "tools/music.h" #include "classicmode/classicfactorysfml.h" #include const sf::Time TIME_PER_FRAME = sf::seconds(1.f / 90.f); Application::Application() : _game_window(std::make_unique(sf::VideoMode{1280, 720}, "Test", sf::Style::Default)) { _font_holder.load(Fonts::Id::GUI, "SourceCodePro-Regular.ttf"); _game_window->setFramerateLimit(60); _game_window->setKeyRepeatEnabled(false); _game_window->setMouseCursorGrabbed(false); _game_window->setVerticalSyncEnabled(true); MainMenu::Callbacks callbacks = { [&](){ pushState(GUIState::Tag::GAME); }, [&](){ pushState(GUIState::Tag::EDITOR); } }; EditorState::Callbacks editor_callbacks = {[&](){ popState(); }}; const auto main_menu = std::make_shared(std::move(callbacks), _font_holder); const auto game_state = std::make_shared(classic::initGame(_game_window), GameState::Callbacks()); const auto editor = std::make_shared(classic::initEditor(_game_window), std::move(editor_callbacks), _font_holder); _states[GUIState::Tag::MAIN_MENU] = main_menu; _states[GUIState::Tag::GAME] = game_state; _states[GUIState::Tag::EDITOR] = editor; pushState(GUIState::Tag::MAIN_MENU); } void Application::run() { _game_window->display(); exec(); } void Application::exec() { sf::Clock timer; sf::Time time_since_last_update = sf::Time::Zero; while (_game_window->isOpen()) { time_since_last_update += timer.restart(); input(); bool isOneFramePassed = time_since_last_update >= TIME_PER_FRAME; if (isOneFramePassed) { time_since_last_update -= TIME_PER_FRAME; update(time_since_last_update); draw(); } } } void Application::input() { sf::Event event; while (_game_window->pollEvent(event)) { switch(event.type) { case sf::Event::Closed: _game_window->close(); break; default: _state_stack.back()->input(event); break; } } } void Application::update(const sf::Time& dt) { _state_stack.back()->update(dt); } void Application::draw() { _game_window->clear(); for (const auto& state : _state_stack) _game_window->draw(*state); _game_window->display(); } void Application::pushState(GUIState::Tag new_state) { if (!_state_stack.empty()) _state_stack.back()->leave(); _state_stack.emplace_back(_states.at(new_state)); _state_stack.back()->enter(_game_window->getSize()); } void Application::popState() { _state_stack.back()->leave(); _state_stack.pop_back(); _state_stack.back()->enter(_game_window->getSize()); }