forked from NaiJi/project-kyoku
All simple curve flying animation
This commit is contained in:
parent
7dc4ef2bb8
commit
192e371d2f
|
@ -30,7 +30,7 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<Game> _game;
|
std::unique_ptr<Game> _game;
|
||||||
|
|
||||||
void startGameLoop();
|
void exec();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // APPLICATION_H
|
#endif // APPLICATION_H
|
||||||
|
|
|
@ -13,7 +13,8 @@ public:
|
||||||
_perfect_offset(perfect_offset) {}
|
_perfect_offset(perfect_offset) {}
|
||||||
virtual ~Note() = default;
|
virtual ~Note() = default;
|
||||||
|
|
||||||
virtual bool isActive(microsec music_offset) const = 0;
|
virtual bool isActive(const microsec& music_offset) const = 0;
|
||||||
|
virtual void update(const microsec& music_offset) = 0;
|
||||||
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const = 0;
|
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const = 0;
|
||||||
|
|
||||||
virtual microsec offset() const
|
virtual microsec offset() const
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
using microsec = sf::Int64;
|
using microsec = sf::Int64;
|
||||||
|
|
||||||
template<typename GRADE, typename = std::enable_if_t<std::is_enum<GRADE>::value>>
|
template<typename Grade, typename = std::enable_if_t<std::is_enum<Grade>::value>>
|
||||||
class PrecisionEvaluator
|
class PrecisionEvaluator
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -34,7 +34,7 @@ public:
|
||||||
&& music_play_offset < _end_handling_offset;
|
&& music_play_offset < _end_handling_offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline GRADE calculatePrecision(microsec odds) const noexcept
|
inline Grade calculatePrecision(microsec odds) const noexcept
|
||||||
{
|
{
|
||||||
microsec shift_from_perfect = std::abs(odds - offset());
|
microsec shift_from_perfect = std::abs(odds - offset());
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ public:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return static_cast<GRADE>(raw_grade);
|
return static_cast<Grade>(raw_grade);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -53,9 +53,9 @@ private:
|
||||||
microsec _start_handling_offset;
|
microsec _start_handling_offset;
|
||||||
microsec _end_handling_offset;
|
microsec _end_handling_offset;
|
||||||
|
|
||||||
/* Amount of values in enum instanced as GRADES
|
/* Amount of values in enum instanced as GradeS
|
||||||
* represents capacity of _intervals.
|
* represents capacity of _intervals.
|
||||||
* So, for each V value in GRADES enum, _intervals[V]
|
* So, for each V value in GradeS enum, _intervals[V]
|
||||||
* should return time shift from V - 1.
|
* should return time shift from V - 1.
|
||||||
* 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 */
|
||||||
|
|
|
@ -13,7 +13,7 @@ public:
|
||||||
virtual ~Timeline() = default;
|
virtual ~Timeline() = default;
|
||||||
|
|
||||||
virtual void update() = 0;
|
virtual void update() = 0;
|
||||||
virtual void init() = 0;
|
virtual void run() = 0;
|
||||||
virtual void clear() = 0;
|
virtual void clear() = 0;
|
||||||
|
|
||||||
virtual microsec currentMusicOffset() const = 0;
|
virtual microsec currentMusicOffset() const = 0;
|
||||||
|
|
|
@ -24,11 +24,12 @@ Application::~Application()
|
||||||
void Application::run()
|
void Application::run()
|
||||||
{
|
{
|
||||||
_game_window.display();
|
_game_window.display();
|
||||||
|
_game->run();
|
||||||
|
|
||||||
startGameLoop();
|
exec();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::startGameLoop()
|
void Application::exec()
|
||||||
{
|
{
|
||||||
sf::Clock timer;
|
sf::Clock timer;
|
||||||
sf::Time time_since_last_update = sf::Time::Zero;
|
sf::Time time_since_last_update = sf::Time::Zero;
|
||||||
|
@ -54,6 +55,9 @@ void Application::input()
|
||||||
sf::Event event;
|
sf::Event event;
|
||||||
while (_game_window.pollEvent(event))
|
while (_game_window.pollEvent(event))
|
||||||
{
|
{
|
||||||
|
if (event.type == sf::Event::Closed)
|
||||||
|
_game_window.close();
|
||||||
|
|
||||||
_game->input(event);
|
_game->input(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,9 +8,7 @@ ClassicGame::ClassicGame() :
|
||||||
_timeline(std::make_unique<ClassicTimeline>()),
|
_timeline(std::make_unique<ClassicTimeline>()),
|
||||||
_view_manager(std::make_unique<ClassicViewManager>())
|
_view_manager(std::make_unique<ClassicViewManager>())
|
||||||
{
|
{
|
||||||
_timeline->fetchVisibleNotes(_view_manager);
|
_font.loadFromFile("VeraMono.ttf");
|
||||||
_timeline->init();
|
|
||||||
|
|
||||||
_keys_to_buttons =
|
_keys_to_buttons =
|
||||||
{
|
{
|
||||||
{sf::Keyboard::Up, Button::UP}, // Load from settings
|
{sf::Keyboard::Up, Button::UP}, // Load from settings
|
||||||
|
@ -55,7 +53,8 @@ ClassicGame::~ClassicGame()
|
||||||
|
|
||||||
void ClassicGame::run()
|
void ClassicGame::run()
|
||||||
{
|
{
|
||||||
|
_timeline->fetchVisibleNotes(_view_manager);
|
||||||
|
_timeline->run();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicGame::input(const sf::Event& event)
|
void ClassicGame::input(const sf::Event& event)
|
||||||
|
@ -66,6 +65,7 @@ void ClassicGame::input(const sf::Event& event)
|
||||||
switch (event.type)
|
switch (event.type)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
|
return;
|
||||||
break;
|
break;
|
||||||
case sf::Event::KeyPressed:
|
case sf::Event::KeyPressed:
|
||||||
{
|
{
|
||||||
|
@ -83,8 +83,26 @@ void ClassicGame::input(const sf::Event& event)
|
||||||
|
|
||||||
auto note = _timeline->getActiveNote();
|
auto note = _timeline->getActiveNote();
|
||||||
|
|
||||||
if (!_timeline->isExpired(note))
|
if (!_timeline->isExpired(note) || (*note)->state() != ClassicNote::State::DEAD)
|
||||||
(*note)->input(ClassicInputType(timestamp, new_action));
|
{
|
||||||
|
auto grade = (*note)->input(ClassicInputType(timestamp, new_action));
|
||||||
|
|
||||||
|
sf::Text new_grade;
|
||||||
|
new_grade.setFillColor(sf::Color::White);
|
||||||
|
new_grade.setPosition((*note)->getCoordinates().x, (*note)->getCoordinates().y - 40);
|
||||||
|
switch (grade)
|
||||||
|
{
|
||||||
|
case ClassicNote::Grade::PERFECT:
|
||||||
|
new_grade.setString("PERFECT"); break;
|
||||||
|
case ClassicNote::Grade::GOOD:
|
||||||
|
new_grade.setString("GOOD"); break;
|
||||||
|
case ClassicNote::Grade::BAD:
|
||||||
|
new_grade.setString("BAD"); break;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_grade.setFont(_font);
|
||||||
|
_grades.emplace_back(new_grade);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Action ClassicGame::getActionKeyPressed(Button button) const
|
Action ClassicGame::getActionKeyPressed(Button button) const
|
||||||
|
@ -101,9 +119,24 @@ void ClassicGame::update()
|
||||||
{
|
{
|
||||||
_timeline->update();
|
_timeline->update();
|
||||||
_timeline->fetchVisibleNotes(_view_manager);
|
_timeline->fetchVisibleNotes(_view_manager);
|
||||||
|
|
||||||
|
for (auto& grade : _grades)
|
||||||
|
{
|
||||||
|
if (grade.getFillColor().a > 20)
|
||||||
|
{
|
||||||
|
grade.setFillColor(sf::Color(255, 255, 255, grade.getFillColor().a - 20));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_grades.remove_if([](const auto& grade) { return grade.getFillColor().a <= 20; });
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicGame::draw(sf::RenderWindow& window) const
|
void ClassicGame::draw(sf::RenderWindow& window) const
|
||||||
{
|
{
|
||||||
_timeline->drawVisibleNotes(window);
|
_timeline->drawVisibleNotes(window);
|
||||||
|
|
||||||
|
for (auto& grade : _grades)
|
||||||
|
{
|
||||||
|
window.draw(grade);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,8 @@
|
||||||
#define CLASSICGAME_H
|
#define CLASSICGAME_H
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <list>
|
||||||
|
#include <SFML/Graphics/Text.hpp>
|
||||||
#include "game.h"
|
#include "game.h"
|
||||||
#include "classicactions.h"
|
#include "classicactions.h"
|
||||||
|
|
||||||
|
@ -31,6 +32,9 @@ private:
|
||||||
|
|
||||||
std::unique_ptr<ClassicTimeline> _timeline;
|
std::unique_ptr<ClassicTimeline> _timeline;
|
||||||
std::unique_ptr<ClassicViewManager> _view_manager;
|
std::unique_ptr<ClassicViewManager> _view_manager;
|
||||||
|
|
||||||
|
sf::Font _font;
|
||||||
|
std::list<sf::Text> _grades;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // CLASSICGAME_H
|
#endif // CLASSICGAME_H
|
||||||
|
|
|
@ -8,22 +8,43 @@ ClassicNote::ClassicNote(const std::vector<microsec>& intervals, microsec perfec
|
||||||
Note(perfect_offset),
|
Note(perfect_offset),
|
||||||
_coordinates(coord),
|
_coordinates(coord),
|
||||||
_evaluator(intervals, _perfect_offset),
|
_evaluator(intervals, _perfect_offset),
|
||||||
_action(action)
|
_action(action),
|
||||||
|
_appearance_time(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
bool ClassicNote::isActive(microsec music_offset) const
|
bool ClassicNote::isActive(const microsec& music_offset) const
|
||||||
{
|
{
|
||||||
return _evaluator.isActive(music_offset);
|
return _evaluator.isActive(music_offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int getPt( int n1 , int n2 , float perc )
|
||||||
|
{
|
||||||
|
int diff = n2 - n1;
|
||||||
|
|
||||||
|
return n1 + ( diff * perc );
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClassicNote::update(const microsec& music_offset)
|
||||||
|
{
|
||||||
|
auto update_time = music_offset - _appearance_time;
|
||||||
|
auto i = update_time / _trail_path_percent / 100;
|
||||||
|
|
||||||
|
int xa = getPt( 720./2. , 1280./2. , i );
|
||||||
|
int ya = getPt( 0 , 720./2. , i );
|
||||||
|
int xb = getPt( 1280./2. , _coordinates.x , i );
|
||||||
|
int yb = getPt( 720./2. , _coordinates.y , i );
|
||||||
|
|
||||||
|
_sprite->setTrailCoordinates(getPt( xa , xb , i ), getPt( ya , yb , i ));
|
||||||
|
}
|
||||||
|
|
||||||
void ClassicNote::draw(sf::RenderTarget& target, sf::RenderStates states) const
|
void ClassicNote::draw(sf::RenderTarget& target, sf::RenderStates states) const
|
||||||
{
|
{
|
||||||
target.draw(*_sprite, states);
|
target.draw(*_sprite, states);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClassicNote::GRADE ClassicNote::input(ClassicInputType&& input_data)
|
auto ClassicNote::input(ClassicInputType&& input_data) -> Grade
|
||||||
{
|
{
|
||||||
auto grade = ClassicNote::GRADE::BAD;
|
auto grade = ClassicNote::Grade::BAD;
|
||||||
|
|
||||||
if (input_data == _action)
|
if (input_data == _action)
|
||||||
{
|
{
|
||||||
|
@ -31,7 +52,7 @@ ClassicNote::GRADE ClassicNote::input(ClassicInputType&& input_data)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "User input: " << static_cast<int>(grade) << "\n";
|
std::cout << "User input: " << static_cast<int>(grade) << "\n";
|
||||||
|
_state = State::DEAD;
|
||||||
return grade;
|
return grade;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,19 +61,35 @@ Action ClassicNote::action() const
|
||||||
return _action;
|
return _action;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto ClassicNote::state() const -> State
|
||||||
|
{
|
||||||
|
return _state;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClassicNote::setState(State next_state)
|
||||||
|
{
|
||||||
|
_state = next_state;
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<ClassicSprite> ClassicNote::sprite() const noexcept
|
std::shared_ptr<ClassicSprite> ClassicNote::sprite() const noexcept
|
||||||
{
|
{
|
||||||
return _sprite;
|
return _sprite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ClassicNote::saveAppearanceTime(const microsec &offset)
|
||||||
|
{
|
||||||
|
_appearance_time = offset;
|
||||||
|
_trail_path_percent = ((_perfect_offset - _appearance_time) * 0.01);
|
||||||
|
}
|
||||||
|
|
||||||
void ClassicNote::setSprite(const std::shared_ptr<ClassicSprite>& sprite) noexcept
|
void ClassicNote::setSprite(const std::shared_ptr<ClassicSprite>& sprite) noexcept
|
||||||
{
|
{
|
||||||
_sprite = sprite;
|
_sprite = sprite;
|
||||||
if (_sprite)
|
if (_sprite)
|
||||||
_sprite->setCoordinates(_coordinates.x, _coordinates.y);
|
_sprite->setCoordinates(_coordinates.x, _coordinates.y, 720/2, 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline const Coordinates& ClassicNote::getCoordinates() const noexcept
|
const Coordinates& ClassicNote::getCoordinates() const noexcept
|
||||||
{
|
{
|
||||||
return _coordinates;
|
return _coordinates;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,31 +23,46 @@ class ClassicNote : public Note
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
enum class GRADE
|
enum class Grade
|
||||||
{
|
{
|
||||||
PERFECT,
|
PERFECT,
|
||||||
GOOD,
|
GOOD,
|
||||||
BAD
|
BAD
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum class State
|
||||||
|
{
|
||||||
|
FLYING,
|
||||||
|
DYING,
|
||||||
|
DEAD
|
||||||
|
};
|
||||||
|
|
||||||
explicit ClassicNote(const std::vector<microsec>& intervals, microsec perfect_offset,
|
explicit ClassicNote(const std::vector<microsec>& intervals, microsec perfect_offset,
|
||||||
Action action, const Coordinates& coord);
|
Action action, const Coordinates& coord);
|
||||||
virtual ~ClassicNote() = default;
|
virtual ~ClassicNote() = default;
|
||||||
|
|
||||||
virtual bool isActive(microsec music_offset) const override;
|
virtual bool isActive(const microsec& music_offset) const override;
|
||||||
|
virtual void update(const microsec &music_offset) override;
|
||||||
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||||
|
|
||||||
GRADE input(ClassicInputType&& input_data);
|
Grade input(ClassicInputType&& input_data);
|
||||||
Action action() const;
|
Action action() const;
|
||||||
|
State state() const;
|
||||||
|
|
||||||
|
void setState(State next_state);
|
||||||
|
|
||||||
std::shared_ptr<ClassicSprite> sprite() const noexcept;
|
std::shared_ptr<ClassicSprite> sprite() const noexcept;
|
||||||
|
void saveAppearanceTime(const microsec& offset);
|
||||||
void setSprite(const std::shared_ptr<ClassicSprite>& sprite) noexcept;
|
void setSprite(const std::shared_ptr<ClassicSprite>& sprite) noexcept;
|
||||||
inline const Coordinates& getCoordinates() const noexcept;
|
const Coordinates& getCoordinates() const noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Coordinates _coordinates;
|
const Coordinates _coordinates;
|
||||||
const PrecisionEvaluator<GRADE> _evaluator;
|
const PrecisionEvaluator<Grade> _evaluator;
|
||||||
const Action _action;
|
const Action _action;
|
||||||
|
State _state = State::FLYING;
|
||||||
|
|
||||||
std::shared_ptr<ClassicSprite> _sprite;
|
std::shared_ptr<ClassicSprite> _sprite;
|
||||||
|
microsec _appearance_time;
|
||||||
|
float _trail_path_percent; //100% for sprite falling trajectory
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,15 +2,23 @@
|
||||||
#include <SFML/Graphics/RenderTarget.hpp>
|
#include <SFML/Graphics/RenderTarget.hpp>
|
||||||
|
|
||||||
ClassicSprite::ClassicSprite(const sf::RectangleShape& shape) :
|
ClassicSprite::ClassicSprite(const sf::RectangleShape& shape) :
|
||||||
_shape(shape)
|
_shape(shape),
|
||||||
|
_trail(shape)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
void ClassicSprite::draw(sf::RenderTarget& target, sf::RenderStates states) const
|
void ClassicSprite::draw(sf::RenderTarget& target, sf::RenderStates states) const
|
||||||
{
|
{
|
||||||
target.draw(_shape, states);
|
target.draw(_shape, states);
|
||||||
|
target.draw(_trail, states);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicSprite::setCoordinates(float x, float y) noexcept
|
void ClassicSprite::setCoordinates(float x, float y, float trail_x, float trail_y) noexcept
|
||||||
{
|
{
|
||||||
_shape.setPosition(x, y);
|
_shape.setPosition(x, y);
|
||||||
|
_trail.setPosition(trail_x, trail_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ClassicSprite::setTrailCoordinates(float trail_x, float trail_y) noexcept
|
||||||
|
{
|
||||||
|
_trail.setPosition(trail_x, trail_y);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,10 @@ public:
|
||||||
ClassicSprite(const sf::RectangleShape& shape);
|
ClassicSprite(const sf::RectangleShape& shape);
|
||||||
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||||
|
|
||||||
void setCoordinates(float x, float y) noexcept;
|
void setCoordinates(float x, float y, float trail_x, float trail_y) noexcept;
|
||||||
|
void setTrailCoordinates(float trail_x, float trail_y) noexcept;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sf::RectangleShape _shape;
|
sf::RectangleShape _shape;
|
||||||
|
sf::RectangleShape _trail;
|
||||||
};
|
};
|
||||||
|
|
|
@ -11,20 +11,20 @@ ClassicTimeline::ClassicTimeline()
|
||||||
// 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
|
||||||
|
|
||||||
std::string song_filename = "/home/naiji/METEOR.flac";
|
std::string song_filename = "METEOR.flac";
|
||||||
|
|
||||||
_music.openFromFile(song_filename);
|
_music.openFromFile(song_filename);
|
||||||
_music.setVolume(10);
|
_music.setVolume(10);
|
||||||
|
|
||||||
_timeline.reserve(1000);
|
_timeline.reserve(1000);
|
||||||
|
|
||||||
microsec starting_beat_offset = 372162;
|
microsec starting_beat_offset = 352162;
|
||||||
int amount_of_beats = 209;
|
int amount_of_beats = 209;
|
||||||
microsec interval = 1412162;
|
microsec interval = 1412162;
|
||||||
microsec note_input_offset = 412162;
|
microsec note_input_offset = 412162;
|
||||||
microsec bpm_iterator = starting_beat_offset;
|
microsec bpm_iterator = starting_beat_offset;
|
||||||
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 * 6;
|
_visibility_offset = note_input_offset * 8;
|
||||||
|
|
||||||
_timeline.emplace_back(new ClassicNote({note_input_offset}, bpm_iterator, Action::PRESS_DOWN, {90, 90}));
|
_timeline.emplace_back(new ClassicNote({note_input_offset}, bpm_iterator, Action::PRESS_DOWN, {90, 90}));
|
||||||
bpm_iterator += interval;
|
bpm_iterator += interval;
|
||||||
|
@ -35,10 +35,13 @@ ClassicTimeline::ClassicTimeline()
|
||||||
_timeline.emplace_back(new ClassicNote({note_input_offset}, bpm_iterator, Action::PRESS_LEFT, {290, 90}));
|
_timeline.emplace_back(new ClassicNote({note_input_offset}, bpm_iterator, Action::PRESS_LEFT, {290, 90}));
|
||||||
bpm_iterator += interval;
|
bpm_iterator += interval;
|
||||||
|
|
||||||
|
float x = 90.;
|
||||||
|
|
||||||
while (bpm_iterator < bpm_end)
|
while (bpm_iterator < bpm_end)
|
||||||
{
|
{
|
||||||
_timeline.emplace_back(new ClassicNote({note_input_offset}, bpm_iterator, Action::PRESS_UP, {390, 390}));
|
_timeline.emplace_back(new ClassicNote({note_input_offset}, bpm_iterator, Action::PRESS_UP, {x, 390.}));
|
||||||
bpm_iterator += interval;
|
bpm_iterator += interval;
|
||||||
|
x += 70;
|
||||||
}
|
}
|
||||||
|
|
||||||
expire(_last_visible_note);
|
expire(_last_visible_note);
|
||||||
|
@ -46,7 +49,7 @@ ClassicTimeline::ClassicTimeline()
|
||||||
_top_note = _timeline.begin();
|
_top_note = _timeline.begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicTimeline::init()
|
void ClassicTimeline::run()
|
||||||
{
|
{
|
||||||
_music.play();
|
_music.play();
|
||||||
}
|
}
|
||||||
|
@ -113,7 +116,7 @@ microsec ClassicTimeline::currentMusicOffset() const
|
||||||
return _music.getPlayingOffset().asMicroseconds();
|
return _music.getPlayingOffset().asMicroseconds();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ClassicTimeline::discardExpiredNotes(const std::unique_ptr<ClassicViewManager> &view_manager, const microsec &music_offset)
|
void ClassicTimeline::discardExpiredNotes(const std::unique_ptr<ClassicViewManager> &view_manager)
|
||||||
{
|
{
|
||||||
if (_top_note == _timeline.begin())
|
if (_top_note == _timeline.begin())
|
||||||
return;
|
return;
|
||||||
|
@ -137,15 +140,25 @@ bool ClassicTimeline::isVisiblyClose(const Iterator &iterator, const microsec &m
|
||||||
|
|
||||||
void ClassicTimeline::fetchVisibleNotes(const std::unique_ptr<ClassicViewManager>& view_manager)
|
void ClassicTimeline::fetchVisibleNotes(const std::unique_ptr<ClassicViewManager>& view_manager)
|
||||||
{
|
{
|
||||||
microsec music_offset = currentMusicOffset();
|
const microsec music_offset = currentMusicOffset();
|
||||||
discardExpiredNotes(view_manager, music_offset);
|
discardExpiredNotes(view_manager);
|
||||||
|
|
||||||
Iterator note_iterator = _top_note;
|
Iterator note_iterator = _top_note;
|
||||||
while (isVisiblyClose(note_iterator, music_offset))
|
while (isVisiblyClose(note_iterator, music_offset))
|
||||||
{
|
{
|
||||||
ClassicNote* note = *note_iterator;
|
ClassicNote* note = *note_iterator;
|
||||||
if (!note->sprite())
|
if (!note->sprite())
|
||||||
|
{
|
||||||
|
note->saveAppearanceTime(music_offset);
|
||||||
view_manager->initNoteSprite(note);
|
view_manager->initNoteSprite(note);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (note->state() == ClassicNote::State::DEAD)
|
||||||
|
{
|
||||||
|
view_manager->resetNoteSprite(note);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
note->update(music_offset);
|
||||||
|
|
||||||
++note_iterator;
|
++note_iterator;
|
||||||
}
|
}
|
||||||
|
@ -157,12 +170,14 @@ void ClassicTimeline::drawVisibleNotes(sf::RenderWindow &window) const
|
||||||
{
|
{
|
||||||
bool no_visible_notes = isExpired(_last_visible_note)
|
bool no_visible_notes = isExpired(_last_visible_note)
|
||||||
|| _top_note > _last_visible_note;
|
|| _top_note > _last_visible_note;
|
||||||
|
|
||||||
if (no_visible_notes)
|
if (no_visible_notes)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
Iterator note_to_draw = _top_note;
|
Iterator note_to_draw = _top_note;
|
||||||
while (note_to_draw != (_last_visible_note))
|
while (note_to_draw != (_last_visible_note))
|
||||||
{
|
{
|
||||||
|
if ((*note_to_draw)->sprite())
|
||||||
window.draw(*(*note_to_draw));
|
window.draw(*(*note_to_draw));
|
||||||
++note_to_draw;
|
++note_to_draw;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ public:
|
||||||
explicit ClassicTimeline();
|
explicit ClassicTimeline();
|
||||||
virtual ~ClassicTimeline();
|
virtual ~ClassicTimeline();
|
||||||
virtual void update() override;
|
virtual void update() override;
|
||||||
virtual void init() override;
|
virtual void run() override;
|
||||||
virtual void clear() override;
|
virtual void clear() override;
|
||||||
|
|
||||||
virtual microsec currentMusicOffset() const override;
|
virtual microsec currentMusicOffset() const override;
|
||||||
|
@ -41,7 +41,7 @@ private:
|
||||||
|
|
||||||
void checkCurrentActiveNote(const microsec &music_offset);
|
void checkCurrentActiveNote(const microsec &music_offset);
|
||||||
void checkForNextActiveNote(const microsec &music_offset);
|
void checkForNextActiveNote(const microsec &music_offset);
|
||||||
void discardExpiredNotes(const std::unique_ptr<ClassicViewManager>& view_manager, const microsec &music_offset);
|
void discardExpiredNotes(const std::unique_ptr<ClassicViewManager>& view_manager);
|
||||||
bool isVisiblyClose(const Iterator& iterator, const microsec& music_offset) const;
|
bool isVisiblyClose(const Iterator& iterator, const microsec& music_offset) const;
|
||||||
|
|
||||||
/* Difference between top and active note is that
|
/* Difference between top and active note is that
|
||||||
|
|
Loading…
Reference in New Issue