From ad1b31c95c17f3145531b94ed1e30bc2e5b60198 Mon Sep 17 00:00:00 2001 From: NaiJi Date: Fri, 11 Jun 2021 20:39:47 +0300 Subject: [PATCH] Implement more precise active note detection --- include/application.h | 8 --- include/debughelper.h | 47 -------------- src/application.cpp | 11 ---- src/classicgame/classicgame.cpp | 36 +---------- src/classicgame/classicgame.h | 4 -- src/classicgame/classicnote.cpp | 9 ++- src/classicgame/classicsprite.cpp | 37 +++++++++-- src/classicgame/classicsprite.h | 10 ++- src/classicgame/classictimeline.cpp | 14 ++-- src/classicgame/classicviewmanager.cpp | 4 +- src/classicgame/classicviewmanager.h | 2 + src/debughelper.cpp | 89 -------------------------- 12 files changed, 62 insertions(+), 209 deletions(-) delete mode 100644 include/debughelper.h delete mode 100644 src/debughelper.cpp diff --git a/include/application.h b/include/application.h index 35b64d1..ea0d2e7 100644 --- a/include/application.h +++ b/include/application.h @@ -4,7 +4,6 @@ #include #include -#include "debughelper.h" #include "timeline.h" #include "note.h" #include "game.h" @@ -13,7 +12,6 @@ class Application { public: Application(); - ~Application(); void run(); void input(); void update(); @@ -21,13 +19,7 @@ public: private: sf::RenderWindow _game_window; - - sf::Font _font; - sf::Text _grade; - std::unique_ptr _timeline; - DebugHelper _debug; - std::unique_ptr _game; void exec(); diff --git a/include/debughelper.h b/include/debughelper.h deleted file mode 100644 index 1148642..0000000 --- a/include/debughelper.h +++ /dev/null @@ -1,47 +0,0 @@ -#ifndef DEBUGHELPER_H -#define DEBUGHELPER_H - -#include -#include -#include -#include - -using microsec = sf::Int64; - -class DebugHelper : public sf::Drawable -{ -public: - DebugHelper(bool init = true); - - void toggle(); - void update(const microsec& microseconds); - virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override; - - void spawnGreenPulse(); - void spawnRedPulse(); - void spawnBluePulse(); - -private: - bool _toggled; - sf::Font _font; - sf::Text _time_print; - - class Pulse : public sf::Drawable - { - public: - Pulse(sf::Vector2f position, sf::Color fill_color); - void appear(); - void fade(); - - virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override; - - private: - sf::RectangleShape _pulse_shape; - }; - - Pulse _red_pulse; - Pulse _green_pulse; - Pulse _blue_pulse; -}; - -#endif // DEBUGHELPER_H diff --git a/src/application.cpp b/src/application.cpp index 825e76f..0a6a774 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -7,18 +7,7 @@ const sf::Time TIME_PER_FRAME = sf::seconds(1.f / 60.f); Application::Application() : _game_window({1280, 720}, "Test"), - _debug(true), _game(std::make_unique()) -{ - _font.loadFromFile("/usr/share/qtcreator/fonts/SourceCodePro-Regular.ttf"); - _grade.setFont(_font); - _grade.setPosition(160, 160); - _grade.setFillColor(sf::Color(255, 0, 0)); - _grade.setCharacterSize(35); - _grade.setString("NOT INIT"); -} - -Application::~Application() {} void Application::run() diff --git a/src/classicgame/classicgame.cpp b/src/classicgame/classicgame.cpp index 9575f80..bcb77b9 100644 --- a/src/classicgame/classicgame.cpp +++ b/src/classicgame/classicgame.cpp @@ -8,7 +8,6 @@ ClassicGame::ClassicGame() : _timeline(std::make_unique()), _view_manager(std::make_unique()) { - _font.loadFromFile("VeraMono.ttf"); _keys_to_buttons = { {sf::Keyboard::Up, Button::UP}, // Load from settings @@ -83,25 +82,9 @@ void ClassicGame::input(const sf::Event& event) auto note = _timeline->getActiveNote(); - if (!_timeline->isExpired(note) || (*note)->state() != ClassicNote::State::DEAD) + if (!_timeline->isExpired(note) && (*note)->state() == ClassicNote::State::FLYING) { - 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); + (*note)->input(ClassicInputType(timestamp, new_action)); } } @@ -119,24 +102,9 @@ void ClassicGame::update() { _timeline->update(); _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 { _timeline->drawVisibleNotes(window); - - for (auto& grade : _grades) - { - window.draw(grade); - } } diff --git a/src/classicgame/classicgame.h b/src/classicgame/classicgame.h index 3dc00cf..95fb8e9 100644 --- a/src/classicgame/classicgame.h +++ b/src/classicgame/classicgame.h @@ -3,7 +3,6 @@ #include #include -#include #include "game.h" #include "classicactions.h" @@ -32,9 +31,6 @@ private: std::unique_ptr _timeline; std::unique_ptr _view_manager; - - sf::Font _font; - std::list _grades; }; #endif // CLASSICGAME_H diff --git a/src/classicgame/classicnote.cpp b/src/classicgame/classicnote.cpp index e327feb..2c67292 100644 --- a/src/classicgame/classicnote.cpp +++ b/src/classicgame/classicnote.cpp @@ -34,7 +34,11 @@ void ClassicNote::update(const microsec& music_offset) 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 )); + _sprite->update(getPt( xa , xb , i ), getPt( ya , yb , i )); + + if (_state == State::DYING) + if (_sprite->isDead()) + _state = State::DEAD; } void ClassicNote::draw(sf::RenderTarget& target, sf::RenderStates states) const @@ -52,7 +56,8 @@ auto ClassicNote::input(ClassicInputType&& input_data) -> Grade } std::cout << "User input: " << static_cast(grade) << "\n"; - _state = State::DEAD; + _state = State::DYING; + _sprite->showGrade(); return grade; } diff --git a/src/classicgame/classicsprite.cpp b/src/classicgame/classicsprite.cpp index 80a43ea..97d09e1 100644 --- a/src/classicgame/classicsprite.cpp +++ b/src/classicgame/classicsprite.cpp @@ -1,24 +1,53 @@ #include "classicsprite.h" #include -ClassicSprite::ClassicSprite(const sf::RectangleShape& shape) : +ClassicSprite::ClassicSprite(const sf::RectangleShape& shape, const sf::Font& font) : _shape(shape), - _trail(shape) -{} + _trail(shape), + _font(font) +{ + _grade_text.setFont(_font); +} void ClassicSprite::draw(sf::RenderTarget& target, sf::RenderStates states) const { target.draw(_shape, states); target.draw(_trail, states); + target.draw(_grade_text, states); } void ClassicSprite::setCoordinates(float x, float y, float trail_x, float trail_y) noexcept { _shape.setPosition(x, y); _trail.setPosition(trail_x, trail_y); + _grade_text.setPosition(x + _shape.getSize().x/2, y + 10); } -void ClassicSprite::setTrailCoordinates(float trail_x, float trail_y) noexcept +void ClassicSprite::update(float trail_x, float trail_y) noexcept { _trail.setPosition(trail_x, trail_y); + fade(); +} + +void ClassicSprite::showGrade() +{ + _grade_text.setFillColor(sf::Color(255, 255, 255, 255)); +} + +void ClassicSprite::fade() +{ + auto fill_color = _grade_text.getFillColor(); + + if (fill_color.a == 0) + return; + + const auto new_alpha = fill_color.a - 55; + fill_color.a = new_alpha < 0 ? 0 : new_alpha; + + _grade_text.setFillColor(fill_color); +} + +bool ClassicSprite::isDead() const +{ + return _grade_text.getFillColor().a == 0; } diff --git a/src/classicgame/classicsprite.h b/src/classicgame/classicsprite.h index 9de9f09..165e0b3 100644 --- a/src/classicgame/classicsprite.h +++ b/src/classicgame/classicsprite.h @@ -2,17 +2,23 @@ #include "sprite.h" #include "SFML/Graphics/RectangleShape.hpp" +#include "SFML/Graphics/Text.hpp" class ClassicSprite : public Sprite, public sf::Drawable { public: - ClassicSprite(const sf::RectangleShape& shape); + ClassicSprite(const sf::RectangleShape& shape, const sf::Font &font); virtual void draw(sf::RenderTarget& target, sf::RenderStates states) const override; void setCoordinates(float x, float y, float trail_x, float trail_y) noexcept; - void setTrailCoordinates(float trail_x, float trail_y) noexcept; + void update(float trail_x, float trail_y) noexcept; + void showGrade(); + void fade(); + bool isDead() const; private: sf::RectangleShape _shape; sf::RectangleShape _trail; + sf::Text _grade_text; + sf::Font _font; }; diff --git a/src/classicgame/classictimeline.cpp b/src/classicgame/classictimeline.cpp index 5ecb39a..ce1812e 100644 --- a/src/classicgame/classictimeline.cpp +++ b/src/classicgame/classictimeline.cpp @@ -79,7 +79,8 @@ void ClassicTimeline::update() void ClassicTimeline::checkCurrentActiveNote(const microsec &music_offset) { - if (!isExpired(_active_note) && !(*_active_note)->isActive(music_offset)) + if (!isExpired(_active_note) + && ((!(*_active_note)->isActive(music_offset)) || (*_active_note)->state() == ClassicNote::State::DEAD)) { expire(_active_note); ++_top_note; @@ -124,8 +125,10 @@ void ClassicTimeline::discardExpiredNotes(const std::unique_ptr sprite = (*past_note)->sprite(); while (sprite) - { // CAREFULLY REWRITE - view_manager->resetNoteSprite(*past_note); + { + auto state = (*past_note)->state(); + if (state == ClassicNote::State::DEAD || state == ClassicNote::State::FLYING) + view_manager->resetNoteSprite(*past_note); if (past_note == _timeline.begin()) return; --past_note; @@ -154,12 +157,9 @@ void ClassicTimeline::fetchVisibleNotes(const std::unique_ptrstate() == ClassicNote::State::DEAD) - { view_manager->resetNoteSprite(note); - } - else - note->update(music_offset); + note->update(music_offset); ++note_iterator; } diff --git a/src/classicgame/classicviewmanager.cpp b/src/classicgame/classicviewmanager.cpp index 86147dd..d6cb552 100644 --- a/src/classicgame/classicviewmanager.cpp +++ b/src/classicgame/classicviewmanager.cpp @@ -13,6 +13,8 @@ ClassicViewManager::ClassicViewManager() { reallocatePoll(kind_of_action); } + + _font.loadFromFile("VeraMono.ttf"); } void ClassicViewManager::reallocatePoll(Action kind_of_action) @@ -50,7 +52,7 @@ std::shared_ptr ClassicViewManager::createSprite(Action kind_of_a sprite.setFillColor(sf::Color(255, 239, 0)); } - return std::make_shared(sprite); + return std::make_shared(sprite, _font); } void ClassicViewManager::initNoteSprite(ClassicNote* note) diff --git a/src/classicgame/classicviewmanager.h b/src/classicgame/classicviewmanager.h index b5cb26a..b6e3c00 100644 --- a/src/classicgame/classicviewmanager.h +++ b/src/classicgame/classicviewmanager.h @@ -7,6 +7,7 @@ #include #include #include +#include class ClassicSprite; class ClassicNote; @@ -25,6 +26,7 @@ private: using SpritePoll = std::stack>; std::map _sprite_dispatcher; + sf::Font _font; }; #endif // CLASSICDIVAVIEWMANAGER_H diff --git a/src/debughelper.cpp b/src/debughelper.cpp deleted file mode 100644 index 3bafcbe..0000000 --- a/src/debughelper.cpp +++ /dev/null @@ -1,89 +0,0 @@ -#include "debughelper.h" - -DebugHelper::DebugHelper(bool init) : - _toggled(init), - _red_pulse({0.f, 0.f}, sf::Color(255, 0, 0)), - _green_pulse({460.f, 0.f}, sf::Color(0, 255, 0)), - _blue_pulse({460.f, 360.f}, sf::Color(0, 100, 255)) -{ - _font.loadFromFile("/usr/share/qtcreator/fonts/SourceCodePro-Regular.ttf"); - - _time_print.setFont(_font); - _time_print.setPosition(60, 60); - _time_print.setFillColor(sf::Color(255, 255, 255)); - _time_print.setCharacterSize(25); -} - -void DebugHelper::toggle() -{ - _toggled = !_toggled; -} - -void DebugHelper::update(const microsec µseconds) -{ - _time_print.setString(std::to_string(microseconds)); - - _red_pulse.fade(); - _green_pulse.fade(); - _blue_pulse.fade(); -} - -void DebugHelper::draw(sf::RenderTarget& target, sf::RenderStates states) const -{ - if (_toggled) - { - target.draw(_green_pulse, states); - target.draw(_red_pulse, states); - target.draw(_blue_pulse, states); - target.draw(_time_print, states); - } -} - -void DebugHelper::spawnGreenPulse() -{ - _green_pulse.appear(); -} - -void DebugHelper::spawnRedPulse() -{ - _red_pulse.appear(); -} - -void DebugHelper::spawnBluePulse() -{ - _blue_pulse.appear(); -} - -DebugHelper::Pulse::Pulse(sf::Vector2f position, sf::Color fill_color) -{ - _pulse_shape.setSize({480, 360}); - _pulse_shape.move(position.x, position.y); - - fill_color.a = 0; - _pulse_shape.setFillColor(fill_color); -} - -void DebugHelper::Pulse::appear() -{ - auto fill_color = _pulse_shape.getFillColor(); - fill_color.a = 255; - _pulse_shape.setFillColor(fill_color); -} - -void DebugHelper::Pulse::fade() -{ - auto fill_color = _pulse_shape.getFillColor(); - - if (fill_color.a == 0) - return; - - const auto new_alpha = fill_color.a - 25; - fill_color.a = new_alpha < 0 ? 0 : new_alpha; - - _pulse_shape.setFillColor(fill_color); -} - -void DebugHelper::Pulse::draw(sf::RenderTarget& target, sf::RenderStates states) const -{ - target.draw(_pulse_shape, states); -}