forked from NaiJi/project-kyoku
Encapsulate timeline and implement logic on it
parent
47277ee754
commit
367316b327
@ -0,0 +1,66 @@
|
||||
#include "timeline.h"
|
||||
#include "note.h"
|
||||
|
||||
Timeline::Timeline()
|
||||
{
|
||||
// BPM of METEOR is 170.
|
||||
// Length is 1:14
|
||||
// I calculated that the time between beats is about 1412162 microseconds
|
||||
|
||||
microsec starting_beat_offset = 372162;
|
||||
int amount_of_beats = 209;
|
||||
microsec time_between_beats = 1412162;
|
||||
microsec note_input_offset = 412162;
|
||||
microsec interval = starting_beat_offset + (time_between_beats * amount_of_beats);
|
||||
|
||||
Note::resetPrecisionQualifier(note_input_offset / 2);
|
||||
|
||||
while (interval > 0)
|
||||
{
|
||||
_timeline.emplace_back(new Note(interval, note_input_offset));
|
||||
interval -= time_between_beats;
|
||||
}
|
||||
|
||||
_active_note = nullptr;
|
||||
_top_note = _timeline.begin();
|
||||
}
|
||||
|
||||
Timeline::~Timeline()
|
||||
{
|
||||
for (auto note : _timeline)
|
||||
delete note;
|
||||
|
||||
_timeline.clear();
|
||||
_top_note = _timeline.end();
|
||||
_active_note = nullptr;
|
||||
|
||||
Note::resetPrecisionQualifier();
|
||||
}
|
||||
|
||||
void Timeline::update(const microsec µseconds)
|
||||
{
|
||||
checkCurrentActiveNote(microseconds);
|
||||
checkForNextActiveNote(microseconds);
|
||||
}
|
||||
|
||||
void Timeline::checkCurrentActiveNote(const microsec µseconds)
|
||||
{
|
||||
if (_active_note && !_active_note->isActive(microseconds))
|
||||
{
|
||||
_active_note = nullptr;
|
||||
++_top_note;
|
||||
}
|
||||
}
|
||||
|
||||
void Timeline::checkForNextActiveNote(const microsec µseconds)
|
||||
{
|
||||
if (!_active_note && (*_top_note)->isActive(microseconds))
|
||||
{
|
||||
_active_note = *_top_note;
|
||||
}
|
||||
}
|
||||
|
||||
const Note* Timeline::getActiveNote() const noexcept
|
||||
{
|
||||
return _active_note;
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
#ifndef TIMELINE_H
|
||||
#define TIMELINE_H
|
||||
|
||||
#include <SFML/Config.hpp>
|
||||
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
using microsec = sf::Int64;
|
||||
class Note;
|
||||
|
||||
class Timeline
|
||||
{
|
||||
public:
|
||||
explicit Timeline();
|
||||
~Timeline();
|
||||
|
||||
void update(const microsec& microseconds);
|
||||
const Note* getActiveNote() const noexcept;
|
||||
|
||||
private:
|
||||
std::vector<Note*> _timeline;
|
||||
std::vector<Note*>::iterator _top_note;
|
||||
Note* _active_note;
|
||||
|
||||
void checkCurrentActiveNote(const microsec µseconds);
|
||||
void checkForNextActiveNote(const microsec µseconds);
|
||||
|
||||
/* 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
|
Loading…
Reference in New Issue