forked from NaiJi/project-kyoku
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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
#include "classicnote.h"
|
||||||
|
|
||||||
|
ClassicNote::ClassicNote(const std::vector<microsec>& intervals, microsec perfect_offset) :
|
||||||
|
Note(perfect_offset),
|
||||||
|
_evaluator(intervals, _perfect_offset)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -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;
|
||||||
|
};
|
|
@ -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);
|
|
@ -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…
Reference in New Issue