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