Run classic timelineviewmanager
This commit is contained in:
parent
ecd0e67ed1
commit
8a7602af78
|
@ -2,6 +2,7 @@
|
|||
|
||||
#include <SFML/Graphics/Color.hpp>
|
||||
#include <SFML/Window/Event.hpp>
|
||||
#include "timelineviews/classicviewmanager.h"
|
||||
|
||||
const sf::Time TIME_PER_FRAME = sf::seconds(1.f / 60.f);
|
||||
|
||||
|
@ -9,6 +10,7 @@ Application::Application() :
|
|||
_game_window({1280, 720}, "Test"),
|
||||
_debug(true)
|
||||
{
|
||||
_timeline = std::make_unique<Timeline>(std::make_unique<ClassicViewManager>());
|
||||
_font.loadFromFile("/usr/share/qtcreator/fonts/SourceCodePro-Regular.ttf");
|
||||
_grade.setFont(_font);
|
||||
_grade.setPosition(160, 160);
|
||||
|
@ -144,7 +146,7 @@ void Application::onTap(const Note::Arrow &arrow)
|
|||
return;
|
||||
|
||||
const auto music_offset = _music.getPlayingOffset().asMicroseconds();
|
||||
auto note = _timeline.fetchActiveNote(music_offset);
|
||||
auto note = _timeline->fetchActiveNote(music_offset);
|
||||
|
||||
if (note)
|
||||
{
|
||||
|
@ -158,7 +160,7 @@ void Application::update()
|
|||
{
|
||||
const auto music_offset = _music.getPlayingOffset().asMicroseconds();
|
||||
|
||||
_timeline.update(music_offset);
|
||||
_timeline->update(music_offset);
|
||||
_debug.update(music_offset);
|
||||
|
||||
if (_grade.getFillColor().a > 0) // TODO: Encapsulate
|
||||
|
@ -172,7 +174,7 @@ void Application::update()
|
|||
void Application::draw()
|
||||
{
|
||||
_game_window.clear();
|
||||
_game_window.draw(_timeline);
|
||||
_game_window.draw(*_timeline);
|
||||
_game_window.draw(_debug);
|
||||
_game_window.draw(_grade);
|
||||
_game_window.display();
|
||||
|
|
|
@ -25,7 +25,7 @@ private:
|
|||
sf::Font _font;
|
||||
sf::Text _grade;
|
||||
|
||||
Timeline _timeline;
|
||||
std::unique_ptr<Timeline> _timeline;
|
||||
DebugHelper _debug;
|
||||
|
||||
void startGameLoop();
|
||||
|
|
19
note.cpp
19
note.cpp
|
@ -26,9 +26,6 @@ microsec Note::offset() const noexcept
|
|||
|
||||
NoteGrade Note::onTap(Arrow arrow_type, microsec tap_time_stamp)
|
||||
{
|
||||
_sprite->setAttachment(false);
|
||||
_sprite = nullptr;
|
||||
|
||||
if (arrow_type != _type)
|
||||
return {0, NoteGrade::Rating::WRONG};
|
||||
|
||||
|
@ -61,7 +58,23 @@ void Note::resetPrecisionQualifier(microsec qualifier)
|
|||
|
||||
void Note::resetSprite(const std::shared_ptr<Sprite> &sprite) noexcept
|
||||
{
|
||||
if (_sprite)
|
||||
_sprite->setAttachment(false);
|
||||
|
||||
_sprite = sprite;
|
||||
|
||||
if (_sprite)
|
||||
_sprite->setAttachment(true);
|
||||
}
|
||||
|
||||
Note::Arrow Note::type() const noexcept
|
||||
{
|
||||
return _type;
|
||||
}
|
||||
|
||||
void Note::draw(sf::RenderTarget &target, sf::RenderStates states) const
|
||||
{
|
||||
target.draw(*_sprite, states);
|
||||
}
|
||||
|
||||
microsec Note::_precision_qualifier = 500000; // Default initialization as 0.5 second.
|
||||
|
|
18
note.h
18
note.h
|
@ -4,6 +4,7 @@
|
|||
#include <SFML/System/Clock.hpp>
|
||||
#include <SFML/System/Vector2.hpp>
|
||||
#include <SFML/Graphics/RectangleShape.hpp> // TEMP MOCK
|
||||
#include <SFML/Graphics/RenderTarget.hpp>
|
||||
|
||||
#include <memory>
|
||||
|
||||
|
@ -12,13 +13,21 @@
|
|||
using microsec = sf::Int64;
|
||||
using coordinates = sf::Vector2i;
|
||||
|
||||
class Sprite // MOCK
|
||||
class Sprite : public sf::Drawable // MOCK
|
||||
{
|
||||
public:
|
||||
Sprite(sf::RectangleShape shape) : _shape(shape), _attached(false) {};
|
||||
bool isAttached() const noexcept
|
||||
{ return _attached; }
|
||||
|
||||
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override
|
||||
{
|
||||
target.draw(_shape, states);
|
||||
}
|
||||
|
||||
void setCoordinates(coordinates cords) noexcept
|
||||
{ _shape.setPosition(cords.x, cords.y); }
|
||||
|
||||
void setAttachment(bool attached) noexcept
|
||||
{ _attached = attached; }
|
||||
|
||||
|
@ -43,7 +52,7 @@ struct NoteGrade
|
|||
|
||||
////////////////////////////////
|
||||
|
||||
class Note
|
||||
class Note : public sf::Drawable
|
||||
{
|
||||
public:
|
||||
enum class Arrow
|
||||
|
@ -61,11 +70,14 @@ public:
|
|||
void setPosition(coordinates position);
|
||||
coordinates position() const noexcept;
|
||||
microsec offset() const noexcept;
|
||||
Note::Arrow type() const noexcept;
|
||||
|
||||
NoteGrade onTap(Arrow arrow_type, microsec tap_time_stamp);
|
||||
bool isActive(microsec music_play_offset) const noexcept;
|
||||
|
||||
void resetSprite(const std::shared_ptr<Sprite>& sprite) noexcept;
|
||||
void resetSprite(const std::shared_ptr<Sprite>& sprite = nullptr) noexcept;
|
||||
|
||||
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||
|
||||
static void resetPrecisionQualifier(microsec qualifier = 500000);
|
||||
|
||||
|
|
36
timeline.cpp
36
timeline.cpp
|
@ -1,10 +1,12 @@
|
|||
#include "timeline.h"
|
||||
#include "note.h"
|
||||
#include "timelineviews/timelineviewmanager.h"
|
||||
|
||||
#include <SFML/Graphics/RenderTarget.hpp>
|
||||
#include <iostream>
|
||||
|
||||
Timeline::Timeline()
|
||||
Timeline::Timeline(std::unique_ptr<TimelineViewManager> view_manager) :
|
||||
_view_manager(std::move(view_manager))
|
||||
{
|
||||
// BPM of METEOR is 170.
|
||||
// Length is 1:14
|
||||
|
@ -18,10 +20,19 @@ Timeline::Timeline()
|
|||
microsec note_input_offset = 412162;
|
||||
microsec bpm_iterator = starting_beat_offset;
|
||||
microsec bpm_end = starting_beat_offset + (interval * amount_of_beats);
|
||||
_visibility_offset = note_input_offset * 3;
|
||||
_visibility_offset = note_input_offset * 12;
|
||||
|
||||
Note::resetPrecisionQualifier(note_input_offset / 3);
|
||||
|
||||
_timeline.emplace_back(new Note(bpm_iterator, note_input_offset, Note::Arrow::DOWN));
|
||||
bpm_iterator += interval;
|
||||
|
||||
_timeline.emplace_back(new Note(bpm_iterator, note_input_offset, Note::Arrow::LEFT));
|
||||
bpm_iterator += interval;
|
||||
|
||||
_timeline.emplace_back(new Note(bpm_iterator, note_input_offset, Note::Arrow::LEFT));
|
||||
bpm_iterator += interval;
|
||||
|
||||
while (bpm_iterator < bpm_end)
|
||||
{
|
||||
_timeline.emplace_back(new Note(bpm_iterator, note_input_offset));
|
||||
|
@ -45,6 +56,8 @@ Timeline::Timeline()
|
|||
_last_visible_note = _timeline.end();
|
||||
_top_note = _timeline.begin();
|
||||
|
||||
_last_visible_note = _top_note;
|
||||
_view_manager->initNoteGraphics(*_top_note);
|
||||
prepareNotesToDraw(0);
|
||||
}
|
||||
|
||||
|
@ -52,8 +65,12 @@ void Timeline::prepareNotesToDraw(const microsec &music_offset)
|
|||
{
|
||||
auto note_iterator = _top_note;
|
||||
|
||||
while (((*note_iterator)->offset() - _visibility_offset) >= music_offset)
|
||||
while (((*note_iterator)->offset() - _visibility_offset) <= music_offset)
|
||||
{
|
||||
++note_iterator;
|
||||
if (note_iterator > _last_visible_note)
|
||||
_view_manager->initNoteGraphics((*note_iterator));
|
||||
}
|
||||
|
||||
_last_visible_note = note_iterator;
|
||||
}
|
||||
|
@ -76,16 +93,6 @@ void Timeline::clear()
|
|||
Note::resetPrecisionQualifier();
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -94,7 +101,7 @@ void Timeline::draw(sf::RenderTarget& target, sf::RenderStates states) const //
|
|||
auto note_to_draw = _top_note;
|
||||
while (note_to_draw != (_last_visible_note + 1))
|
||||
{
|
||||
target.draw(createNoteGlyph(note_to_draw), states);
|
||||
target.draw(*(*note_to_draw), states);
|
||||
++note_to_draw;
|
||||
}
|
||||
}
|
||||
|
@ -111,6 +118,7 @@ void Timeline::checkCurrentActiveNote(const microsec &music_offset)
|
|||
if (_active_note && !_active_note->isActive(music_offset))
|
||||
{
|
||||
_active_note = nullptr;
|
||||
(*_top_note)->resetSprite();
|
||||
++_top_note;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,11 +9,12 @@
|
|||
|
||||
using microsec = sf::Int64;
|
||||
class Note;
|
||||
class TimelineViewManager;
|
||||
|
||||
class Timeline : public sf::Drawable // Probably it's bad
|
||||
{
|
||||
public:
|
||||
explicit Timeline();
|
||||
explicit Timeline(std::unique_ptr<TimelineViewManager> view_manager);
|
||||
virtual ~Timeline();
|
||||
|
||||
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||
|
@ -32,6 +33,8 @@ private:
|
|||
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);
|
||||
|
|
|
@ -1,6 +0,0 @@
|
|||
#include "timelineviewmanager.h"
|
||||
|
||||
TimelineViewManager::TimelineViewManager()
|
||||
{
|
||||
|
||||
}
|
|
@ -1,11 +0,0 @@
|
|||
#ifndef TIMELINEVIEWMANAGER_H
|
||||
#define TIMELINEVIEWMANAGER_H
|
||||
|
||||
|
||||
class TimelineViewManager
|
||||
{
|
||||
public:
|
||||
TimelineViewManager();
|
||||
};
|
||||
|
||||
#endif // TIMELINEVIEWMANAGER_H
|
|
@ -9,20 +9,56 @@ ClassicViewManager::ClassicViewManager()
|
|||
for (std::size_t i = ARROW_UP; i < AMOUNT_OF_KINDS; ++i)
|
||||
{
|
||||
SpritePoll &poll = _sprite_dispatcher.at(i);
|
||||
poll.reserve(RESERVED_SIZE);
|
||||
poll.resize(RESERVED_SIZE);
|
||||
for (auto &sprite : poll)
|
||||
{
|
||||
sprite = createSprite(static_cast<Button>(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
ClassicViewManager::~ClassicViewManager()
|
||||
{}
|
||||
|
||||
std::shared_ptr<Sprite> ClassicViewManager::createSprite(Button kind_of_button) const
|
||||
{
|
||||
auto sprite = std::make_shared<sf::RectangleShape>();
|
||||
sprite->setSize({20.f, 20.f});
|
||||
sf::RectangleShape sprite;
|
||||
sprite.setSize({20.f, 20.f});
|
||||
switch (kind_of_button)
|
||||
{
|
||||
return
|
||||
case ARROW_UP:
|
||||
sprite.setFillColor(sf::Color(255, 0, 0));
|
||||
break;
|
||||
|
||||
case ARROW_DOWN:
|
||||
sprite.setFillColor(sf::Color(0, 255, 0));
|
||||
break;
|
||||
|
||||
case ARROW_LEFT:
|
||||
sprite.setFillColor(sf::Color(0, 0, 255));
|
||||
break;
|
||||
|
||||
case ARROW_RIGHT:
|
||||
sprite.setFillColor(sf::Color(255, 0, 255));
|
||||
break;
|
||||
|
||||
default: // yellow
|
||||
sprite.setFillColor(sf::Color(255, 239, 0));
|
||||
}
|
||||
|
||||
return std::make_shared<Sprite>(sprite);
|
||||
}
|
||||
|
||||
void ClassicViewManager::initNoteGraphics(Note *note)
|
||||
{
|
||||
const auto type = note->type();
|
||||
for (const auto sprite : _sprite_dispatcher.at(static_cast<int>(type)))
|
||||
{
|
||||
if (!sprite->isAttached())
|
||||
{
|
||||
sprite->setCoordinates(note->position());
|
||||
note->resetSprite(sprite);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,8 +14,6 @@ public:
|
|||
explicit ClassicViewManager();
|
||||
virtual ~ClassicViewManager() override;
|
||||
|
||||
virtual void update() override;
|
||||
virtual void draw() override;
|
||||
virtual void initNoteGraphics(Note *note) override;
|
||||
|
||||
private:
|
||||
|
@ -23,9 +21,9 @@ private:
|
|||
enum Button
|
||||
{
|
||||
ARROW_UP,
|
||||
ARROW_RIGHT,
|
||||
ARROW_DOWN,
|
||||
ARROW_LEFT,
|
||||
ARROW_RIGHT,
|
||||
|
||||
SHOULDER_RIGHT,
|
||||
SHOULDER_LEFT,
|
||||
|
|
|
@ -9,8 +9,6 @@ public:
|
|||
explicit TimelineViewManager();
|
||||
virtual ~TimelineViewManager();
|
||||
|
||||
virtual void update() = 0;
|
||||
virtual void draw() = 0;
|
||||
virtual void initNoteGraphics(Note *note) = 0;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue