Run classic timelineviewmanager

This commit is contained in:
NaiJi ✨ 2021-04-17 19:14:36 +03:00
parent ecd0e67ed1
commit 8a7602af78
11 changed files with 105 additions and 52 deletions

View File

@ -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();

View File

@ -25,7 +25,7 @@ private:
sf::Font _font;
sf::Text _grade;
Timeline _timeline;
std::unique_ptr<Timeline> _timeline;
DebugHelper _debug;
void startGameLoop();

View File

@ -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
View File

@ -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);

View File

@ -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;
}
}

View File

@ -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);

View File

@ -1,6 +0,0 @@
#include "timelineviewmanager.h"
TimelineViewManager::TimelineViewManager()
{
}

View File

@ -1,11 +0,0 @@
#ifndef TIMELINEVIEWMANAGER_H
#define TIMELINEVIEWMANAGER_H
class TimelineViewManager
{
public:
TimelineViewManager();
};
#endif // TIMELINEVIEWMANAGER_H

View File

@ -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;
}
}
}

View File

@ -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,

View File

@ -9,8 +9,6 @@ public:
explicit TimelineViewManager();
virtual ~TimelineViewManager();
virtual void update() = 0;
virtual void draw() = 0;
virtual void initNoteGraphics(Note *note) = 0;
};