From df093323e48426e8d54a504aeae4155fa3c8e605 Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Wed, 24 Feb 2021 10:35:56 -0500 Subject: Added variable animation frame rates Lucas's climbing animation now accurately uses 60fps and looks correct finally! --- src/animation_system.cpp | 44 ++++++++++++++++++++++++++++++-------------- src/animation_system.h | 3 ++- src/sprite.h | 1 + 3 files changed, 33 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/animation_system.cpp b/src/animation_system.cpp index b57816b..baf94a4 100644 --- a/src/animation_system.cpp +++ b/src/animation_system.cpp @@ -65,13 +65,13 @@ void AnimationSystem::initSprite(int spriteId, std::string_view filename) { std::string animLine; std::getline(datafile, animLine); // blank while (std::getline(datafile, animLine)) { - std::regex re(R"(([a-z!._]+)\[([a-z_]+)\]: ([0-9,#]+))"); + std::regex re(R"(([a-z!._]+)\[([a-z_]+)\](%[0-9]+)?: ([0-9,#]+))"); std::smatch m; std::regex_match(animLine, m, re); std::string animName = m[1]; Animation anim; - auto framestrs = splitStr>(m[3], ","); + auto framestrs = splitStr>(m[4], ","); for (const std::string& f : framestrs) { int times = 1; size_t repeat_it = f.find("#"); @@ -88,6 +88,15 @@ void AnimationSystem::initSprite(int spriteId, std::string_view filename) { anim.looping = false; } + if (m[3] != "") { + int frameRate = std::stoi(std::string(m[3]).substr(1)); + switch (frameRate) { + case 5: anim.timerNum = 0; break; + case 60: anim.timerNum = 1; break; + default: throw std::invalid_argument("Invalid frame rate"); + } + } + int animId = sprite.animations.size(); sprite.animations.push_back(std::move(anim)); @@ -101,18 +110,25 @@ void AnimationSystem::initSprite(int spriteId, std::string_view filename) { void AnimationSystem::tick(double dt) { if (game_.isGameplayPaused()) return; - animTimer_.accumulate(dt); - while (animTimer_.step()) { - for (Sprite& sprite : game_.getSprites() | game_.spriteView()) { - if (sprite.isAnimated && !sprite.animFinished && !sprite.animPaused) { - sprite.animationFrame++; - - if (sprite.animationFrame >= sprite.animations[sprite.animationId].frameIndices.size()) { - if (sprite.animations[sprite.animationId].looping) { - sprite.animationFrame = 0; - } else { - sprite.animFinished = true; - sprite.animationFrame = sprite.animations[sprite.animationId].frameIndices.size() - 1; + for (int timerNum = 0; timerNum < animTimers_.size(); timerNum++) { + Timer& animTimer = animTimers_[timerNum]; + + animTimer.accumulate(dt); + while (animTimer.step()) { + for (Sprite& sprite : game_.getSprites() | game_.spriteView()) { + if (sprite.isAnimated && + sprite.animations[sprite.animationId].timerNum == timerNum && + !sprite.animFinished && + !sprite.animPaused) { + sprite.animationFrame++; + + if (sprite.animationFrame >= sprite.animations[sprite.animationId].frameIndices.size()) { + if (sprite.animations[sprite.animationId].looping) { + sprite.animationFrame = 0; + } else { + sprite.animFinished = true; + sprite.animationFrame = sprite.animations[sprite.animationId].frameIndices.size() - 1; + } } } } diff --git a/src/animation_system.h b/src/animation_system.h index a116673..c64c2dc 100644 --- a/src/animation_system.h +++ b/src/animation_system.h @@ -2,6 +2,7 @@ #define ANIMATION_SYSTEM_H_CCCC7CB8 #include +#include #include "direction.h" #include "system.h" #include "timer.h" @@ -28,7 +29,7 @@ private: void updateAnimation(int spriteId); Game& game_; - Timer animTimer_ {1000/5};//30fps * 1000 t/s;; + std::vector animTimers_ = {{1000/5}, {1000/60}};//30fps * 1000 t/s;; }; #endif /* end of include guard: ANIMATION_SYSTEM_H_CCCC7CB8 */ diff --git a/src/sprite.h b/src/sprite.h index 5750308..2bbc4ea 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -24,6 +24,7 @@ struct SpriteFrame { struct Animation { bool looping = true; std::vector frameIndices; + int timerNum = 0; }; enum class CharacterState { -- cgit 1.4.1