Implement basic ClassicNote
This commit is contained in:
		
							parent
							
								
									3c733cd490
								
							
						
					
					
						commit
						f66951bcec
					
				| @ -8,6 +8,7 @@ | |||||||
| #include "debughelper.h" | #include "debughelper.h" | ||||||
| #include "timeline.h" | #include "timeline.h" | ||||||
| #include "note.h" | #include "note.h" | ||||||
|  | #include "game.h" | ||||||
| 
 | 
 | ||||||
| class Application | class Application | ||||||
| { | { | ||||||
| @ -28,9 +29,9 @@ private: | |||||||
|     std::unique_ptr<Timeline> _timeline; |     std::unique_ptr<Timeline> _timeline; | ||||||
|     DebugHelper _debug; |     DebugHelper _debug; | ||||||
| 
 | 
 | ||||||
|  |     std::unique_ptr<Game> _game; | ||||||
|  | 
 | ||||||
|     void startGameLoop(); |     void startGameLoop(); | ||||||
|     void onKeyPressed(const sf::Keyboard::Key& key); |  | ||||||
|     void onTap(const Note::Arrow& arrow); |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif // APPLICATION_H
 | #endif // APPLICATION_H
 | ||||||
|  | |||||||
							
								
								
									
										17
									
								
								include/note.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								include/note.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <vector> | ||||||
|  | #include <SFML/System/Clock.hpp> | ||||||
|  | 
 | ||||||
|  | using microsec = sf::Int64; | ||||||
|  | 
 | ||||||
|  | class Note | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     explicit Note(microsec perfect_offset) : | ||||||
|  |         _perfect_offset(perfect_offset) {} | ||||||
|  |     virtual ~Note() = 0; | ||||||
|  | 
 | ||||||
|  | protected: | ||||||
|  |     microsec _perfect_offset; | ||||||
|  | }; | ||||||
| @ -1,31 +0,0 @@ | |||||||
| #ifndef NOTEGRAPHICSENTITY_H |  | ||||||
| #define NOTEGRAPHICSENTITY_H |  | ||||||
| 
 |  | ||||||
| #include <SFML/Graphics/Drawable.hpp> |  | ||||||
| #include <SFML/Graphics/Transformable.hpp> |  | ||||||
| 
 |  | ||||||
| class NoteGraphicsEntity : public sf::Drawable, public sf::Transformable |  | ||||||
| { |  | ||||||
| public: |  | ||||||
|     explicit NoteGraphicsEntity(); |  | ||||||
|     virtual ~NoteGraphicsEntity() = 0; |  | ||||||
| 
 |  | ||||||
|     virtual void update() = 0; |  | ||||||
| 
 |  | ||||||
|     virtual void attach() noexcept final; |  | ||||||
|     virtual void detach() noexcept final; |  | ||||||
| 
 |  | ||||||
|     virtual void onKeyPressed() = 0; |  | ||||||
|     virtual void onKeyReleased() = 0; |  | ||||||
| 
 |  | ||||||
|     virtual void show() = 0; |  | ||||||
|     virtual void killAsExpired() = 0; |  | ||||||
|     virtual void reset() = 0; |  | ||||||
| 
 |  | ||||||
|     virtual bool isActive() const = 0; |  | ||||||
| 
 |  | ||||||
| protected: |  | ||||||
|     bool _attached; |  | ||||||
| }; |  | ||||||
| 
 |  | ||||||
| #endif |  | ||||||
| @ -14,9 +14,9 @@ template<typename GRADE, typename = std::enable_if_t<std::is_enum<GRADE>::value> | |||||||
| class PrecisionEvaluator | class PrecisionEvaluator | ||||||
| { | { | ||||||
| public: | public: | ||||||
|     PrecisionEvaluator(std::vector<microsec>&& intervals, microsec offset) : |     PrecisionEvaluator(const std::vector<microsec>& intervals, microsec offset) : | ||||||
|         _offset(offset), |         _offset(offset), | ||||||
|         _intervals(std::move(intervals)) |         _intervals(intervals) | ||||||
|     { |     { | ||||||
|         microsec&& handling_offset = std::accumulate(intervals.begin(), intervals.end(), 0); |         microsec&& handling_offset = std::accumulate(intervals.begin(), intervals.end(), 0); | ||||||
|         _start_handling_offset = _offset - handling_offset; |         _start_handling_offset = _offset - handling_offset; | ||||||
| @ -41,7 +41,7 @@ public: | |||||||
|         std::size_t raw_grade; |         std::size_t raw_grade; | ||||||
|         for (raw_grade = 0; raw_grade < _intervals.size(); ++raw_grade) |         for (raw_grade = 0; raw_grade < _intervals.size(); ++raw_grade) | ||||||
|         { |         { | ||||||
|             if (shift_from_perfect <= _intervals[raw_grade]) |             if (shift_from_perfect <= _intervals.at(raw_grade)) | ||||||
|                 break; |                 break; | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
| @ -60,7 +60,7 @@ private: | |||||||
|      * V0 is PERFECT SCORE and the last V represents the worst |      * V0 is PERFECT SCORE and the last V represents the worst | ||||||
|      * grades which is death of note by expiration */ |      * grades which is death of note by expiration */ | ||||||
| 
 | 
 | ||||||
|     std::vector<microsec> _intervals; |     const std::vector<microsec>& _intervals; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif // PRECISIONEVALUATOR_H
 | #endif // PRECISIONEVALUATOR_H
 | ||||||
|  | |||||||
							
								
								
									
										6
									
								
								include/sprite.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								include/sprite.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,6 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | class Sprite | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | }; | ||||||
| @ -2,56 +2,18 @@ | |||||||
| #define TIMELINE_H | #define TIMELINE_H | ||||||
| 
 | 
 | ||||||
| #include <SFML/Config.hpp> | #include <SFML/Config.hpp> | ||||||
| #include <SFML/Graphics/RectangleShape.hpp> |  | ||||||
| 
 |  | ||||||
| #include <vector> |  | ||||||
| #include <memory> | #include <memory> | ||||||
| 
 | 
 | ||||||
| using microsec = sf::Int64; | using microsec = sf::Int64; | ||||||
| class Note; |  | ||||||
| class TimelineViewManager; |  | ||||||
| 
 | 
 | ||||||
| class Timeline : public sf::Drawable // Probably it's bad
 | class Timeline | ||||||
| { | { | ||||||
| public: | public: | ||||||
|     explicit Timeline(std::unique_ptr<TimelineViewManager> view_manager); |     virtual ~Timeline() = default; | ||||||
|     virtual ~Timeline(); |  | ||||||
| 
 | 
 | ||||||
|     virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override; |     virtual void update(const microsec& music_offset) = 0; | ||||||
| 
 |     virtual void init() = 0; | ||||||
|     void update(const microsec& music_offset); |     virtual void clear() = 0; | ||||||
|     Note *fetchActiveNote(const microsec &music_offset) noexcept; |  | ||||||
| 
 |  | ||||||
|  /* void init();  */ |  | ||||||
|     void clear(); |  | ||||||
| 
 |  | ||||||
| private: |  | ||||||
|     std::vector<Note*> _timeline; |  | ||||||
|     std::vector<Note*>::const_iterator _top_note; |  | ||||||
|     Note* _active_note; |  | ||||||
| 
 |  | ||||||
|     std::vector<Note*>::const_iterator _last_visible_note; |  | ||||||
|     microsec _visibility_offset; |  | ||||||
| 
 |  | ||||||
|     std::unique_ptr<TimelineViewManager> _view_manager; |  | ||||||
| 
 |  | ||||||
|     void checkCurrentActiveNote(const microsec &music_offset); |  | ||||||
|     void checkForNextActiveNote(const microsec &music_offset); |  | ||||||
|     void prepareNotesToDraw(const microsec &music_offset); |  | ||||||
| 
 |  | ||||||
|     /* Difference between top and active note is that
 |  | ||||||
|      * top note is the note handling input right now |  | ||||||
|      * OR it's the closest note from current music offset |  | ||||||
|      * position, not necessarily active. A note stops being top only |  | ||||||
|      * after dying or being tapped by player, even if it's already |  | ||||||
|      * past her perfect offset. |  | ||||||
|      * |  | ||||||
|      * Meanwhile active note is the note which is currently handling |  | ||||||
|      *     player input for grade. |  | ||||||
|      * |  | ||||||
|      * An active note is always top note but a top note |  | ||||||
|      *    is not always active note. |  | ||||||
|      *                                         */ |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif // TIMELINE_H
 | #endif // TIMELINE_H
 | ||||||
|  | |||||||
| @ -6,8 +6,7 @@ class Note; | |||||||
| class TimelineViewManager | class TimelineViewManager | ||||||
| { | { | ||||||
| public: | public: | ||||||
|     explicit TimelineViewManager(); |     virtual ~TimelineViewManager() = default; | ||||||
|     virtual ~TimelineViewManager() = 0; |  | ||||||
| 
 | 
 | ||||||
|     virtual void initNoteGraphics(Note *note) = 0; |     virtual void initNoteGraphics(Note *note) = 0; | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -1,16 +1,15 @@ | |||||||
| #include "application.h" | #include "application.h" | ||||||
| 
 | #include "classicgame/classicgame.h" | ||||||
| #include <SFML/Graphics/Color.hpp> | #include <SFML/Graphics/Color.hpp> | ||||||
| #include <SFML/Window/Event.hpp> | #include <SFML/Window/Event.hpp> | ||||||
| #include "classicviewmanager.h" |  | ||||||
| 
 | 
 | ||||||
| const sf::Time TIME_PER_FRAME = sf::seconds(1.f / 60.f); | const sf::Time TIME_PER_FRAME = sf::seconds(1.f / 60.f); | ||||||
| 
 | 
 | ||||||
| Application::Application() : | Application::Application() : | ||||||
|     _game_window({1280, 720}, "Test"), |     _game_window({1280, 720}, "Test"), | ||||||
|     _debug(true) |     _debug(true), | ||||||
|  |     _game(std::make_unique<ClassicGame>()) | ||||||
| { | { | ||||||
|     _timeline = std::make_unique<Timeline>(std::make_unique<ClassicViewManager>()); |  | ||||||
|     _font.loadFromFile("/usr/share/qtcreator/fonts/SourceCodePro-Regular.ttf"); |     _font.loadFromFile("/usr/share/qtcreator/fonts/SourceCodePro-Regular.ttf"); | ||||||
|     _grade.setFont(_font); |     _grade.setFont(_font); | ||||||
|     _grade.setPosition(160, 160); |     _grade.setPosition(160, 160); | ||||||
| @ -53,121 +52,17 @@ void Application::startGameLoop() | |||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| static void makeGradeString(const NoteGrade::Rating& rating, sf::Text& text) |  | ||||||
| { |  | ||||||
|     switch (rating) |  | ||||||
|     { |  | ||||||
|     case (NoteGrade::Rating::BAD): |  | ||||||
|         text.setString("BAD"); |  | ||||||
|         text.setFillColor(sf::Color(255, 255, 255, 255)); |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|     case (NoteGrade::Rating::GREAT): |  | ||||||
|         text.setString("GREAT"); |  | ||||||
|         text.setFillColor(sf::Color(255, 255, 0, 255)); |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|     case (NoteGrade::Rating::WRONG): |  | ||||||
|         text.setString("WRONG"); |  | ||||||
|         text.setFillColor(sf::Color(120, 120, 120, 255)); |  | ||||||
|         break; |  | ||||||
| 
 |  | ||||||
|     case (NoteGrade::Rating::GOOD): |  | ||||||
|         text.setString("GOOD"); |  | ||||||
|         text.setFillColor(sf::Color(255, 100, 120, 255)); |  | ||||||
|         break; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void Application::input() | void Application::input() | ||||||
| { | { | ||||||
|     sf::Event event; |     sf::Event event; | ||||||
|     while (_game_window.pollEvent(event)) |     while (_game_window.pollEvent(event)) | ||||||
|     { |     { | ||||||
|         switch (event.type) |         _game->input(event); | ||||||
|         { |  | ||||||
|         default: |  | ||||||
|             break; |  | ||||||
| 
 |  | ||||||
|         case (sf::Event::Closed): |  | ||||||
|             _game_window.close(); |  | ||||||
|             break; |  | ||||||
| 
 |  | ||||||
|         case (sf::Event::KeyPressed): |  | ||||||
|             onKeyPressed(event.key.code); |  | ||||||
|             break; |  | ||||||
|         } |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| static Note::Arrow keyToArrow(const sf::Keyboard::Key &key) |  | ||||||
| { |  | ||||||
|     switch (key) |  | ||||||
|     { |  | ||||||
|     case sf::Keyboard::A: |  | ||||||
|     case sf::Keyboard::Left: |  | ||||||
|     case sf::Keyboard::Num4: |  | ||||||
|         return Note::Arrow::LEFT; |  | ||||||
| 
 |  | ||||||
|     case sf::Keyboard::W: |  | ||||||
|     case sf::Keyboard::Up: |  | ||||||
|     case sf::Keyboard::Num8: |  | ||||||
|         return Note::Arrow::UP; |  | ||||||
| 
 |  | ||||||
|     case sf::Keyboard::D: |  | ||||||
|     case sf::Keyboard::Right: |  | ||||||
|     case sf::Keyboard::Num6: |  | ||||||
|         return Note::Arrow::RIGHT; |  | ||||||
| 
 |  | ||||||
|     case sf::Keyboard::S: |  | ||||||
|     case sf::Keyboard::Down: |  | ||||||
|     case sf::Keyboard::Num2: |  | ||||||
|         return Note::Arrow::DOWN; |  | ||||||
| 
 |  | ||||||
|     default: |  | ||||||
|         return Note::Arrow::NONE; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void Application::onKeyPressed(const sf::Keyboard::Key &key) |  | ||||||
| { |  | ||||||
|     if (key == sf::Keyboard::D) |  | ||||||
|     { |  | ||||||
|         _debug.toggle(); |  | ||||||
|         return; |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     onTap(keyToArrow(key)); |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void Application::onTap(const Note::Arrow &arrow) |  | ||||||
| { |  | ||||||
|     if (arrow == Note::Arrow::NONE) |  | ||||||
|         return; |  | ||||||
| 
 |  | ||||||
|     const auto music_offset = _music.getPlayingOffset().asMicroseconds(); |  | ||||||
|     auto note = _timeline->fetchActiveNote(music_offset); |  | ||||||
| 
 |  | ||||||
|     if (note) |  | ||||||
|     { |  | ||||||
|         auto tap_result = note->onTap(arrow, music_offset); |  | ||||||
|         makeGradeString(tap_result.rating, _grade); |  | ||||||
|         _grade.setFillColor(sf::Color(255, 255, 255, 255)); |  | ||||||
|     } |     } | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Application::update() | void Application::update() | ||||||
| { | { | ||||||
|     const auto music_offset = _music.getPlayingOffset().asMicroseconds(); |  | ||||||
| 
 |  | ||||||
|     _timeline->update(music_offset); |  | ||||||
|     _debug.update(music_offset); |  | ||||||
| 
 |  | ||||||
|     if (_grade.getFillColor().a > 0)    // TODO: Encapsulate
 |  | ||||||
|     { |  | ||||||
|         const auto alpha = _grade.getFillColor().a - 20; |  | ||||||
|         _grade.setFillColor(sf::Color(255, 255, 255, alpha < 0 ? 0 : alpha)); |  | ||||||
|     } |  | ||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,7 +1,9 @@ | |||||||
| #include "classicgame.h" | #include "classicgame.h" | ||||||
| #include "classicinputtype.h" | #include "classicinputtype.h" | ||||||
|  | #include "classictimeline.h" | ||||||
| 
 | 
 | ||||||
| ClassicGame::ClassicGame() | ClassicGame::ClassicGame() : | ||||||
|  |     _timeline(std::make_unique<ClassicTimeline>()) | ||||||
| { | { | ||||||
|     _keys_to_buttons = |     _keys_to_buttons = | ||||||
|     { |     { | ||||||
| @ -71,7 +73,8 @@ void ClassicGame::input(const sf::Event& event) | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     ClassicInputType input(timestamp, new_action); |     ClassicInputType input(timestamp, new_action); | ||||||
|     /* Here get active Note from timeline and pass the input object to it */ |     auto note = _timeline->getActiveNote(timestamp); | ||||||
|  |     note-> | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| Action ClassicGame::getActionKeyPressed(Button button) const | Action ClassicGame::getActionKeyPressed(Button button) const | ||||||
|  | |||||||
| @ -6,6 +6,8 @@ | |||||||
| #include "game.h" | #include "game.h" | ||||||
| #include "classicactions.h" | #include "classicactions.h" | ||||||
| 
 | 
 | ||||||
|  | class ClassicTimeline; | ||||||
|  | 
 | ||||||
| class ClassicGame final : public Game | class ClassicGame final : public Game | ||||||
| { | { | ||||||
| public: | public: | ||||||
| @ -25,6 +27,9 @@ private: | |||||||
| 
 | 
 | ||||||
|     Action getActionKeyPressed(Button button) const; |     Action getActionKeyPressed(Button button) const; | ||||||
|     Action getActionKeyReleased(Button button) const; |     Action getActionKeyReleased(Button button) const; | ||||||
|  | 
 | ||||||
|  |     std::unique_ptr<ClassicTimeline> _timeline; | ||||||
|  | 
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| #endif // CLASSICGAME_H
 | #endif // CLASSICGAME_H
 | ||||||
|  | |||||||
							
								
								
									
										8
									
								
								src/classicgame/classicnote.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								src/classicgame/classicnote.cpp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,8 @@ | |||||||
|  | #include "classicnote.h" | ||||||
|  | 
 | ||||||
|  | ClassicNote::ClassicNote(const std::vector<microsec>& intervals, microsec perfect_offset) : | ||||||
|  |     Note(perfect_offset), | ||||||
|  |     _evaluator(intervals, _perfect_offset) | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										22
									
								
								src/classicgame/classicnote.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/classicgame/classicnote.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include "note.h" | ||||||
|  | #include "precisionevaluator.h" | ||||||
|  | 
 | ||||||
|  | class ClassicNote : public Note | ||||||
|  | { | ||||||
|  | public: | ||||||
|  | 
 | ||||||
|  |     enum class GRADE | ||||||
|  |     { | ||||||
|  |         PERFECT, | ||||||
|  |            GOOD, | ||||||
|  |             BAD | ||||||
|  |     }; | ||||||
|  | 
 | ||||||
|  |     explicit ClassicNote(const std::vector<microsec>& intervals, microsec perfect_offset); | ||||||
|  |     virtual ~ClassicNote() = default; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     PrecisionEvaluator<GRADE> _evaluator; | ||||||
|  | }; | ||||||
							
								
								
									
										0
									
								
								src/classicgame/classicsprite.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/classicgame/classicsprite.cpp
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								src/classicgame/classicsprite.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/classicgame/classicsprite.h
									
									
									
									
									
										Normal file
									
								
							| @ -1,12 +1,9 @@ | |||||||
| #include "timeline.h" |  | ||||||
| #include "note.h" |  | ||||||
| #include "timelineviewmanager.h" |  | ||||||
| 
 |  | ||||||
| #include <SFML/Graphics/RenderTarget.hpp> |  | ||||||
| #include <iostream> | #include <iostream> | ||||||
|  | #include "classicactions.h" | ||||||
|  | #include "classictimeline.h" | ||||||
|  | #include "note.h" | ||||||
| 
 | 
 | ||||||
| Timeline::Timeline(std::unique_ptr<TimelineViewManager> view_manager) : | ClassicTimeline::ClassicTimeline() | ||||||
|     _view_manager(std::move(view_manager)) |  | ||||||
| { | { | ||||||
|     // BPM of METEOR is 170.
 |     // BPM of METEOR is 170.
 | ||||||
|     // Length is 1:14
 |     // Length is 1:14
 | ||||||
| @ -22,15 +19,13 @@ Timeline::Timeline(std::unique_ptr<TimelineViewManager> view_manager) : | |||||||
|     microsec bpm_end = starting_beat_offset + (interval * amount_of_beats); |     microsec bpm_end = starting_beat_offset + (interval * amount_of_beats); | ||||||
|     _visibility_offset = note_input_offset * 12; |     _visibility_offset = note_input_offset * 12; | ||||||
| 
 | 
 | ||||||
|     Note::resetPrecisionQualifier(note_input_offset / 3); |     _timeline.emplace_back(new Note(bpm_iterator, note_input_offset, Button::DOWN)); | ||||||
| 
 |  | ||||||
|     _timeline.emplace_back(new Note(bpm_iterator, note_input_offset, Note::Arrow::DOWN)); |  | ||||||
|     bpm_iterator += interval; |     bpm_iterator += interval; | ||||||
| 
 | 
 | ||||||
|     _timeline.emplace_back(new Note(bpm_iterator, note_input_offset, Note::Arrow::LEFT)); |     _timeline.emplace_back(new Note(bpm_iterator, note_input_offset, Button::LEFT)); | ||||||
|     bpm_iterator += interval; |     bpm_iterator += interval; | ||||||
| 
 | 
 | ||||||
|     _timeline.emplace_back(new Note(bpm_iterator, note_input_offset, Note::Arrow::LEFT)); |     _timeline.emplace_back(new Note(bpm_iterator, note_input_offset, Button::LEFT)); | ||||||
|     bpm_iterator += interval; |     bpm_iterator += interval; | ||||||
| 
 | 
 | ||||||
|     while (bpm_iterator < bpm_end) |     while (bpm_iterator < bpm_end) | ||||||
| @ -39,19 +34,6 @@ Timeline::Timeline(std::unique_ptr<TimelineViewManager> view_manager) : | |||||||
|         bpm_iterator += interval; |         bpm_iterator += interval; | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     _timeline[0]->setPosition({200, 200}); |  | ||||||
|     _timeline[1]->setPosition({250, 200}); |  | ||||||
|     _timeline[2]->setPosition({300, 200}); |  | ||||||
|     _timeline[3]->setPosition({350, 200}); |  | ||||||
|     _timeline[4]->setPosition({400, 200}); |  | ||||||
|     _timeline[5]->setPosition({450, 200}); |  | ||||||
|     _timeline[6]->setPosition({200, 300}); |  | ||||||
|     _timeline[7]->setPosition({250, 300}); |  | ||||||
|     _timeline[8]->setPosition({300, 300}); |  | ||||||
|     _timeline[9]->setPosition({350, 300}); |  | ||||||
|     _timeline[10]->setPosition({400, 300}); |  | ||||||
|     _timeline[11]->setPosition({450, 300}); |  | ||||||
| 
 |  | ||||||
|     _active_note = nullptr; |     _active_note = nullptr; | ||||||
|     _last_visible_note = _timeline.end(); |     _last_visible_note = _timeline.end(); | ||||||
|     _top_note = _timeline.begin(); |     _top_note = _timeline.begin(); | ||||||
| @ -93,19 +75,6 @@ void Timeline::clear() | |||||||
|     Note::resetPrecisionQualifier(); |     Note::resetPrecisionQualifier(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| void Timeline::draw(sf::RenderTarget& target, sf::RenderStates states) const  // Temporary solution
 |  | ||||||
| { |  | ||||||
|     if (_last_visible_note == _timeline.end() || _top_note > _last_visible_note) |  | ||||||
|         return; |  | ||||||
| 
 |  | ||||||
|     auto note_to_draw = _top_note; |  | ||||||
|     while (note_to_draw != (_last_visible_note + 1)) |  | ||||||
|     { |  | ||||||
|         target.draw(*(*note_to_draw), states); |  | ||||||
|         ++note_to_draw; |  | ||||||
|     } |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void Timeline::update(const microsec &music_offset) | void Timeline::update(const microsec &music_offset) | ||||||
| { | { | ||||||
|     checkCurrentActiveNote(music_offset); |     checkCurrentActiveNote(music_offset); | ||||||
							
								
								
									
										43
									
								
								src/classicgame/classictimeline.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								src/classicgame/classictimeline.h
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | |||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <vector> | ||||||
|  | #include "timeline.h" | ||||||
|  | 
 | ||||||
|  | class Note; | ||||||
|  | 
 | ||||||
|  | class ClassicTimeline : public Timeline | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     explicit ClassicTimeline(); | ||||||
|  |     virtual void update(const microsec& music_offset) override; | ||||||
|  |     virtual void init() override; | ||||||
|  |     virtual void clear() override; | ||||||
|  | 
 | ||||||
|  |     Note *getActiveNote(const microsec &music_offset) noexcept; | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |     std::vector<Note*> _timeline; | ||||||
|  |     std::vector<Note*>::const_iterator _top_note; | ||||||
|  |     Note* _active_note; | ||||||
|  | 
 | ||||||
|  |     std::vector<Note*>::const_iterator _last_visible_note; | ||||||
|  |     microsec _visibility_offset; | ||||||
|  | 
 | ||||||
|  |     void checkCurrentActiveNote(const microsec &music_offset); | ||||||
|  |     void checkForNextActiveNote(const microsec &music_offset); | ||||||
|  |     void prepareNotesToDraw(const microsec &music_offset); | ||||||
|  | 
 | ||||||
|  |     /* Difference between top and active note is that
 | ||||||
|  |      * top note is the note handling input right now | ||||||
|  |      * OR it's the closest note from current music offset | ||||||
|  |      * position, not necessarily active. A note stops being top only | ||||||
|  |      * after dying or being tapped by player, even if it's already | ||||||
|  |      * past her perfect offset. | ||||||
|  |      * | ||||||
|  |      * Meanwhile active note is the note which is currently handling | ||||||
|  |      *     player input for grade. | ||||||
|  |      * | ||||||
|  |      * An active note is always top note but a top note | ||||||
|  |      *    is not always active note. | ||||||
|  |      *                                         */ | ||||||
|  | }; | ||||||
| @ -1,15 +0,0 @@ | |||||||
| #include "notegraphicsentity.h" |  | ||||||
| 
 |  | ||||||
| NoteGraphicsEntity::NoteGraphicsEntity() : |  | ||||||
|     _attached(false) |  | ||||||
| {} |  | ||||||
| 
 |  | ||||||
| void NoteGraphicsEntity::attach() noexcept |  | ||||||
| { |  | ||||||
|     _attached = true; |  | ||||||
| } |  | ||||||
| 
 |  | ||||||
| void NoteGraphicsEntity::detach() noexcept |  | ||||||
| { |  | ||||||
|     _attached = false; |  | ||||||
| } |  | ||||||
| @ -1,4 +0,0 @@ | |||||||
| #include "timelineviewmanager.h" |  | ||||||
| 
 |  | ||||||
| TimelineViewManager::TimelineViewManager() |  | ||||||
| {} |  | ||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user