From 06d099c11f54b5726d787f86f1ff46ac9c8c5166 Mon Sep 17 00:00:00 2001 From: NaiJi Date: Thu, 24 Jun 2021 01:43:13 +0300 Subject: [PATCH] Encapsulate animation into objects --- CMakeLists.txt | 25 +++++------ src/classicgame/classicanimationscenario.cpp | 0 src/classicgame/classicanimationscenario.h | 23 ++++++++++ .../classicdyinganimationscenario.cpp | 21 ++++++++++ .../classicdyinganimationscenario.h | 14 +++++++ .../classicflyinganimationscenario.cpp | 42 +++++++++++++++++++ .../classicflyinganimationscenario.h | 19 +++++++++ src/classicgame/classicgame.cpp | 1 - src/classicgame/classicgraphicsmanager.cpp | 5 ++- src/classicgame/classicgraphicsmanager.h | 4 +- src/classicgame/classicnote.cpp | 33 +++++++++++---- src/classicgame/classicnote.h | 17 +++++++- src/classicgame/classicsprite.cpp | 5 +++ src/classicgame/classicsprite.h | 1 + 14 files changed, 183 insertions(+), 27 deletions(-) create mode 100644 src/classicgame/classicanimationscenario.cpp create mode 100644 src/classicgame/classicanimationscenario.h create mode 100644 src/classicgame/classicdyinganimationscenario.cpp create mode 100644 src/classicgame/classicdyinganimationscenario.h create mode 100644 src/classicgame/classicflyinganimationscenario.cpp create mode 100644 src/classicgame/classicflyinganimationscenario.h diff --git a/CMakeLists.txt b/CMakeLists.txt index fab34fe..5d63dc0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,18 +15,19 @@ file(GLOB SOURCES "src/*.cpp" "src/classicgame/*.*" "src/classicgame/classicnote # STATIC # # You need to build SFML from sources with cmake -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-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-audio.so.2.5) -set(SFML_INCL_DIR ${CMAKE_SOURCE_DIR}/SFML-2.5.1/include) -include_directories(${SFML_INCL_DIR} ${CMAKE_SOURCE_DIR}/include) -add_executable(project-kyoku ${SOURCES}) -target_link_libraries(project-kyoku ${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-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-audio.so.2.5) +#set(SFML_INCL_DIR ${CMAKE_SOURCE_DIR}/SFML-2.5.1/include) +#include_directories(${SFML_INCL_DIR} ${CMAKE_SOURCE_DIR}/include) +#add_executable(project-kyoku ${SOURCES}) +#target_link_libraries(project-kyoku ${SFML_LIB_DIR}) # DYNAMIC # # You only need to install SFML from your package manager -#find_package(SFML REQUIRED graphics window system) -#add_executable(project-kyoku ${SOURCES}) -#target_link_libraries(project-kyoku sfml-system sfml-audio sfml-graphics sfml-network) +find_package(SFML REQUIRED graphics window system) +add_executable(project-kyoku ${SOURCES}) +include_directories(${SFML_INCL_DIR} ${CMAKE_SOURCE_DIR}/include) +target_link_libraries(project-kyoku sfml-system sfml-audio sfml-graphics sfml-network) diff --git a/src/classicgame/classicanimationscenario.cpp b/src/classicgame/classicanimationscenario.cpp new file mode 100644 index 0000000..e69de29 diff --git a/src/classicgame/classicanimationscenario.h b/src/classicgame/classicanimationscenario.h new file mode 100644 index 0000000..a9c1986 --- /dev/null +++ b/src/classicgame/classicanimationscenario.h @@ -0,0 +1,23 @@ +#pragma once + +#include +#include + +using microsec = sf::Int64; + +class ClassicSprite; + +class ClassicAnimationScenario +{ +public: + virtual ~ClassicAnimationScenario() = default; + + virtual void launch(const std::shared_ptr sprite, const microsec& time_begin, const microsec &time_end) = 0; + virtual void update(const microsec& music_offset) = 0; + virtual bool isDone() const = 0; + +protected: + std::shared_ptr _sprite; + microsec _time_begin; + microsec _time_end; +}; diff --git a/src/classicgame/classicdyinganimationscenario.cpp b/src/classicgame/classicdyinganimationscenario.cpp new file mode 100644 index 0000000..cae1aee --- /dev/null +++ b/src/classicgame/classicdyinganimationscenario.cpp @@ -0,0 +1,21 @@ +#include "classicdyinganimationscenario.h" +#include "classicsprite.h" + +void ClassicDyingAnimationScenario::launch(const std::shared_ptr sprite, const microsec& time_begin, const microsec &time_end) +{ + _sprite = sprite; + _time_begin = time_begin; + _time_end = time_end; + + _sprite->pulse(); +} + +void ClassicDyingAnimationScenario::update(const microsec& music_offset) +{ + _sprite->update(); +} + +bool ClassicDyingAnimationScenario::isDone() const +{ + return _sprite->isDead(); +} diff --git a/src/classicgame/classicdyinganimationscenario.h b/src/classicgame/classicdyinganimationscenario.h new file mode 100644 index 0000000..41050f4 --- /dev/null +++ b/src/classicgame/classicdyinganimationscenario.h @@ -0,0 +1,14 @@ +#ifndef CLASSICDYINGANIMATIONSCENARIO_H +#define CLASSICDYINGANIMATIONSCENARIO_H + +#include "classicanimationscenario.h" + +class ClassicDyingAnimationScenario : public ClassicAnimationScenario +{ +public: + virtual void launch(const std::shared_ptr sprite, const microsec& time_begin, const microsec& time_end) override; + virtual void update(const microsec& music_offset) override; + virtual bool isDone() const override; +}; + +#endif // CLASSICDYINGANIMATIONSCENARIO_H diff --git a/src/classicgame/classicflyinganimationscenario.cpp b/src/classicgame/classicflyinganimationscenario.cpp new file mode 100644 index 0000000..b60cb8b --- /dev/null +++ b/src/classicgame/classicflyinganimationscenario.cpp @@ -0,0 +1,42 @@ +#include "classicflyinganimationscenario.h" +#include "classicsprite.h" + +void ClassicFlyingAnimationScenario::launch(const std::shared_ptr sprite, const microsec& time_begin, const microsec &time_end) +{ + _sprite = sprite; + _time_begin = time_begin; + _time_end = time_end; + + _percentage = ((_time_end - _time_begin) * 0.01); +} + +int ClassicFlyingAnimationScenario::getPoint(float n1, float n2, float perc) const +{ + float diff = n2 - n1; + + return n1 + ( diff * perc ); +} + +void ClassicFlyingAnimationScenario::update(const microsec& music_offset) +{ + float i; + const auto crd = _sprite->coordinates(); + auto update_time = music_offset - _time_begin; + i = update_time / _percentage * 0.01; + + float xa = getPoint( crd.first + 20. , crd.first + 90. , i ); + float ya = getPoint( crd.second - 600. , crd.second - 150. , i ); + float xb = getPoint( crd.first + 90. , crd.first , i ); + float yb = getPoint( crd.second - 150. , crd.second , i ); + + _sprite->update(getPoint( xa , xb , i ), getPoint( ya , yb , i )); + if (i >= 1) + { + _sprite->trailFade(); + } +} + +bool ClassicFlyingAnimationScenario::isDone() const +{ + return false; +} diff --git a/src/classicgame/classicflyinganimationscenario.h b/src/classicgame/classicflyinganimationscenario.h new file mode 100644 index 0000000..7f5d79c --- /dev/null +++ b/src/classicgame/classicflyinganimationscenario.h @@ -0,0 +1,19 @@ +#ifndef CLASSICFLYINGANIMATIONSCENARIO_H +#define CLASSICFLYINGANIMATIONSCENARIO_H + +#include "classicanimationscenario.h" + +class ClassicFlyingAnimationScenario : public ClassicAnimationScenario +{ +public: + virtual void launch(const std::shared_ptr sprite, const microsec& time_begin, const microsec& time_end) override; + virtual void update(const microsec& music_offset) override; + virtual bool isDone() const override; + +private: + int getPoint(float n1, float n2, float perc) const; + + float _percentage; +}; + +#endif // CLASSICFLYINGANIMATIONSCENARIO_H diff --git a/src/classicgame/classicgame.cpp b/src/classicgame/classicgame.cpp index a167db7..3039828 100644 --- a/src/classicgame/classicgame.cpp +++ b/src/classicgame/classicgame.cpp @@ -1,7 +1,6 @@ #include "classicgame.h" #include "classictimeline.h" #include "classicmapcreator.h" -#include "classicnote.h" ClassicGame::ClassicGame(std::unique_ptr&& manager) : _timeline(std::make_unique()), diff --git a/src/classicgame/classicgraphicsmanager.cpp b/src/classicgame/classicgraphicsmanager.cpp index e09a550..943e006 100644 --- a/src/classicgame/classicgraphicsmanager.cpp +++ b/src/classicgame/classicgraphicsmanager.cpp @@ -8,12 +8,13 @@ ClassicGraphicsManager::ClassicGraphicsManager(sf::RenderTarget& target) : _render_target(target) {} -void ClassicGraphicsManager::initSprite(ClassicNote* note) +void ClassicGraphicsManager::initGraphics(ClassicNote* note) { note->setSprite(_sprite_container.getSprite(note->type())); + note->sprite()->setCoordinates(note->getCoordinates().x, note->getCoordinates().y, 0, 0); } -void ClassicGraphicsManager::resetSprite(ClassicNote* note) +void ClassicGraphicsManager::resetGraphics(ClassicNote* note) { _sprite_container.resetSprite(note->sprite(), note->type()); } diff --git a/src/classicgame/classicgraphicsmanager.h b/src/classicgame/classicgraphicsmanager.h index 842825e..f21f885 100644 --- a/src/classicgame/classicgraphicsmanager.h +++ b/src/classicgame/classicgraphicsmanager.h @@ -14,8 +14,8 @@ class ClassicGraphicsManager public: explicit ClassicGraphicsManager(sf::RenderTarget& target); - void initSprite(ClassicNote* note); - void resetSprite(ClassicNote* note); + void initGraphics(ClassicNote* note); + void resetGraphics(ClassicNote* note); void draw(const ClassicNote *note); private: diff --git a/src/classicgame/classicnote.cpp b/src/classicgame/classicnote.cpp index 270c615..32695ac 100644 --- a/src/classicgame/classicnote.cpp +++ b/src/classicgame/classicnote.cpp @@ -1,6 +1,8 @@ #include "classicnote.h" #include "classicsprite.h" -#include +#include "classicgraphicsmanager.h" +#include "classicflyinganimationscenario.h" +#include "classicdyinganimationscenario.h" #include ClassicNote::ClassicNote(const std::vector& intervals, microsec perfect_offset, @@ -8,10 +10,16 @@ ClassicNote::ClassicNote(const std::vector& intervals, microsec perfec Note(perfect_offset), _coordinates(coord), _evaluator(intervals, _perfect_offset), + _keys({sf::Keyboard::W, sf::Keyboard::Up}), _graphics_manager(manager), _is_expired(true), - _type(type) -{} + _type(type), + _state(State::NONE) +{ + _animations[State::NONE] = nullptr; + _animations[State::FLYING] = std::make_shared(); + _animations[State::DYING] = std::make_shared(); +} bool ClassicNote::isActive(const microsec &music_offset) const { @@ -21,9 +29,9 @@ bool ClassicNote::isActive(const microsec &music_offset) const void ClassicNote::putToGame(const microsec &music_offset) { _is_expired = false; - _graphics_manager->initSprite(this); (void) music_offset; - //_appearance_time = music_offset; // To animation manager - //_trail_path_percent = ((_perfect_offset - _appearance_time) * 0.01); + _graphics_manager->initGraphics(this); + _state = State::FLYING; + _animations[_state]->launch(_sprite, music_offset, offset()); } bool ClassicNote::isExpired() const @@ -33,13 +41,19 @@ bool ClassicNote::isExpired() const void ClassicNote::update(const microsec& music_offset) { + if (!_animations[_state]) + return; + bool is_not_active_anymore = (!_is_expired && !isActive(music_offset)); if (is_not_active_anymore) { - _graphics_manager->resetSprite(this); - _is_expired = true; + _state = State::DYING; + _animations[_state]->launch(_sprite, music_offset, offset()); } + + _animations[_state]->update(music_offset); + _is_expired = _animations[_state]->isDone(); } void ClassicNote::input(PlayerInput&& inputdata) @@ -49,6 +63,9 @@ void ClassicNote::input(PlayerInput&& inputdata) if (std::find(_keys.begin(), _keys.end(), inputdata.event.key.code) != _keys.end()) grade = _evaluator.calculatePrecision(inputdata.timestamp); + _state = State::DYING; + _animations[_state]->launch(_sprite, inputdata.timestamp, offset()); + std::cout << "User input: " << static_cast(grade) << "\n"; } diff --git a/src/classicgame/classicnote.h b/src/classicgame/classicnote.h index 3a05d58..c0d1299 100644 --- a/src/classicgame/classicnote.h +++ b/src/classicgame/classicnote.h @@ -2,7 +2,7 @@ #include "note.h" #include "precisionevaluator.h" -#include "classicgraphicsmanager.h" +#include "classicactions.h" #include #include @@ -19,6 +19,8 @@ struct Coordinates }; // MOVE TO OWN HEADER ^ class ClassicSprite; +class ClassicGraphicsManager; +class ClassicAnimationScenario; class ClassicNote : public Note { @@ -31,6 +33,14 @@ public: BAD }; + enum State + { + NONE, + + FLYING, + DYING + }; + explicit ClassicNote(const std::vector& intervals, microsec perfect_offset, Type type, const Coordinates& coord, const std::unique_ptr& manager); @@ -52,11 +62,14 @@ public: private: const Coordinates _coordinates; const PrecisionEvaluator _evaluator; + const std::array _keys; const std::unique_ptr& _graphics_manager; std::shared_ptr _sprite; bool _is_expired; - std::array _keys; const Type _type; + + State _state; + std::array, 3> _animations; }; diff --git a/src/classicgame/classicsprite.cpp b/src/classicgame/classicsprite.cpp index d28d05f..a0f26fb 100644 --- a/src/classicgame/classicsprite.cpp +++ b/src/classicgame/classicsprite.cpp @@ -36,6 +36,11 @@ void ClassicSprite::setCoordinates(float x, float y, float trail_x, float trail_ _grade_text.setPosition(x + _shape.getSize().x/2, y + 10); } +std::pair ClassicSprite::coordinates() const +{ + return std::make_pair(_shape.getPosition().x, _shape.getPosition().y); +} + void ClassicSprite::update(float trail_x, float trail_y) noexcept { _trail.setPosition(trail_x, trail_y); diff --git a/src/classicgame/classicsprite.h b/src/classicgame/classicsprite.h index 9820925..e4ebed0 100644 --- a/src/classicgame/classicsprite.h +++ b/src/classicgame/classicsprite.h @@ -12,6 +12,7 @@ public: virtual void reset() override; void setCoordinates(float x, float y, float trail_x, float trail_y) noexcept; + std::pair coordinates() const; void update(float trail_x, float trail_y) noexcept; void update() noexcept;