From 82598dbaac1bc99a0a4f99833b68915ffbec0495 Mon Sep 17 00:00:00 2001 From: Ekaitz Zarraga Date: Thu, 17 Nov 2022 16:59:15 +0100 Subject: Simplify animations --- src/graphics/animation.cpp | 145 +++++++++++++++------------------------------ src/graphics/animation.h | 70 ++++++---------------- src/main.cpp | 56 +++++------------ 3 files changed, 82 insertions(+), 189 deletions(-) diff --git a/src/graphics/animation.cpp b/src/graphics/animation.cpp index f311cf0..828772c 100644 --- a/src/graphics/animation.cpp +++ b/src/graphics/animation.cpp @@ -1,118 +1,69 @@ #include "animation.h" -#include +#include namespace Graphics{ - // Basic animation, loops through the pictures Animation::Animation(){} - Animation::Animation(const sf::Texture& texture, int count, int switchTime, - int height = 0, int width = 0, int row = 0) : - i_ (0), - count_ (count), - row_ (row), - lastTime_ (0), - switchTime_ (switchTime){ - - sf::Vector2u size = texture_.getSize(); - if ( height == 0 ){ - h_ = size.y; - } else { - h_ = height; - } - - if ( width == 0 ){ - if (size.x % count != 0){ - printf("Animation: size not divisible by %d\n", count); - } - w_ = size.x / count_; - } else { - w_ = width; + Animation::Animation(const sf::Texture& texture, std::size_t count, + sf::Time duration, bool repeat) + : numFrames_ (count) + , currentFrame_(0) + , duration_(duration) + , elapsedTime_(sf::Time::Zero) + , repeat_ (repeat) + { + sprite_.setTexture(texture); + sf::Vector2u size = texture.getSize(); + + if (size.x % numFrames_ != 0){ + throw ("Animation: size not divisible by " + std::to_string(count)); } + frameSize_.x = static_cast(size.x / count); + frameSize_.y = size.y; - rect_ = sf::IntRect(0,row_ * h_,w_,h_); // set to first picture in - // animation + sprite_.setTextureRect( sf::IntRect(0,0,frameSize_.x,frameSize_.y) ); } - bool Animation::ticked(int deltaTime){ - lastTime_ += deltaTime; - if ( switchTime_ > lastTime_ ){ - return false; - } - lastTime_ = 0; - return true; - } + void Animation::update(sf::Time deltaTime){ + sf::Time timePerFrame = duration_ / static_cast(numFrames_); + elapsedTime_ += deltaTime; - sf::IntRect& Animation::next(int deltaTime){ - if ( !ticked(deltaTime) ){ - return rect_; - } - if (i_ < count_ -1 ){ - i_ += 1; - } else { - i_ = 0; - } - rect_.left = i_ * w_; - - return rect_; - } - - void Animation::reset(){ - i_ = 0; - rect_.left = i_ * w_; - rect_.top = row_ * h_; - } - - bool Animation::finished(){ - return false; - } - Animation::~Animation(){} + while (elapsedTime_ > timePerFrame ){ - // ONESHOT ANIMATION - bool OneShotAnimation::finished(){ - return (i_ == count_ - 1); - } - - sf::IntRect& OneShotAnimation::next(int deltaTime){ - if ( !ticked(deltaTime) ){ - return rect_; - } - if ( finished() ){ - return rect_; - } - if (i_ < count_ -1 ){ - i_ += 1; - } - rect_.left = i_ * w_; - - return rect_; - } - - // BOUNCING ANIMATION - sf::IntRect& BouncingAnimation::next(int deltaTime){ - if( !ticked(deltaTime) ) { - return rect_; - } - // Rewrite this and eliminate the boolean (use the count as - // positive/negative) - if ( up_ ) { - if( i_ == count_ - 1){ - up_ = false; + if(currentFrame_ == numFrames_ - 1){ + if (repeat_) { + currentFrame_ = 0; + } else { + return; + } } else { - i_++; - } - } else { - i_--; - if( i_ == 0 ){ - up_ = true; + currentFrame_ ++; } + elapsedTime_ -= timePerFrame; + sprite_.setTextureRect( + sf::IntRect( + currentFrame_ * frameSize_.x, + 0, + frameSize_.x, + frameSize_.y) + ); } - rect_.left = i_ * w_; + } - return rect_; + void Animation::draw(sf::RenderTarget& target, sf::RenderStates states) + const{ + target.draw(sprite_, states); + } + void Animation::reset(){ + currentFrame_ = 0; + elapsedTime_ = sf::Time::Zero; + sprite_.setTextureRect( sf::IntRect(0,0,frameSize_.x,frameSize_.y) ); } - BouncingAnimation::~BouncingAnimation(){} + bool Animation::finished() const{ + return (!repeat_ && currentFrame_ == numFrames_ - 1) ; + } } diff --git a/src/graphics/animation.h b/src/graphics/animation.h index 583da8a..04bf9ff 100644 --- a/src/graphics/animation.h +++ b/src/graphics/animation.h @@ -2,65 +2,31 @@ #define GRAPHICS_ANIMATION_H #include +#include namespace Graphics{ - class Animation{ + class Animation : public sf::Drawable, sf::Transformable{ protected: - int i_; - int count_; - int row_; - int lastTime_; - int switchTime_; - unsigned int w_, h_; - sf::IntRect rect_; - sf::Texture texture_; - bool ticked(int deltaTime); - public: - Animation(); - ~Animation(); - Animation(const sf::Texture& texture, int count, int switchTime, - int height, int width, int row); - virtual sf::IntRect& next(int deltaTime); - virtual void reset(); - virtual bool finished(); - static sf::Sprite& flip(sf::Sprite &sprite){ - sf::IntRect frame = sprite.getTextureRect(); - frame.left += frame.width; - frame.width *= -1; - sprite.setTextureRect(frame); - return sprite; - }; - }; + sf::Sprite sprite_; + sf::Vector2i frameSize_; + std::size_t numFrames_; + std::size_t currentFrame_; + std::size_t row_; + sf::Time duration_; + sf::Time elapsedTime_; + bool repeat_; - class OneShotAnimation : public Animation { public: - using Animation::Animation; - virtual sf::IntRect& next(int deltaTime) override; - bool finished() override; - }; - - class BouncingAnimation : public Animation{ - private: - bool up_; - public: - using Animation::Animation; - ~BouncingAnimation(); - virtual sf::IntRect& next(int deltaTime) override; + Animation(); + Animation(const sf::Texture& texture, std::size_t count, + sf::Time duration, bool repeat = false); + void update(sf::Time deltaTime); + void draw(sf::RenderTarget& target, sf::RenderStates states) + const override; + void reset(); + bool finished() const; }; - template - class FlippedAnimation : public T{ - static_assert(std::is_base_of::value, - "Base class of FlippedAnimation is not an Animation"); - public: - using T::T; - sf::IntRect& next(int deltaTime) override{ - T::next(deltaTime); - T::rect_.left = (T::i_ + 1) * T::w_; - T::rect_.width = -T::w_; - return T::rect_; - } - }; } #endif // GRAPHICS_ANIMATION_H diff --git a/src/main.cpp b/src/main.cpp index bd330fc..02697d7 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,20 +14,8 @@ class Unit: Entity{ sf::Texture spritesheet_; public: - enum class Anim : int{ - standing = 0, - walking = 1, - shooting = 2, - complaining = 3, - dying = 4, - }; - std::vector animation_frame_count { 6, 8, 6, 1, 14 }; - gph::Animation walking_animation; - gph::Animation standing_animation; - gph::FlippedAnimation shooting_animation; - gph::OneShotAnimation complaining_animation; - gph::OneShotAnimation dying_animation; - gph::Animation* current_animation = &standing_animation; + gph::Animation dying_animation; + gph::Animation& current_animation = dying_animation; sf::Sprite sprite; sf::Vector2f position; @@ -37,11 +25,8 @@ class Unit: Entity{ Unit(sf::Texture& spritesheet){ spritesheet_ = spritesheet; - standing_animation = gph::Animation(spritesheet_, 6, 60, 44, 48, 0); - walking_animation = gph::Animation(spritesheet_, 8, 60, 44, 48, 1); - shooting_animation = gph::FlippedAnimation(spritesheet_, 6, 60, 44, 48, 2); - complaining_animation = gph::OneShotAnimation(spritesheet_, 1, 60, 44, 48, 3); - dying_animation = gph::OneShotAnimation(spritesheet_, 14, 60, 44, 48, 4); + dying_animation = gph::Animation(spritesheet_, 14, sf::milliseconds(1400), false); + current_animation = dying_animation; position = sf::Vector2f{0,0}; speed = sf::Vector2f{0,0}; @@ -49,25 +34,16 @@ class Unit: Entity{ void walk(float vx, float vy){ speed.y = vy; speed.x = vx; - current_animation->reset(); - current_animation = &walking_animation; + current_animation.reset(); + // current_animation = &walking_animation; } void shoot(){ - current_animation->reset(); - current_animation = &shooting_animation; + current_animation.reset(); + // current_animation = &shooting_animation; } ~Unit(){}; - void update(int dt){ - //if (current_animation->finished()){ - // current_animation->reset(); - // current_animation = &standing_animation; - //} - position.x += round(speed.x * dt); - sprite.setTexture(spritesheet_); - sprite.setScale(8,8); - sprite.setTextureRect(current_animation->next(dt)); - sprite.setPosition(position.x, position.y); - sprite = sprite; + void update(sf::Time dt){ + current_animation.update( dt); } }; @@ -88,17 +64,17 @@ int main() sf::Clock clock; ResourceManager TextureManager; - TextureManager.load( TextureId::Angle1, "assets/img/Player/Player Angle 1 Sheet.png"); + TextureManager.load( TextureId::Angle1, "assets/img/Player/angle1-dying.png"); Unit unit = Unit(TextureManager.get(TextureId::Angle1)); renderWindow.setFramerateLimit(60); - long elapsed_time = 0; + sf::Time elapsed_time = sf::Time::Zero; bool once = true; while (renderWindow.isOpen()){ - int dt = clock.getElapsedTime().asMilliseconds(); + sf::Time dt = clock.getElapsedTime(); elapsed_time += dt; clock.restart(); while (renderWindow.pollEvent(event)){ @@ -106,15 +82,15 @@ int main() renderWindow.close(); } - if(elapsed_time > 1000 && once){ - unit.shoot(); + if(elapsed_time > sf::milliseconds(4000) && once){ + unit.current_animation.reset(); once = false; } unit.update(dt); renderWindow.clear(); - renderWindow.draw(unit.sprite); + renderWindow.draw(unit.current_animation); renderWindow.display(); } } -- cgit v1.2.3