Test implementation of drawing timeline

selection
NaiJi ✨ 3 years ago
parent e8d1724b45
commit dd3a175b55

@ -147,8 +147,6 @@ void Application::onTap(const Note::Arrow &arrow)
if (arrow == Note::Arrow::NONE) if (arrow == Note::Arrow::NONE)
return; return;
_debug.spawnGreenPulse();
const auto music_offset = _music.getPlayingOffset().asMicroseconds(); const auto music_offset = _music.getPlayingOffset().asMicroseconds();
const auto note = _timeline.fetchActiveNote(music_offset); const auto note = _timeline.fetchActiveNote(music_offset);
@ -178,6 +176,7 @@ void Application::update()
void Application::draw() void Application::draw()
{ {
_game_window.clear(); _game_window.clear();
_game_window.draw(_timeline);
_game_window.draw(_debug); _game_window.draw(_debug);
_game_window.draw(_grade); _game_window.draw(_grade);
_game_window.display(); _game_window.display();

@ -1,6 +1,7 @@
#include "timeline.h" #include "timeline.h"
#include "note.h" #include "note.h"
#include <SFML/Graphics/RenderTarget.hpp>
#include <iostream> #include <iostream>
Timeline::Timeline() Timeline::Timeline()
@ -9,64 +10,123 @@ Timeline::Timeline()
// Length is 1:14 // Length is 1:14
// I calculated that the time between beats is about 1412162 microseconds // I calculated that the time between beats is about 1412162 microseconds
_timeline.reserve(1000);
microsec starting_beat_offset = 372162; microsec starting_beat_offset = 372162;
int amount_of_beats = 209; int amount_of_beats = 209;
microsec time_between_beats = 1412162; microsec interval = 1412162;
microsec note_input_offset = 412162; microsec note_input_offset = 412162;
microsec interval = starting_beat_offset; microsec bpm_iterator = starting_beat_offset;
microsec AAAAAAAAENDBLYAT = starting_beat_offset + (time_between_beats * amount_of_beats); microsec bpm_end = starting_beat_offset + (interval * amount_of_beats);
_visibility_offset = note_input_offset * 3;
Note::resetPrecisionQualifier(note_input_offset / 3); Note::resetPrecisionQualifier(note_input_offset / 3);
while (interval < AAAAAAAAENDBLYAT) while (bpm_iterator < bpm_end)
{ {
_timeline.emplace_back(new Note(interval, note_input_offset)); _timeline.emplace_back(new Note(bpm_iterator, note_input_offset));
interval += time_between_beats; 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();
_top_note = _timeline.begin(); _top_note = _timeline.begin();
prepareNotesToDraw(0);
}
void Timeline::prepareNotesToDraw(const microsec &music_offset)
{
auto note_iterator = _top_note;
while (((*note_iterator)->offset() - _visibility_offset) >= music_offset)
++note_iterator;
_last_visible_note = note_iterator;
} }
Timeline::~Timeline() Timeline::~Timeline()
{
clear();
}
void Timeline::clear()
{ {
for (auto note : _timeline) for (auto note : _timeline)
delete note; delete note;
_timeline.clear(); _timeline.clear();
_top_note = _timeline.end(); _top_note = _timeline.end();
_last_visible_note = _timeline.end();
_active_note = nullptr; _active_note = nullptr;
Note::resetPrecisionQualifier(); Note::resetPrecisionQualifier();
} }
void Timeline::update(const microsec &microseconds) static sf::RectangleShape createNoteGlyph(const std::vector<Note*>::const_iterator& note_to_draw)
{ // Temporary solution
sf::RectangleShape ret;
const auto position = (*note_to_draw)->position();
ret.setPosition(position.x, position.y);
ret.setFillColor(sf::Color(255, 100, 0));
ret.setSize({10.f, 10.f});
return ret;
}
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(createNoteGlyph(note_to_draw), states);
++note_to_draw;
}
}
void Timeline::update(const microsec &music_offset)
{ {
checkCurrentActiveNote(microseconds); checkCurrentActiveNote(music_offset);
checkForNextActiveNote(microseconds); checkForNextActiveNote(music_offset);
prepareNotesToDraw(music_offset);
} }
void Timeline::checkCurrentActiveNote(const microsec &microseconds) void Timeline::checkCurrentActiveNote(const microsec &music_offset)
{ {
if (_active_note && !_active_note->isActive(microseconds)) if (_active_note && !_active_note->isActive(music_offset))
{ {
_active_note = nullptr; _active_note = nullptr;
++_top_note; ++_top_note;
} }
} }
void Timeline::checkForNextActiveNote(const microsec &microseconds) void Timeline::checkForNextActiveNote(const microsec &music_offset)
{ {
if (!_active_note && (*_top_note)->isActive(microseconds)) if (!_active_note && (*_top_note)->isActive(music_offset))
{ {
std::cout << "New active note: " << microseconds << '\n'; std::cout << "New active note: " << music_offset << '\n';
_active_note = *_top_note; _active_note = *_top_note;
} }
} }
const Note* Timeline::fetchActiveNote(const microsec &microseconds) noexcept const Note* Timeline::fetchActiveNote(const microsec &music_offset) noexcept
{ {
std::cout << "Clicked at: " << microseconds << '\n'; std::cout << "Clicked at: " << music_offset << '\n';
update(microseconds); update(music_offset);
return _active_note; return _active_note;
} }

@ -2,6 +2,7 @@
#define TIMELINE_H #define TIMELINE_H
#include <SFML/Config.hpp> #include <SFML/Config.hpp>
#include <SFML/Graphics/RectangleShape.hpp>
#include <vector> #include <vector>
#include <memory> #include <memory>
@ -9,22 +10,31 @@
using microsec = sf::Int64; using microsec = sf::Int64;
class Note; class Note;
class Timeline class Timeline : public sf::Drawable // Probably it's bad
{ {
public: public:
explicit Timeline(); explicit Timeline();
~Timeline(); virtual ~Timeline();
void update(const microsec& microseconds); virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
const Note* fetchActiveNote(const microsec &microseconds) noexcept;
void update(const microsec& music_offset);
const Note* fetchActiveNote(const microsec &music_offset) noexcept;
/* void init(); */
void clear();
private: private:
std::vector<Note*> _timeline; std::vector<Note*> _timeline;
std::vector<Note*>::iterator _top_note; std::vector<Note*>::const_iterator _top_note;
Note* _active_note; Note* _active_note;
void checkCurrentActiveNote(const microsec &microseconds); std::vector<Note*>::const_iterator _last_visible_note;
void checkForNextActiveNote(const microsec &microseconds); 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 /* Difference between top and active note is that
* top note is the note handling input right now * top note is the note handling input right now

Loading…
Cancel
Save