forked from NaiJi/project-kyoku
Add abstraction for timeline views
This commit is contained in:
parent
dd3a175b55
commit
ecd0e67ed1
|
@ -4,22 +4,24 @@ project(project-kyoku LANGUAGES CXX)
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 17)
|
set(CMAKE_CXX_STANDARD 17)
|
||||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||||
set(SOURCES application.cpp note.cpp main.cpp)
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall")
|
||||||
set(HEADER_FILES application.h note.h)
|
set(SOURCES application.cpp note.cpp debughelper.cpp main.cpp timeline.cpp timelineviews/timelineviewmanager.cpp timelineviews/classicviewmanager.cpp)
|
||||||
|
set(HEADER_FILES application.h note.h debughelper.h timeline.h timelineviews/timelineviewmanager.h timelineviews/classicviewmanager.h)
|
||||||
|
|
||||||
# STATIC #
|
# STATIC #
|
||||||
# You need to build SFML from sources with cmake
|
# You need to build SFML from sources with cmake
|
||||||
#set(SFML_LIB_DIR
|
set(SFML_LIB_DIR
|
||||||
# ${CMAKE_SOURCE_DIR}/SFML-2.5.1/lib/libsfml-graphics.so.2.5
|
${CMAKE_SOURCE_DIR}/SFML-2.5.1/lib/libsfml-graphics.so.2.5
|
||||||
# ${CMAKE_SOURCE_DIR}/SFML-2.5.1/lib/libsfml-system.so.2.5
|
${CMAKE_SOURCE_DIR}/SFML-2.5.1/lib/libsfml-system.so.2.5
|
||||||
# ${CMAKE_SOURCE_DIR}/SFML-2.5.1/lib/libsfml-window.so.2.5)
|
${CMAKE_SOURCE_DIR}/SFML-2.5.1/lib/libsfml-window.so.2.5
|
||||||
#set(SFML_INCL_DIR ${CMAKE_SOURCE_DIR}/SFML-2.5.1/include)
|
${CMAKE_SOURCE_DIR}/SFML-2.5.1/lib/libsfml-audio.so.2.5)
|
||||||
#include_directories(${SFML_INCL_DIR})
|
set(SFML_INCL_DIR ${CMAKE_SOURCE_DIR}/SFML-2.5.1/include)
|
||||||
#add_executable(project-kyoku ${SOURCES} ${HEADER_FILES} )
|
include_directories(${SFML_INCL_DIR})
|
||||||
#target_link_libraries(project-kyoku ${SFML_LIB_DIR})
|
add_executable(project-kyoku ${SOURCES} ${HEADER_FILES} )
|
||||||
|
target_link_libraries(project-kyoku ${SFML_LIB_DIR})
|
||||||
|
|
||||||
# DYNAMIC #
|
# DYNAMIC #
|
||||||
# You only need to install SFML from your package manager
|
# You only need to install SFML from your package manager
|
||||||
find_package(SFML REQUIRED graphics window system)
|
#find_package(SFML REQUIRED graphics window system)
|
||||||
add_executable(project-kyoku ${SOURCES} ${HEADER_FILES} )
|
#add_executable(project-kyoku ${SOURCES} ${HEADER_FILES} )
|
||||||
target_link_libraries(project-kyoku sfml-system sfml-audio sfml-graphics sfml-network)
|
#target_link_libraries(project-kyoku sfml-system sfml-audio sfml-graphics sfml-network)
|
||||||
|
|
|
@ -30,12 +30,6 @@ void Application::run()
|
||||||
startGameLoop();
|
startGameLoop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool isOneFramePassed(const sf::Time& time_since_last_update)
|
|
||||||
{
|
|
||||||
return time_since_last_update >= TIME_PER_FRAME;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::startGameLoop()
|
void Application::startGameLoop()
|
||||||
{
|
{
|
||||||
sf::Clock timer;
|
sf::Clock timer;
|
||||||
|
@ -46,7 +40,9 @@ void Application::startGameLoop()
|
||||||
input();
|
input();
|
||||||
|
|
||||||
time_since_last_update += timer.restart();
|
time_since_last_update += timer.restart();
|
||||||
if (isOneFramePassed(time_since_last_update))
|
|
||||||
|
bool isOneFramePassed = time_since_last_update >= TIME_PER_FRAME;
|
||||||
|
if (isOneFramePassed)
|
||||||
{
|
{
|
||||||
time_since_last_update -= TIME_PER_FRAME;
|
time_since_last_update -= TIME_PER_FRAME;
|
||||||
update();
|
update();
|
||||||
|
@ -148,11 +144,11 @@ void Application::onTap(const Note::Arrow &arrow)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
const auto music_offset = _music.getPlayingOffset().asMicroseconds();
|
const auto music_offset = _music.getPlayingOffset().asMicroseconds();
|
||||||
const auto note = _timeline.fetchActiveNote(music_offset);
|
auto note = _timeline.fetchActiveNote(music_offset);
|
||||||
|
|
||||||
if (note)
|
if (note)
|
||||||
{
|
{
|
||||||
const auto tap_result = note->onTap(arrow, music_offset);
|
auto tap_result = note->onTap(arrow, music_offset);
|
||||||
makeGradeString(tap_result.rating, _grade);
|
makeGradeString(tap_result.rating, _grade);
|
||||||
_grade.setFillColor(sf::Color(255, 255, 255, 255));
|
_grade.setFillColor(sf::Color(255, 255, 255, 255));
|
||||||
}
|
}
|
||||||
|
|
10
note.cpp
10
note.cpp
|
@ -24,8 +24,11 @@ microsec Note::offset() const noexcept
|
||||||
return _offset;
|
return _offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
NoteGrade Note::onTap(Arrow arrow_type, microsec tap_time_stamp) const
|
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};
|
||||||
|
|
||||||
|
@ -56,4 +59,9 @@ void Note::resetPrecisionQualifier(microsec qualifier)
|
||||||
_precision_qualifier = qualifier;
|
_precision_qualifier = qualifier;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Note::resetSprite(const std::shared_ptr<Sprite> &sprite) noexcept
|
||||||
|
{
|
||||||
|
_sprite = sprite;
|
||||||
|
}
|
||||||
|
|
||||||
microsec Note::_precision_qualifier = 500000; // Default initialization as 0.5 second.
|
microsec Note::_precision_qualifier = 500000; // Default initialization as 0.5 second.
|
||||||
|
|
24
note.h
24
note.h
|
@ -3,12 +3,30 @@
|
||||||
|
|
||||||
#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 <memory>
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
using microsec = sf::Int64;
|
using microsec = sf::Int64;
|
||||||
using coordinates = sf::Vector2i;
|
using coordinates = sf::Vector2i;
|
||||||
|
|
||||||
|
class Sprite // MOCK
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Sprite(sf::RectangleShape shape) : _shape(shape), _attached(false) {};
|
||||||
|
bool isAttached() const noexcept
|
||||||
|
{ return _attached; }
|
||||||
|
|
||||||
|
void setAttachment(bool attached) noexcept
|
||||||
|
{ _attached = attached; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
sf::RectangleShape _shape;
|
||||||
|
bool _attached;
|
||||||
|
};
|
||||||
|
|
||||||
struct NoteGrade
|
struct NoteGrade
|
||||||
{
|
{
|
||||||
int score;
|
int score;
|
||||||
|
@ -44,9 +62,11 @@ public:
|
||||||
coordinates position() const noexcept;
|
coordinates position() const noexcept;
|
||||||
microsec offset() const noexcept;
|
microsec offset() const noexcept;
|
||||||
|
|
||||||
NoteGrade onTap(Arrow arrow_type, microsec tap_time_stamp) const;
|
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;
|
||||||
|
|
||||||
static void resetPrecisionQualifier(microsec qualifier = 500000);
|
static void resetPrecisionQualifier(microsec qualifier = 500000);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -58,6 +78,8 @@ private:
|
||||||
|
|
||||||
static microsec _precision_qualifier;
|
static microsec _precision_qualifier;
|
||||||
NoteGrade calculatePrecision(microsec odds) const;
|
NoteGrade calculatePrecision(microsec odds) const;
|
||||||
|
|
||||||
|
std::shared_ptr<Sprite> _sprite;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NOTE_H
|
#endif // NOTE_H
|
||||||
|
|
|
@ -124,7 +124,7 @@ void Timeline::checkForNextActiveNote(const microsec &music_offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const Note* Timeline::fetchActiveNote(const microsec &music_offset) noexcept
|
Note* Timeline::fetchActiveNote(const microsec &music_offset) noexcept
|
||||||
{
|
{
|
||||||
std::cout << "Clicked at: " << music_offset << '\n';
|
std::cout << "Clicked at: " << music_offset << '\n';
|
||||||
update(music_offset);
|
update(music_offset);
|
||||||
|
|
|
@ -19,7 +19,7 @@ public:
|
||||||
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override;
|
||||||
|
|
||||||
void update(const microsec& music_offset);
|
void update(const microsec& music_offset);
|
||||||
const Note* fetchActiveNote(const microsec &music_offset) noexcept;
|
Note *fetchActiveNote(const microsec &music_offset) noexcept;
|
||||||
|
|
||||||
/* void init(); */
|
/* void init(); */
|
||||||
void clear();
|
void clear();
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
#include "timelineviewmanager.h"
|
||||||
|
|
||||||
|
TimelineViewManager::TimelineViewManager()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
#ifndef TIMELINEVIEWMANAGER_H
|
||||||
|
#define TIMELINEVIEWMANAGER_H
|
||||||
|
|
||||||
|
|
||||||
|
class TimelineViewManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
TimelineViewManager();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TIMELINEVIEWMANAGER_H
|
|
@ -0,0 +1,28 @@
|
||||||
|
#include "classicviewmanager.h"
|
||||||
|
#include "../note.h"
|
||||||
|
#include <SFML/Graphics/RectangleShape.hpp>
|
||||||
|
|
||||||
|
static constexpr std::size_t RESERVED_SIZE = 20;
|
||||||
|
|
||||||
|
ClassicViewManager::ClassicViewManager()
|
||||||
|
{
|
||||||
|
for (std::size_t i = ARROW_UP; i < AMOUNT_OF_KINDS; ++i)
|
||||||
|
{
|
||||||
|
SpritePoll &poll = _sprite_dispatcher.at(i);
|
||||||
|
poll.reserve(RESERVED_SIZE);
|
||||||
|
for (auto &sprite : poll)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Sprite> ClassicViewManager::createSprite(Button kind_of_button) const
|
||||||
|
{
|
||||||
|
auto sprite = std::make_shared<sf::RectangleShape>();
|
||||||
|
sprite->setSize({20.f, 20.f});
|
||||||
|
switch (kind_of_button)
|
||||||
|
{
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,43 @@
|
||||||
|
#ifndef CLASSICDIVAVIEWMANAGER_H
|
||||||
|
#define CLASSICDIVAVIEWMANAGER_H
|
||||||
|
|
||||||
|
#include "timelineviewmanager.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
class Sprite;
|
||||||
|
|
||||||
|
class ClassicViewManager : public TimelineViewManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ClassicViewManager();
|
||||||
|
virtual ~ClassicViewManager() override;
|
||||||
|
|
||||||
|
virtual void update() override;
|
||||||
|
virtual void draw() override;
|
||||||
|
virtual void initNoteGraphics(Note *note) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
|
||||||
|
enum Button
|
||||||
|
{
|
||||||
|
ARROW_UP,
|
||||||
|
ARROW_DOWN,
|
||||||
|
ARROW_LEFT,
|
||||||
|
ARROW_RIGHT,
|
||||||
|
|
||||||
|
SHOULDER_RIGHT,
|
||||||
|
SHOULDER_LEFT,
|
||||||
|
|
||||||
|
AMOUNT_OF_KINDS
|
||||||
|
};
|
||||||
|
|
||||||
|
using SpritePoll = std::vector<std::shared_ptr<Sprite>>;
|
||||||
|
using SpriteDispatcher = std::array<SpritePoll, AMOUNT_OF_KINDS>;
|
||||||
|
SpriteDispatcher _sprite_dispatcher;
|
||||||
|
|
||||||
|
std::shared_ptr<Sprite> createSprite(Button kind_of_button) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // CLASSICDIVAVIEWMANAGER_H
|
|
@ -0,0 +1,7 @@
|
||||||
|
#include "timelineviewmanager.h"
|
||||||
|
|
||||||
|
TimelineViewManager::TimelineViewManager()
|
||||||
|
{}
|
||||||
|
|
||||||
|
TimelineViewManager::~TimelineViewManager()
|
||||||
|
{}
|
|
@ -0,0 +1,17 @@
|
||||||
|
#ifndef TIMELINEVIEWMANAGER_H
|
||||||
|
#define TIMELINEVIEWMANAGER_H
|
||||||
|
|
||||||
|
class Note;
|
||||||
|
|
||||||
|
class TimelineViewManager
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit TimelineViewManager();
|
||||||
|
virtual ~TimelineViewManager();
|
||||||
|
|
||||||
|
virtual void update() = 0;
|
||||||
|
virtual void draw() = 0;
|
||||||
|
virtual void initNoteGraphics(Note *note) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TIMELINEVIEWMANAGER_H
|
Loading…
Reference in New Issue