From be09120d1d044b476ef8b516efbdb526f20d9e2d Mon Sep 17 00:00:00 2001 From: Kelly Rauchenberger Date: Wed, 3 Feb 2021 01:35:58 -0500 Subject: Added animation system --- src/animation_system.cpp | 122 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 122 insertions(+) create mode 100644 src/animation_system.cpp (limited to 'src/animation_system.cpp') diff --git a/src/animation_system.cpp b/src/animation_system.cpp new file mode 100644 index 0000000..3320e1d --- /dev/null +++ b/src/animation_system.cpp @@ -0,0 +1,122 @@ +#include "animation_system.h" +#include +#include +#include +#include "game.h" +#include "vector.h" +#include "util.h" + +void AnimationSystem::initSprite(int spriteId, std::string_view filename, Renderer& renderer) { + std::ifstream datafile(filename.data()); + if (!datafile.is_open()) { + throw std::invalid_argument(std::string("Could not find sprite datafile: ") + std::string(filename)); + } + + Sprite& sprite = game_.getSprite(spriteId); + sprite.isAnimated = true; + + char ch; + std::string line; + + std::string imagename; + datafile >> imagename; + sprite.textureId = renderer.loadImageFromFile(imagename); + + std::string framefilename; + datafile >> framefilename; + + std::ifstream framefile(framefilename); + if (!framefile.is_open()) { + throw std::invalid_argument("Could not find frame datafile: " + framefilename); + } + + vec2i cellSize; + framefile >> cellSize.w(); + framefile >> ch; //, + framefile >> cellSize.h(); + std::getline(framefile, line); // cell size + + int framesPerRow; + framefile >> framesPerRow; + std::getline(framefile, line); // frames per row + + int numFrames; + framefile >> numFrames; + std::getline(framefile, line); // frames + std::getline(framefile, line); // blank + + for (int i=0; i> f.size.w(); + framefile >> ch; //, + framefile >> f.size.h(); + framefile >> ch; //, + framefile >> f.center.x(); + framefile >> ch; //, + framefile >> f.center.y(); + std::getline(framefile, line); // blank + + f.srcRect.x = (i % framesPerRow) * cellSize.w(); + f.srcRect.y = (i / framesPerRow) * cellSize.h(); + f.srcRect.w = f.size.w(); + f.srcRect.h = f.size.h(); + + sprite.frames.push_back(std::move(f)); + } + + std::string animLine; + std::getline(datafile, animLine); // blank + while (std::getline(datafile, animLine)) { + std::regex re(R"(([a-z]+)\[([a-z_]+)\]: ([0-9,]+))"); + std::smatch m; + std::regex_match(animLine, m, re); + + std::vector frames; + auto framestrs = splitStr>(m[3], ","); + for (const std::string& f : framestrs) { + frames.push_back(std::stoi(f)); + } + + int animId = sprite.animations.size(); + sprite.animations.push_back(std::move(frames)); + + Direction dir = directionFromString(std::string(m[2])); + sprite.nameDirToAnim[m[1]][dir] = animId; + } + + updateAnimation(spriteId); +} + +void AnimationSystem::tick(double dt) { + animTimer_.accumulate(dt); + while (animTimer_.step()) { + for (Sprite& sprite : game_.getSprites() | game_.spriteView()) { + sprite.animationFrame++; + if (sprite.animationFrame >= sprite.animations[sprite.animationId].size()) { + sprite.animationFrame = 0; + } + } + } +} + +void AnimationSystem::setSpriteDirection(int spriteId, Direction dir) { + Sprite& sprite = game_.getSprite(spriteId); + if (sprite.dir != dir) { + sprite.dir = dir; + updateAnimation(spriteId); + } +} + +void AnimationSystem::setSpriteAnimation(int spriteId, std::string_view name) { + Sprite& sprite = game_.getSprite(spriteId); + if (sprite.animationName != name) { + sprite.animationName = name; + updateAnimation(spriteId); + } +} + +void AnimationSystem::updateAnimation(int spriteId) { + Sprite& sprite = game_.getSprite(spriteId); + sprite.animationId = sprite.nameDirToAnim[sprite.animationName][sprite.dir]; + sprite.animationFrame = 0; +} -- cgit 1.4.1