From ed933607765a6e010689aaaf85184053ff6e8a2b Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Sat, 13 Feb 2021 12:14:58 -0500 Subject: Added non-looping animations Lucas can get electrocuted now. --- src/animation_system.cpp | 29 +++++++++++++++++++++-------- src/renderer.cpp | 2 +- src/script_system.cpp | 3 ++- src/sprite.h | 8 +++++++- 4 files changed, 31 insertions(+), 11 deletions(-) (limited to 'src') diff --git a/src/animation_system.cpp b/src/animation_system.cpp index 997b7f7..3f3f22a 100644 --- a/src/animation_system.cpp +++ b/src/animation_system.cpp @@ -65,21 +65,26 @@ 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,]+))"); std::smatch m; std::regex_match(animLine, m, re); - std::vector frames; + std::string animName = m[1]; + Animation anim; auto framestrs = splitStr>(m[3], ","); for (const std::string& f : framestrs) { - frames.push_back(std::stoi(f)); + anim.frameIndices.push_back(std::stoi(f)); + } + + if (animName.back() == '!') { + anim.looping = false; } int animId = sprite.animations.size(); - sprite.animations.push_back(std::move(frames)); + sprite.animations.push_back(std::move(anim)); Direction dir = directionFromString(std::string(m[2])); - sprite.nameDirToAnim[m[1]][dir] = animId; + sprite.nameDirToAnim[animName][dir] = animId; } updateAnimation(spriteId); @@ -89,10 +94,17 @@ void AnimationSystem::tick(double dt) { animTimer_.accumulate(dt); while (animTimer_.step()) { for (Sprite& sprite : game_.getSprites() | game_.spriteView()) { - if (sprite.isAnimated) { + if (sprite.isAnimated && !sprite.animFinished) { sprite.animationFrame++; - if (sprite.animationFrame >= sprite.animations[sprite.animationId].size()) { - sprite.animationFrame = 0; + if (sprite.animations[sprite.animationId].looping) { + if (sprite.animationFrame >= sprite.animations[sprite.animationId].frameIndices.size()) { + sprite.animationFrame = 0; + } + } else { + if (sprite.animationFrame >= sprite.animations[sprite.animationId].frameIndices.size() - 1) { + sprite.animationFrame = sprite.animations[sprite.animationId].frameIndices.size() - 1; + sprite.animFinished = true; + } } } } @@ -119,4 +131,5 @@ void AnimationSystem::updateAnimation(int spriteId) { Sprite& sprite = game_.getSprite(spriteId); sprite.animationId = sprite.nameDirToAnim[sprite.animationName][sprite.dir]; sprite.animationFrame = 0; + sprite.animFinished = false; } diff --git a/src/renderer.cpp b/src/renderer.cpp index f07931b..a7169e9 100644 --- a/src/renderer.cpp +++ b/src/renderer.cpp @@ -130,7 +130,7 @@ void Renderer::render(Game& game) { SDL_RenderCopy(ren_.get(), textures_.at(shadowTexId).get(), nullptr, &shadowDest); } - const SpriteFrame& frame = sprite.frames.at(sprite.animations.at(sprite.animationId).at(sprite.animationFrame)); + const SpriteFrame& frame = sprite.frames.at(sprite.animations.at(sprite.animationId).frameIndices.at(sprite.animationFrame)); const SDL_Rect& src = frame.srcRect; SDL_Rect dest { sprite.loc.x() - frame.center.x(), sprite.loc.y() - frame.center.y(), frame.size.w(), frame.size.h() }; SDL_RenderCopy(ren_.get(), textures_.at(loadImageFromFile(sprite.spritesheet)).get(), &src, &dest); diff --git a/src/script_system.cpp b/src/script_system.cpp index 5b9b987..3f89290 100644 --- a/src/script_system.cpp +++ b/src/script_system.cpp @@ -16,7 +16,8 @@ ScriptSystem::ScriptSystem(Game& game) : game_(game) { "dir", &Sprite::dir, "followers", &Sprite::followers, "characterState", &Sprite::characterState, - "controllable", &Sprite::controllable); + "controllable", &Sprite::controllable, + "animFinished", &Sprite::animFinished); engine_.new_usertype( "message", diff --git a/src/sprite.h b/src/sprite.h index 84a7b03..fcf7e1d 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -16,6 +16,11 @@ struct SpriteFrame { vec2i size; }; +struct Animation { + bool looping = true; + std::vector frameIndices; +}; + enum class CharacterState { Still, Walking, @@ -48,8 +53,9 @@ public: int animationId = 0; int animationFrame = 0; std::vector frames; - std::vector> animations; + std::vector animations; std::map> nameDirToAnim; + bool animFinished = false; bool hasShadow = false; // Character -- cgit 1.4.1