diff --git a/core/shared/core/timeline.h b/core/shared/core/timeline.h index eec87d1..79af060 100644 --- a/core/shared/core/timeline.h +++ b/core/shared/core/timeline.h @@ -118,6 +118,15 @@ public: return _active_note; } + inline Iterator getNoteBy(const microsec& music_offset) noexcept + { + return std::find_if(_timeline.begin(), _timeline.end(), + [music_offset](const auto& note) + { + return note->offset() == music_offset; + }); + } + inline bool isExpired(const Iterator& iterator) const { return iterator == _timeline.end(); diff --git a/modes/classicmode/editor/classiceditor.cpp b/modes/classicmode/editor/classiceditor.cpp index f4b4b8a..8391e25 100644 --- a/modes/classicmode/editor/classiceditor.cpp +++ b/modes/classicmode/editor/classiceditor.cpp @@ -1,21 +1,65 @@ #include "classiceditor.h" -ClassicEditor::ClassicEditor(std::shared_ptr&& manager) +ClassicEditor::ClassicEditor(std::shared_ptr&& manager) : + _graphics_manager(manager), + _selected_type(Type::UP) { - + _context.graphics_manager = _graphics_manager; } void ClassicEditor::input(PlayerInput&& inputdata) { + const auto& event = inputdata.event; + const auto offset = _music.fetchOffset(); + switch (event.type) + { + + default: + break; + + case sf::Event::MouseButtonPressed: + { + const auto note = _timeline.getNoteBy(offset); + if (_timeline.isExpired(note)) + { + NoteInitializer init; + init.context = &_context; + init.intervals = {}; + init.perfect_offset = offset; + + ElementInitializer elem_init; + elem_init.type = _selected_type; + elem_init.coordinates = Coordinates{ event.mouseButton.x, event.mouseButton.y }; + elem_init.falling_curve_interpolation = {}; + + MockArrowNoteInitializer mock_init; + mock_init.elements = {elem_init}; + mock_init.initializer = init; + + _timeline.insertNote(new MockClassicNote(std::move(mock_init))); + } + break; + } + + } } void ClassicEditor::update(const sf::Time& dt) { + (void)dt; + // TODO!!! + _timeline.update(_music.fetchOffset()); + _timeline.fetchVisibleNotes(); } void ClassicEditor::draw() const { - + _timeline.drawVisibleNotes(); +} + +void ClassicEditor::selectNoteType(Type type) noexcept +{ + _selected_type = type; } diff --git a/modes/classicmode/editor/classiceditor.h b/modes/classicmode/editor/classiceditor.h index e7f96df..f41bcb2 100644 --- a/modes/classicmode/editor/classiceditor.h +++ b/modes/classicmode/editor/classiceditor.h @@ -1,9 +1,12 @@ #pragma once #include + #include "core/editor.h" -#include "tools/music.h" #include "core/timeline.h" +#include "tools/music.h" + +#include "mockclassicnote.h" class ClassicGraphicsManager; @@ -16,9 +19,14 @@ public: virtual void update(const sf::Time& dt) override; virtual void draw() const override; + void selectNoteType(Type type) noexcept; + private: Music _music; + Context _context; std::shared_ptr _graphics_manager; - Timeline _timeline; + Timeline _timeline; + + Type _selected_type; }; diff --git a/modes/classicmode/editor/mockclassicnote.cpp b/modes/classicmode/editor/mockclassicnote.cpp index 42d0b22..8c5be43 100644 --- a/modes/classicmode/editor/mockclassicnote.cpp +++ b/modes/classicmode/editor/mockclassicnote.cpp @@ -1,7 +1,93 @@ #include "mockclassicnote.h" +#include "graphics/classicgraphicsmanager.h" + +// Replace with interface by dependency injection +#include "graphics/classicflyinganimationscenario.h" +#include "graphics/classicdyinganimationscenario.h" +// + +// A LOT OF CODE DUPLICATES game/arrowclassicnote, DO SOMETHING D:< MockClassicNote::MockClassicNote(MockArrowNoteInitializer&& init) : - Note(init.initializer) + Note(init.initializer.perfect_offset), + _state(State::NONE), + _context(init.initializer.context) { + _elements.resize(init.elements.size()); + for (std::size_t i = 0; i < _elements.size(); ++i) + { + _elements[i].coordinates = init.elements[i].coordinates; + _elements[i].type = init.elements[i].type; + + // Animations will be injected into note. + _elements[i].animations[State::NONE] = nullptr; + _elements[i].animations[State::FLYING] = std::make_shared(); + _elements[i].animations[State::DYING] = std::make_shared(); + _elements[i].animations[State::DEAD] = nullptr; + } +} + +bool MockClassicNote::isActive() const +{ + return _state != State::DEAD + && _state != State::NONE; +} + +bool MockClassicNote::isInGame() const +{ + return _state == State::FLYING + || _state == State::DYING; +} + +bool MockClassicNote::shouldRemove() const +{ + return _state == State::DEAD; +} + +void MockClassicNote::putToGame(const microsec &music_offset) +{ + _state = State::FLYING; + + for (auto& element : _elements) + { + element.sprite = _context->graphics_manager->getSprite(element.type); + element.sprite->setCoordinates(element.coordinates); + element.sprite->setTrailCoordinates(Coordinates(0.f, 9.f)); + element.animations[_state]->launch(element.sprite, music_offset, offset()); + } +} + +void MockClassicNote::update(const microsec &music_offset) +{ + switch (_state) + { + default: return; + break; + + case State::FLYING: + if (music_offset > offset()) + _state = State::DYING; + break; + + case State::DYING: + if (_elements[0].animations[_state]->isDone()) + _state = State::DEAD; + break; + } + + for (auto& element : _elements) + if (element.animations[_state]) + element.animations[_state]->update(music_offset); +} + +void MockClassicNote::draw() const +{ + for (std::size_t i = 0; i < _elements.size(); ++i) + { + if (i >= 1) + _context->graphics_manager->drawLine(_elements[i-1].sprite->trailCoordinates(), _elements[i].sprite->trailCoordinates()); + + _context->graphics_manager->draw(_elements[i].sprite); + } } diff --git a/modes/classicmode/editor/mockclassicnote.h b/modes/classicmode/editor/mockclassicnote.h index b610952..10f5226 100644 --- a/modes/classicmode/editor/mockclassicnote.h +++ b/modes/classicmode/editor/mockclassicnote.h @@ -1,8 +1,14 @@ #pragma once +#include +#include + #include "core/note.h" #include "initializers/mockarrownoteinitializer.h" +class ClassicSprite; +class ClassicAnimationScenario; + class MockClassicNote : public Note { public: @@ -17,13 +23,29 @@ public: }; explicit MockClassicNote(MockArrowNoteInitializer&& init); - virtual ~MockClassicNote() = default; + virtual ~MockClassicNote() override = default; virtual bool isActive() const override final; virtual bool isInGame() const override final; virtual bool shouldRemove() const override final; - virtual void putToGame(const microsec &music_offset) override = 0; - virtual void update(const microsec &music_offset) override = 0; - virtual void draw() const override = 0; + virtual void putToGame(const microsec &music_offset) override final; + virtual void update(const microsec &music_offset) override final; + virtual void draw() const override final; + +private: + struct MockElement + { + std::shared_ptr sprite; + std::array, 4> animations; + Type type = Type::NONE; + + Coordinates coordinates; + std::vector falling_curve_interpolation; + }; + + std::vector _elements; + + State _state; + const Context *_context; }; diff --git a/modes/classicmode/game/classicarrownote.cpp b/modes/classicmode/game/classicarrownote.cpp index d6b06b4..5c0f728 100644 --- a/modes/classicmode/game/classicarrownote.cpp +++ b/modes/classicmode/game/classicarrownote.cpp @@ -15,9 +15,9 @@ ClassicArrowNote::ClassicArrowNote(ArrowNoteInitializer&& init) : for (std::size_t i = 0; i < _elements.size(); ++i) { - _elements[i].keys = init.elements[i].element.keys; + _elements[i].keys = init.elements[i].keys; _elements[i].coordinates = init.elements[i].element.coordinates; - _elements[i].type = init.elements[i].type; + _elements[i].type = init.elements[i].element.type; // Animations will be injected into note. _elements[i].animations[State::NONE] = nullptr; @@ -36,7 +36,7 @@ void ClassicArrowNote::putToGame(const microsec &music_offset) { element.sprite = _context->graphics_manager->getSprite(element.type); element.sprite->setCoordinates(element.coordinates); - element.sprite->setTrailCoordinates({0., 9.}); + element.sprite->setTrailCoordinates(Coordinates( 0.f, 9.f )); element.animations[_state]->launch(element.sprite, music_offset, offset()); } } diff --git a/modes/classicmode/game/classicmapcreator.cpp b/modes/classicmode/game/classicmapcreator.cpp index ea85ec6..dbdec05 100644 --- a/modes/classicmode/game/classicmapcreator.cpp +++ b/modes/classicmode/game/classicmapcreator.cpp @@ -38,16 +38,16 @@ auto classic::createBeatmap(const std::string& filepath, const Context &context) init.hold = false; init.initializer.context = &context; - element.element.coordinates = {x, 390.}; + element.element.coordinates = Coordinates(x, 390.f); element.element.falling_curve_interpolation = {}; - element.element.keys = {sf::Keyboard::W, sf::Keyboard::Up}; - element.type = Type::UP; + element.keys = {sf::Keyboard::W, sf::Keyboard::Up}; + element.element.type = Type::UP; if (counter == 0) { init.hold = true; - element.element.keys = {sf::Keyboard::D, sf::Keyboard::Right}; - element.type = Type::RIGHT; + element.keys = {sf::Keyboard::D, sf::Keyboard::Right}; + element.element.type = Type::RIGHT; } --counter; diff --git a/modes/classicmode/game/classicnote.h b/modes/classicmode/game/classicnote.h index dac3d80..a252b9b 100644 --- a/modes/classicmode/game/classicnote.h +++ b/modes/classicmode/game/classicnote.h @@ -30,7 +30,7 @@ public: }; explicit ClassicNote(NoteInitializer&& init); - virtual ~ClassicNote() = default; + virtual ~ClassicNote() override = default; virtual bool isActive() const override final; virtual bool isInGame() const override final; diff --git a/modes/classicmode/game/initializers/arrowelementinitializer.h b/modes/classicmode/game/initializers/arrowelementinitializer.h index f8d2f84..8930f64 100644 --- a/modes/classicmode/game/initializers/arrowelementinitializer.h +++ b/modes/classicmode/game/initializers/arrowelementinitializer.h @@ -1,12 +1,9 @@ #pragma once #include "classicmode/elementinitializer.h" -#include "classicmode/classicactions.h" struct ArrowElementInitializer { ElementInitializer element; - - Type type = Type::NONE; std::array keys; }; diff --git a/modes/classicmode/graphics/classicdyinganimationscenario.cpp b/modes/classicmode/graphics/classicdyinganimationscenario.cpp index df20f32..8e8a7f9 100644 --- a/modes/classicmode/graphics/classicdyinganimationscenario.cpp +++ b/modes/classicmode/graphics/classicdyinganimationscenario.cpp @@ -9,7 +9,7 @@ void ClassicDyingAnimationScenario::launch(const std::shared_ptr _sprite->setColor(sf::Color(140, 140, 140)); _sprite->setTrailColor(sf::Color(0, 0, 0, 0)); - _sprite->setTrailCoordinates({0, 0}); + _sprite->setTrailCoordinates(Coordinates(0, 0)); } void ClassicDyingAnimationScenario::update(const microsec& music_offset) diff --git a/modes/classicmode/graphics/classicflyinganimationscenario.cpp b/modes/classicmode/graphics/classicflyinganimationscenario.cpp index 9a97e48..95e257e 100644 --- a/modes/classicmode/graphics/classicflyinganimationscenario.cpp +++ b/modes/classicmode/graphics/classicflyinganimationscenario.cpp @@ -28,7 +28,7 @@ void ClassicFlyingAnimationScenario::update(const microsec& music_offset) float xb = getPoint( crd.x + 90. , crd.x , i ); float yb = getPoint( crd.y - 150. , crd.y , i ); - _sprite->setTrailCoordinates({getPoint( xa , xb , i ), getPoint( ya , yb , i )}); + _sprite->setTrailCoordinates(Coordinates(getPoint( xa , xb , i ), getPoint( ya , yb , i ))); bool pastPerfectScore = (i >= 1); diff --git a/modes/classicmode/graphics/classicsprite.cpp b/modes/classicmode/graphics/classicsprite.cpp index c361bc3..29cf008 100644 --- a/modes/classicmode/graphics/classicsprite.cpp +++ b/modes/classicmode/graphics/classicsprite.cpp @@ -34,12 +34,12 @@ void ClassicSprite::setTrailCoordinates(const Coordinates &coordinates) Coordinates ClassicSprite::coordinates() const { - return {_shape.getPosition().x, _shape.getPosition().y}; + return Coordinates(_shape.getPosition().x, _shape.getPosition().y); } Coordinates ClassicSprite::trailCoordinates() const { - return {_trail.getPosition().x, _trail.getPosition().y}; + return Coordinates(_trail.getPosition().x, _trail.getPosition().y); } void ClassicSprite::setColor(const sf::Color& color) diff --git a/modes/classicmode/include/classicmode/context.h b/modes/classicmode/include/classicmode/context.h new file mode 100644 index 0000000..8d977a9 --- /dev/null +++ b/modes/classicmode/include/classicmode/context.h @@ -0,0 +1,12 @@ +#pragma once + +#include + +class ClassicGraphicsManager; +class HoldManager; + +struct Context +{ + std::shared_ptr graphics_manager; + std::shared_ptr hold_manager; +}; diff --git a/modes/classicmode/include/classicmode/elementinitializer.h b/modes/classicmode/include/classicmode/elementinitializer.h index 543b4e5..f64b897 100644 --- a/modes/classicmode/include/classicmode/elementinitializer.h +++ b/modes/classicmode/include/classicmode/elementinitializer.h @@ -1,5 +1,6 @@ #pragma once +#include "classicactions.h" #include "core/inputtype.h" #include "tools/mathutils.h" @@ -7,6 +8,7 @@ struct ElementInitializer { + Type type = Type::NONE; Coordinates coordinates; std::vector falling_curve_interpolation; }; diff --git a/src/application/application.cpp b/src/application/application.cpp index 4bbb681..36537d1 100644 --- a/src/application/application.cpp +++ b/src/application/application.cpp @@ -31,7 +31,7 @@ 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::init(_game_window), GameState::Callbacks()); + const auto game_state = std::make_shared(_game_window, classic::initGame(_game_window), GameState::Callbacks()); const auto editor = std::make_shared(_game_window, std::move(editor_callbacks), std::make_unique(), _font_holder); _states[GUIState::Tag::MAIN_MENU] = main_menu; diff --git a/src/application/editorstate.cpp b/src/application/editorstate.cpp index 984c8c7..ab0b899 100644 --- a/src/application/editorstate.cpp +++ b/src/application/editorstate.cpp @@ -99,7 +99,7 @@ void EditorState::enter() menu_bar->setVisibility(true); - auto editor_widget = std::make_unique(_edito) + //auto editor_widget = std::make_unique(_edito) _group = std::make_shared(); _group->addChild(menu_bar); diff --git a/tools/shared/tools/mathutils.h b/tools/shared/tools/mathutils.h index ecffe7e..b0476f8 100644 --- a/tools/shared/tools/mathutils.h +++ b/tools/shared/tools/mathutils.h @@ -4,17 +4,29 @@ using microsec = long long; struct Coordinates { - float x = 0.; - float y = 0.; + float x; + float y; + + constexpr inline explicit Coordinates() noexcept : + x(0.), y(0.) + {} + + constexpr inline explicit Coordinates(int x, int y) noexcept : + x(x), y(y) + {} + + constexpr inline explicit Coordinates(float x, float y) noexcept : + x(x), y(y) + {} constexpr inline Coordinates operator+(const Coordinates& right) const noexcept { - return {right.x + x, right.y + y}; + return Coordinates{right.x + x, right.y + y}; } constexpr inline Coordinates operator-(const Coordinates& right) const noexcept { - return {right.x - x, right.y - y}; + return Coordinates{right.x - x, right.y - y}; } inline void moveBy(float x, float y) noexcept