diff --git a/core/shared/core/game.h b/core/shared/core/game.h index f43ddd9..721ed8c 100644 --- a/core/shared/core/game.h +++ b/core/shared/core/game.h @@ -2,14 +2,17 @@ #include "core/inputtype.h" #include "core/updatedata.h" +#include -class Game +class Game : public sf::Drawable { public: virtual ~Game() = default; virtual void run() = 0; - virtual void input(PlayerInput&& inputdata) = 0; virtual void update(UpdateData&& updatedata) = 0; + + // Separate CORE from SFML in the future + virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const = 0; }; diff --git a/include/state.h b/include/state.h index f07b017..eb8b2ac 100644 --- a/include/state.h +++ b/include/state.h @@ -3,9 +3,12 @@ #include #include #include + #include +#include +#include -class GUIState +class GUIState : public sf::Drawable { public: @@ -25,8 +28,8 @@ public: virtual void input(const sf::Event& event) = 0; virtual void update(const sf::Time& dt) = 0; - virtual void draw() const = 0; + virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override = 0; - virtual void enter() = 0; + virtual void enter(sf::Vector2u&& render_size) = 0; virtual void leave() = 0; }; diff --git a/modes/classicmode/classicfactory.cpp b/modes/classicmode/classicfactory.cpp index 3d07926..c64bc17 100644 --- a/modes/classicmode/classicfactory.cpp +++ b/modes/classicmode/classicfactory.cpp @@ -1,6 +1,6 @@ #include "shared/classicmode/classicfactory.h" #include "game/classicgame.h" -#include "game/classicgraphicsmanager.h" +#include "graphics/classicgraphicsmanager.h" #include "tools/music.h" #include "editor/classiceditor.h" diff --git a/modes/classicmode/editor/mockclassicnote.cpp b/modes/classicmode/editor/mockclassicnote.cpp index 88544ef..998e8e5 100644 --- a/modes/classicmode/editor/mockclassicnote.cpp +++ b/modes/classicmode/editor/mockclassicnote.cpp @@ -1,5 +1,5 @@ #include "mockclassicnote.h" -#include "game/classicgraphicsmanager.h" +#include "graphics/classicgraphicsmanager.h" // Replace with interface by dependency injection #include "graphics/classicflyinganimationscenario.h" diff --git a/modes/classicmode/game/classicarrownote.cpp b/modes/classicmode/game/classicarrownote.cpp index 2a538e3..6f01110 100644 --- a/modes/classicmode/game/classicarrownote.cpp +++ b/modes/classicmode/game/classicarrownote.cpp @@ -1,5 +1,5 @@ #include "classicarrownote.h" -#include "game/classicgraphicsmanager.h" +#include "graphics/classicgraphicsmanager.h" #include "graphics/classicanimationscenario.h" #include "holdmanager.h" diff --git a/modes/classicmode/game/classicgame.cpp b/modes/classicmode/game/classicgame.cpp index 705d401..753e7c5 100644 --- a/modes/classicmode/game/classicgame.cpp +++ b/modes/classicmode/game/classicgame.cpp @@ -1,10 +1,11 @@ #include "classicgame.h" #include "classicnote.h" #include "classicmapcreator.h" -#include "game/classicgraphicsmanager.h" +#include "game/classicgamegraphicsmanager.h" #include "holdmanager.h" ClassicGame::ClassicGame() : + _graphics_manager(new ClassicGameGraphicsManager(_timeline, 1648648)), _hold_manager(std::make_unique()) { _slap_buffer.loadFromFile("Tick.ogg"); @@ -93,11 +94,21 @@ void ClassicGame::input(PlayerInput&& inputdata) void ClassicGame::update(UpdateData&& updatedata) { + // UNCOMMENT TO TEST AUTOPLAY + /*auto note_it = _timeline.getActiveNote(updatedata.timestamp); + + if (!_timeline.isExpired(note_it) && updatedata.timestamp >= (*note_it)->offset()) + { + auto note = (*note_it); + note->input(PlayerInput{updatedata.timestamp, sf::Event{}}); + _slap.play(); + }*/ + _timeline.update(updatedata.timestamp); _graphics_manager->update(updatedata.timestamp); } -void ClassicGame::draw() const +void ClassicGame::draw(sf::RenderTarget& target, sf::RenderStates states) const { - _graphics_manager->draw(); + _graphics_manager->draw(target, states); } diff --git a/modes/classicmode/game/classicgame.h b/modes/classicmode/game/classicgame.h index af8e39f..79c47b3 100644 --- a/modes/classicmode/game/classicgame.h +++ b/modes/classicmode/game/classicgame.h @@ -27,14 +27,14 @@ public: virtual void input(PlayerInput&& inputdata) override; virtual void update(UpdateData&& updatedata) override; - virtual void draw() const override; + virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override; private: std::map _keys_to_buttons; std::map _buttons_to_pressed_actions; std::map _buttons_to_released_actions; - std::unique_ptr _graphics_manager; + ClassicGraphicsManager * const _graphics_manager; std::shared_ptr _hold_manager; Timeline _timeline; diff --git a/modes/classicmode/game/classicgraphicsmanager.cpp b/modes/classicmode/game/classicgamegraphicsmanager.cpp similarity index 67% rename from modes/classicmode/game/classicgraphicsmanager.cpp rename to modes/classicmode/game/classicgamegraphicsmanager.cpp index 9127b26..b3ba9f7 100644 --- a/modes/classicmode/game/classicgraphicsmanager.cpp +++ b/modes/classicmode/game/classicgamegraphicsmanager.cpp @@ -1,21 +1,18 @@ -#include "classicgraphicsmanager.h" +#include "classicgamegraphicsmanager.h" #include "graphics/classicsprite.h" #include "graphics/classicflyinganimationscenario.h" #include "graphics/classicdyinganimationscenario.h" -ClassicGraphicsManager::ClassicGraphicsManager(Timeline &timeline, const microsec& visibility_offset) : - _sprite_container({Type::UP, Type::DOWN, - Type::LEFT, Type::RIGHT}, - std::make_unique()), - _timeline(&timeline), - _visibility_offset(visibility_offset) +ClassicGameGraphicsManager::ClassicGameGraphicsManager(Timeline &timeline, const microsec& visibility_offset) : + ClassicGraphicsManager(visibility_offset), + _timeline(&timeline) { _timeline->expire(_first); _timeline->expire(_last); } -void ClassicGraphicsManager::draw(sf::RenderTarget& target, sf::RenderStates states) const +void ClassicGameGraphicsManager::draw(sf::RenderTarget& target, sf::RenderStates states) const { if (nothingToDraw()) return; @@ -26,7 +23,7 @@ void ClassicGraphicsManager::draw(sf::RenderTarget& target, sf::RenderStates sta } } -void ClassicGraphicsManager::draw(const std::vector& elements, sf::RenderTarget& target, sf::RenderStates states) const +void ClassicGameGraphicsManager::draw(const std::vector& elements, sf::RenderTarget& target, sf::RenderStates states) const { for (std::size_t i = 0; i < elements.size(); ++i) { @@ -46,7 +43,7 @@ void ClassicGraphicsManager::draw(const std::vector& elements, TimeRange &&range) +void ClassicGameGraphicsManager::setGraphics(std::vector& elements, TimeRange &&range) { for (auto& element : elements) { @@ -74,13 +71,21 @@ void ClassicGraphicsManager::setGraphics(std::vectorupdate(offset); } -void ClassicGraphicsManager::fetchFirstNote(const microsec& offset) +void ClassicGameGraphicsManager::fetchFirstNote(const microsec& offset) { (void)offset; // ???? @@ -98,7 +103,7 @@ void ClassicGraphicsManager::fetchFirstNote(const microsec& offset) } } -void ClassicGraphicsManager::fetchLastNote(const microsec& offset) +void ClassicGameGraphicsManager::fetchLastNote(const microsec& offset) { Iterator note_iterator = _timeline->getTopNote(); while (!_timeline->isExpired(note_iterator) && isVisiblyClose(note_iterator, offset)) @@ -120,13 +125,13 @@ void ClassicGraphicsManager::fetchLastNote(const microsec& offset) _last = note_iterator; } -bool ClassicGraphicsManager::nothingToDraw() const noexcept +bool ClassicGameGraphicsManager::nothingToDraw() const noexcept { return _timeline->isExpired(_first) || _timeline->isExpired(_last); } -bool ClassicGraphicsManager::isVisiblyClose(const Iterator& iterator, const microsec& music_offset) const noexcept +bool ClassicGameGraphicsManager::isVisiblyClose(const Iterator& iterator, const microsec& music_offset) const noexcept { return ((*iterator)->offset() - _visibility_offset) <= music_offset; } diff --git a/modes/classicmode/game/classicgraphicsmanager.h b/modes/classicmode/game/classicgamegraphicsmanager.h similarity index 50% rename from modes/classicmode/game/classicgraphicsmanager.h rename to modes/classicmode/game/classicgamegraphicsmanager.h index d439f01..f8c60e4 100644 --- a/modes/classicmode/game/classicgraphicsmanager.h +++ b/modes/classicmode/game/classicgamegraphicsmanager.h @@ -1,27 +1,22 @@ #pragma once -#include "spritecontainer.h" -#include "classicmode/classicactions.h" -#include "graphics/classicspritefactory.h" -#include "classicarrownote.h" +#include "graphics/classicgraphicsmanager.h" #include "core/timeline.h" #include class ClassicSprite; -class ClassicGraphicsManager : public sf::Drawable +class ClassicGameGraphicsManager : public ClassicGraphicsManager { public: - explicit ClassicGraphicsManager(Timeline& timeline, const microsec& visibility_offset); + explicit ClassicGameGraphicsManager(Timeline& timeline, const microsec& visibility_offset); virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override; - void draw(const std::vector& elements, sf::RenderTarget& target, sf::RenderStates states) const; - void setGraphics(std::vector &elements, TimeRange&& range); + virtual void draw(const std::vector& elements, sf::RenderTarget& target, sf::RenderStates states) const override; + virtual void setGraphics(std::vector &elements, TimeRange&& range) override; - void update(const microsec& offset); - void fetchFirstNote(const microsec& offset); - void fetchLastNote(const microsec& offset); + virtual void update(const microsec& offset) override; private: using Iterator = Timeline::Iterator; @@ -29,12 +24,13 @@ private: Iterator _first; Iterator _last; - SpriteContainer _sprite_container; Timeline * const _timeline; - microsec _visibility_offset; - inline bool nothingToDraw() const noexcept; inline bool isVisiblyClose(const Iterator& iterator, const microsec& music_offset) const noexcept; inline sf::VertexArray makeLine(const Coordinates& c1, const Coordinates& c2) const; + + void fetchFirstNote(const microsec& offset); + void fetchLastNote(const microsec& offset); + void updateVisibleNotes(const microsec& offset); }; diff --git a/modes/classicmode/game/classicmapcreator.cpp b/modes/classicmode/game/classicmapcreator.cpp index dbdec05..e8526cb 100644 --- a/modes/classicmode/game/classicmapcreator.cpp +++ b/modes/classicmode/game/classicmapcreator.cpp @@ -10,7 +10,7 @@ auto classic::createBeatmap(const std::string& filepath, const Context &context) { (void) filepath; - microsec starting_beat_offset = 362162; + microsec starting_beat_offset = 402162; int amount_of_beats = 209; microsec interval = 1412162; microsec tempo_interval = interval / 4; diff --git a/modes/classicmode/game/classicnote.cpp b/modes/classicmode/game/classicnote.cpp index b35071a..2ee4d03 100644 --- a/modes/classicmode/game/classicnote.cpp +++ b/modes/classicmode/game/classicnote.cpp @@ -1,11 +1,4 @@ #include "classicnote.h" -#include "graphics/classicsprite.h" -#include "game/classicgraphicsmanager.h" - -// Replace with interface by dependency injection -#include "graphics/classicflyinganimationscenario.h" -#include "graphics/classicdyinganimationscenario.h" -// ClassicNote::ClassicNote(NoteInitializer &&init) : Note(init.perfect_offset), diff --git a/modes/classicmode/graphics/classicgraphicsmanager.h b/modes/classicmode/graphics/classicgraphicsmanager.h new file mode 100644 index 0000000..25f7d09 --- /dev/null +++ b/modes/classicmode/graphics/classicgraphicsmanager.h @@ -0,0 +1,32 @@ +#pragma once + +#include "game/classicarrownote.h" +#include "spritecontainer.h" +#include "classicmode/classicactions.h" +#include "graphics/classicspritefactory.h" + +#include + +class ClassicSprite; + +class ClassicGraphicsManager : public sf::Drawable +{ +public: + virtual ~ClassicGraphicsManager() = default; + explicit ClassicGraphicsManager(const microsec& visibility_offset) : + _sprite_container({Type::UP, Type::DOWN, + Type::LEFT, Type::RIGHT}, + std::make_unique()), + _visibility_offset(visibility_offset) + {} + + virtual void draw(const std::vector& elements, sf::RenderTarget& target, sf::RenderStates states) const = 0; + virtual void setGraphics(std::vector &elements, TimeRange&& range) = 0; + + virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override = 0; + virtual void update(const microsec& offset) = 0; + +protected: + SpriteContainer _sprite_container; + microsec _visibility_offset; +}; diff --git a/src/application/application.cpp b/src/application/application.cpp index 720a4f7..189a864 100644 --- a/src/application/application.cpp +++ b/src/application/application.cpp @@ -31,15 +31,15 @@ Application::Application() : EditorState::Callbacks editor_callbacks = {[&](){ popState(); }}; - const auto main_menu = std::make_shared(_game_window, std::move(callbacks), _font_holder); - const auto game_state = std::make_shared(_game_window, classic::initGame(), GameState::Callbacks()); - const auto editor = std::make_shared(_game_window, classic::initEditor(), std::move(editor_callbacks), _font_holder); + const auto main_menu = std::make_shared(std::move(callbacks), _font_holder); + const auto game_state = std::make_shared(classic::initGame(), GameState::Callbacks()); + const auto editor = std::make_shared(classic::initEditor(), std::move(editor_callbacks), _font_holder); _states[GUIState::Tag::MAIN_MENU] = main_menu; _states[GUIState::Tag::GAME] = game_state; _states[GUIState::Tag::EDITOR] = editor; - _state_stack.emplace_back(_states.at(GUIState::Tag::MAIN_MENU)); + pushState(GUIState::Tag::MAIN_MENU); } void Application::run() @@ -97,21 +97,23 @@ void Application::draw() _game_window.clear(); for (const auto& state : _state_stack) - state->draw(); + _game_window.draw(*state); _game_window.display(); } void Application::pushState(GUIState::Tag new_state) { - _state_stack.back()->leave(); + if (!_state_stack.empty()) + _state_stack.back()->leave(); + _state_stack.emplace_back(_states.at(new_state)); - _state_stack.back()->enter(); + _state_stack.back()->enter(_game_window.getSize()); } void Application::popState() { _state_stack.back()->leave(); _state_stack.pop_back(); - _state_stack.back()->enter(); + _state_stack.back()->enter(_game_window.getSize()); } diff --git a/src/application/editorstate.cpp b/src/application/editorstate.cpp index 277df8c..5c764dc 100644 --- a/src/application/editorstate.cpp +++ b/src/application/editorstate.cpp @@ -11,9 +11,8 @@ #include -EditorState::EditorState(sf::RenderWindow& game_window, std::unique_ptr&& editor, Callbacks&& callbacks, const FontHolder& font_holder) : +EditorState::EditorState(std::unique_ptr&& editor, Callbacks&& callbacks, const FontHolder& font_holder) : _font(font_holder.get(Fonts::Id::GUI)), - _game_window(game_window), _callbacks(std::move(callbacks)), _editor(std::move(editor)) {} @@ -31,12 +30,12 @@ void EditorState::update(const sf::Time& dt) _group->update(dt); } -void EditorState::draw() const +void EditorState::draw(sf::RenderTarget &target, sf::RenderStates states) const { - _game_window.draw(*_group); + target.draw(*_group, states); } -void EditorState::enter() +void EditorState::enter(sf::Vector2u &&render_size) { _music.openFromFile("METEOR.flac"); _music.setVolume(5); @@ -95,7 +94,7 @@ void EditorState::enter() group->unblock(); }; - const float window_width = _game_window.getSize().x; + const float window_width = render_size.x; auto menu_bar = std::make_shared(_font); @@ -107,7 +106,9 @@ void EditorState::enter() bpm_widget->setVisibility(true); }); - bpm_widget->setRect(sf::FloatRect(_game_window.getSize().x / 3, _game_window.getSize().y / 3, _game_window.getSize().x / 3, _game_window.getSize().y / 3)); + bpm_widget->setRect(sf::FloatRect(render_size.x / 3, render_size.y / 3, + render_size.x / 3, render_size.y / 3)); + bpm_widget->addBarButton("X", bpm_widget_callback); bpm_widget->setVisibility(false); diff --git a/src/application/editorstate.h b/src/application/editorstate.h index 06d5c8b..8f5e3f0 100644 --- a/src/application/editorstate.h +++ b/src/application/editorstate.h @@ -18,18 +18,17 @@ public: std::function onLeaveEditorState; }; - explicit EditorState(sf::RenderWindow& game_window, std::unique_ptr&& editor, Callbacks&& callbacks, const FontHolder& font_holder); + explicit EditorState(std::unique_ptr&& editor, Callbacks&& callbacks, const FontHolder& font_holder); virtual ~EditorState() override; virtual void input(const sf::Event& event) override; virtual void update(const sf::Time& dt) override; - virtual void draw() const override; + virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override; - virtual void enter() override; + virtual void enter(sf::Vector2u&& render_size) override; virtual void leave() override; private: const std::shared_ptr _font; - sf::RenderWindow& _game_window; Callbacks _callbacks; diff --git a/src/application/gamestate.cpp b/src/application/gamestate.cpp index f975c6f..fe77b8b 100644 --- a/src/application/gamestate.cpp +++ b/src/application/gamestate.cpp @@ -4,10 +4,8 @@ #include "core/game.h" -GameState::GameState(sf::RenderWindow& game_window, const std::shared_ptr& game, - Callbacks&& callbacks) : +GameState::GameState(const std::shared_ptr& game, Callbacks&& callbacks) : _game(game), - _game_window(game_window), _onLeaveGameCallback(callbacks.onLeaveGame) {} @@ -24,13 +22,14 @@ void GameState::update(const sf::Time& dt) _game->update(UpdateData{_music.fetchOffset(), dt}); } -void GameState::draw() const +void GameState::draw(sf::RenderTarget &target, sf::RenderStates states) const { - _game->draw(); + _game->draw(target, states); } -void GameState::enter() +void GameState::enter(sf::Vector2u&& render_size) { + (void)render_size; // We will need this later when I add UI to game state _game->run(); _music.openFromFile("METEOR.flac"); diff --git a/src/application/gamestate.h b/src/application/gamestate.h index c6d76f3..806a56b 100644 --- a/src/application/gamestate.h +++ b/src/application/gamestate.h @@ -17,21 +17,18 @@ public: }; - explicit GameState(sf::RenderWindow& game_window, - const std::shared_ptr& game, - Callbacks&& callbacks); + explicit GameState(const std::shared_ptr& game, Callbacks&& callbacks); virtual void input(const sf::Event& event) override; virtual void update(const sf::Time& dt) override; - virtual void draw() const override; + virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override; - virtual void enter() override; + virtual void enter(sf::Vector2u&& render_size) override; virtual void leave() override; private: Music _music; std::shared_ptr _game; - sf::RenderWindow& _game_window; std::function _onEnterGameCallback; std::function _onLeaveGameCallback; diff --git a/src/application/mainmenu.cpp b/src/application/mainmenu.cpp index 6724262..15a7617 100644 --- a/src/application/mainmenu.cpp +++ b/src/application/mainmenu.cpp @@ -2,31 +2,11 @@ #include "widgets/pushbutton.h" #include "widgets/group.h" -MainMenu::MainMenu(sf::RenderWindow& game_window, Callbacks&& callbacks, const FontHolder& font_holder) : - _buttons(std::make_shared()), - _game_window(game_window) +MainMenu::MainMenu(Callbacks&& callbacks, const FontHolder& font_holder) : + _font(font_holder.get(Fonts::Id::GUI)), + _callbacks(std::move(callbacks)), + _buttons(std::make_shared()) { - const float window_width = game_window.getSize().x; - const float window_height = game_window.getSize().y; - - auto button_start = std::make_shared("Start", font_holder.get(Fonts::Id::GUI), 48); - button_start->setRect(sf::FloatRect(window_width / 3., window_height / 7., window_width / 3., window_height / 7.)); - button_start->setCallback(callbacks.onAppendGameState); - - auto button_editor = std::make_shared("Editor", font_holder.get(Fonts::Id::GUI), 48); - button_editor->setRect(sf::FloatRect(window_width / 3., window_height / 7. * 3, window_width / 3., window_height / 7.)); - button_editor->setCallback(callbacks.onAppendEditorState); - - auto button_exit = std::make_shared("Exit", font_holder.get(Fonts::Id::GUI), 48); - button_exit->setRect(sf::FloatRect(window_width / 3., window_height / 7. * 5, window_width / 3., window_height / 7.)); - button_exit->setCallback([&]() - { - _game_window.close(); - }); - - _buttons->addChild(button_start); - _buttons->addChild(button_editor); - _buttons->addChild(button_exit); } void MainMenu::input(const sf::Event& event) @@ -39,13 +19,27 @@ void MainMenu::update(const sf::Time& dt) _buttons->update(dt); } -void MainMenu::draw() const +void MainMenu::draw(sf::RenderTarget &target, sf::RenderStates states) const { - _game_window.draw(*_buttons); + target.draw(*_buttons, states); } -void MainMenu::enter() +void MainMenu::enter(sf::Vector2u&& render_size) { + const float window_width = render_size.x; + const float window_height = render_size.y; + + auto button_start = std::make_shared("Start", _font, 48); + button_start->setRect(sf::FloatRect(window_width / 3., window_height / 7., window_width / 3., window_height / 7.)); + button_start->setCallback(_callbacks.onAppendGameState); + + auto button_editor = std::make_shared("Editor", _font, 48); + button_editor->setRect(sf::FloatRect(window_width / 3., window_height / 7. * 3, window_width / 3., window_height / 7.)); + button_editor->setCallback(_callbacks.onAppendEditorState); + + _buttons->addChild(button_start); + _buttons->addChild(button_editor); + _buttons->setVisibility(); } diff --git a/src/application/mainmenu.h b/src/application/mainmenu.h index ce75467..a792df5 100644 --- a/src/application/mainmenu.h +++ b/src/application/mainmenu.h @@ -16,16 +16,18 @@ public: std::function onAppendEditorState; }; - explicit MainMenu(sf::RenderWindow& game_window, Callbacks&& callbacks, const FontHolder &font_holder); + explicit MainMenu(Callbacks&& callbacks, const FontHolder &font_holder); virtual void input(const sf::Event& event) override; virtual void update(const sf::Time& dt) override; - virtual void draw() const override; + virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override; - virtual void enter() override; + virtual void enter(sf::Vector2u&& render_size) override; virtual void leave() override; private: + const std::shared_ptr _font; + const Callbacks _callbacks; + std::shared_ptr _buttons; - sf::RenderWindow& _game_window; };