diff --git a/src/application/src/editorstate.cpp b/src/application/src/editorstate.cpp index e634c4a..b21635e 100644 --- a/src/application/src/editorstate.cpp +++ b/src/application/src/editorstate.cpp @@ -187,4 +187,5 @@ void EditorState::leave() { _group.reset(); _bpm_calculator.reset(); + _music.reset(); } diff --git a/src/application/src/gamestate.cpp b/src/application/src/gamestate.cpp index 0ee3808..6d515ca 100644 --- a/src/application/src/gamestate.cpp +++ b/src/application/src/gamestate.cpp @@ -9,7 +9,6 @@ GameState::GameState(const std::shared_ptr& core_factory, cons _game(game), _onLeaveGameCallback(callbacks.onLeaveGame) { - _music = _core_factory->getMusic(); } void GameState::input(const kku::SystemEvent& event) @@ -24,10 +23,14 @@ void GameState::input(const kku::SystemEvent& event) if (view == kku::SystemEvent::Key::Code::Space) _music->isPlaying() ? _music->pause() : _music->play(); if (view == kku::SystemEvent::Key::Code::Escape) + { _onLeaveGameCallback(); + return; + } } - _game->input(kku::GameEvent{_music->fetchOffset(), event}); + if (_music->isPlaying()) + _game->input(kku::GameEvent{_music->fetchOffset(), event}); } void GameState::update(const kku::microsec& dt) @@ -44,6 +47,7 @@ void GameState::enter() { _game->run(); + _music = _core_factory->getMusic(); _music->open("resources/METEOR.flac"); _music->setVolume(10); _music->play(); @@ -51,5 +55,5 @@ void GameState::enter() void GameState::leave() { - _music->stop(); + _music.reset(); } diff --git a/src/modes/classicmode/classicfactory.cpp b/src/modes/classicmode/classicfactory.cpp index 5921ebe..44af705 100644 --- a/src/modes/classicmode/classicfactory.cpp +++ b/src/modes/classicmode/classicfactory.cpp @@ -1,6 +1,7 @@ #include "classicmode/classicfactory.h" #include "graphics/classicscenegraphicsmanager.h" +#include "graphics/classictimelinegraphicsmanager.h" #include "graphics/classicgraphicsfactory.h" #include "core/timeline.h" @@ -37,6 +38,7 @@ std::unique_ptr classic::getEditor(const std::shared_ptr>(); std::vector> graphics_managers; graphics_managers.emplace_back(std::make_shared(timeline, factory, visibility_offset)); + graphics_managers.emplace_back(std::make_shared(timeline, factory, visibility_offset * 2)); const auto context = std::make_shared(selection_manager, std::move(graphics_managers)); diff --git a/src/modes/classicmode/graphics/animations/classicflyinganimationscenario.cpp b/src/modes/classicmode/graphics/animations/classicflyinganimationscenario.cpp index 4640578..0413986 100644 --- a/src/modes/classicmode/graphics/animations/classicflyinganimationscenario.cpp +++ b/src/modes/classicmode/graphics/animations/classicflyinganimationscenario.cpp @@ -9,7 +9,7 @@ void ClassicFlyingAnimationScenario::launch(const std::shared_ptrsetTrailColor(_sprite->getColor()); } float ClassicFlyingAnimationScenario::getPoint(const kku::Point& point, float perc) const @@ -35,8 +35,3 @@ bool ClassicFlyingAnimationScenario::isDone() const { return false; } - -void ClassicFlyingAnimationScenario::refillColor() const -{ - _sprite->setTrailColor(_sprite->getColor()); -} diff --git a/src/modes/classicmode/graphics/animations/classicflyinganimationscenario.h b/src/modes/classicmode/graphics/animations/classicflyinganimationscenario.h index 7ebdb2a..e001159 100644 --- a/src/modes/classicmode/graphics/animations/classicflyinganimationscenario.h +++ b/src/modes/classicmode/graphics/animations/classicflyinganimationscenario.h @@ -12,7 +12,5 @@ public: private: float getPoint(const kku::Point& position, float perc) const; - void refillColor() const; - float _percentage; }; diff --git a/src/modes/classicmode/graphics/classictimelinegraphicsmanager.cpp b/src/modes/classicmode/graphics/classictimelinegraphicsmanager.cpp new file mode 100644 index 0000000..f59e8dd --- /dev/null +++ b/src/modes/classicmode/graphics/classictimelinegraphicsmanager.cpp @@ -0,0 +1,165 @@ +#include "classictimelinegraphicsmanager.h" +#include "game/classicarrownote.h" + +#include + +ClassicTimelineGraphicsManager::ClassicTimelineGraphicsManager(const std::shared_ptr>& timeline, + const std::shared_ptr& factory, + const kku::microsec& visibility_offset) : + ClassicGraphicsManager(visibility_offset), + _sprite_container({Type::UP, Type::DOWN, + Type::LEFT, Type::RIGHT}, + factory), + _factory(factory), + _timeline(timeline) +{ + _timeline->expire(_first); + _timeline->expire(_last); +} + +void ClassicTimelineGraphicsManager::input(kku::GameEvent&& input) +{ + if (nothingToDraw()) + return; + + for (auto it = _first; it != _last; ++it) + { + (*it)->input(std::move(input)); + } +} + +void ClassicTimelineGraphicsManager::display() const +{ + if (nothingToDraw()) + return; + + for (auto it = _first; it != _last; ++it) + { + const auto note = *it; + if (note->getState() != ClassicNote::State::DEAD) + note->draw(shared_from_this()); + } +} + +void ClassicTimelineGraphicsManager::update(const kku::microsec &offset) +{ + fetchLastNote(offset); + fetchFirstNote(offset); + + updateVisibleNotes(offset); +} + +void ClassicTimelineGraphicsManager::update(const kku::microsec& offset, ClassicArrowNote* note) +{ + bool hasGraphics = (note->getElements()[0].sprite != nullptr); + + if (isVisiblyClose(note, offset) && !hasGraphics) + { + std::cout << note->getId() << ": set graphics!\n" << std::flush; + } + else + { + std::cout << note->getId() << ": remove graphics!\n" << std::flush; + } +} + +void ClassicTimelineGraphicsManager::draw(const std::vector& elements) const +{ + for (std::size_t i = 0; i < elements.size(); ++i) + { + const auto& sprite = elements[i].sprite; + + if (i >= 1) + { + //const auto& neighbor_sprite = elements[i - 1].sprite; + //const auto c1 = neighbor_sprite->trailPosition(); + //const auto c2 = sprite->trailPosition(); + //_render_target->draw(makeLine(c1, c2)); + } + + sprite->display(); + } +} + +bool ClassicTimelineGraphicsManager::nothingToDraw() const noexcept +{ + return _timeline->isExpired(_first) + || _timeline->isExpired(_last); +} + +bool ClassicTimelineGraphicsManager::isVisiblyClose(const ClassicNote * const note, const kku::microsec& music_offset) const noexcept +{ + return (note->getPerfectOffset() - _visibility_offset) <= music_offset; +} + +void ClassicTimelineGraphicsManager::fetchFirstNote(const kku::microsec& offset) +{ + if (nothingToDraw()) + return; + + if (offset < (*_first)->getPerfectOffset()) + { + Iterator note_iterator = _first; + while (note_iterator != _timeline->begin() && isVisiblyClose(*note_iterator, offset)) + { + --note_iterator; + } + + _first = note_iterator; + + auto note = *_first; + const auto state = note->getState(); + if (state != ClassicNote::State::FLYING + && state != ClassicNote::State::DYING + && state != ClassicNote::State::INITIAL + && offset <= note->getPerfectOffset()) + { + note->setState(ClassicNote::State::INITIAL); + } + } + else + { + Iterator note_iterator = _first; + while (note_iterator != _last) + { + auto note = *note_iterator; + if (note->getState() == ClassicNote::State::DEAD) + { + // note->removeGraphics(this); + ++_first; + } + + ++note_iterator; + } + } +} + +void ClassicTimelineGraphicsManager::fetchLastNote(const kku::microsec& offset) +{ + Iterator note_iterator = _timeline->getTopNote(); + while (!_timeline->isExpired(note_iterator) && isVisiblyClose(*note_iterator, offset)) + { + if (nothingToDraw()) + _first = note_iterator; + + auto note = *note_iterator; + const auto state = note->getState(); + if (state != ClassicNote::State::FLYING + && state != ClassicNote::State::DYING + && state != ClassicNote::State::INITIAL + && offset <= note->getPerfectOffset()) + { + note->setState(ClassicNote::State::INITIAL); + } + + ++note_iterator; + } + + _last = note_iterator; +} + +void ClassicTimelineGraphicsManager::updateVisibleNotes(const kku::microsec& offset) +{ + for (auto it = _first; it != _last; ++it) + (*it)->update(offset); +} diff --git a/src/modes/classicmode/graphics/classictimelinegraphicsmanager.h b/src/modes/classicmode/graphics/classictimelinegraphicsmanager.h new file mode 100644 index 0000000..5869b5c --- /dev/null +++ b/src/modes/classicmode/graphics/classictimelinegraphicsmanager.h @@ -0,0 +1,44 @@ +#pragma once + +#include "classicmode/classicnote.h" +#include "graphics/classicgraphicsmanager.h" +#include "graphics/classicgraphicsfactory.h" +#include "core/timeline.h" +#include "core/spritecontainer.h" + +#include "game/arrowelement.h" + +#include "graphics/animations/classicflyinganimationscenario.h" +#include "graphics/animations/classicdyinganimationscenario.h" + +class ClassicTimelineGraphicsManager : public ClassicGraphicsManager +{ +public: + explicit ClassicTimelineGraphicsManager(const std::shared_ptr>& timeline, + const std::shared_ptr& factory, + const kku::microsec& visibility_offset); + + virtual void input(kku::GameEvent&& input) override; + virtual void display() const override; + virtual void update(const kku::microsec& offset) override; + + virtual void update(const kku::microsec& offset, ClassicArrowNote* note) override; + virtual void draw(const std::vector& elements) const override; + +protected: + kku::SpriteContainer _sprite_container; + const std::shared_ptr _factory; + + typedef typename std::set::const_iterator Iterator; + + Iterator _first; + Iterator _last; + + const std::shared_ptr> _timeline; + + inline bool nothingToDraw() const noexcept; + inline bool isVisiblyClose(const ClassicNote * const note, const kku::microsec& music_offset) const noexcept; + void fetchFirstNote(const kku::microsec& offset); + void fetchLastNote(const kku::microsec& offset); + void updateVisibleNotes(const kku::microsec& offset); +};