#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) { 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; datafile >> sprite.spritesheet; 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 sprite.frames.clear(); 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 sprite.animations.clear(); sprite.nameDirToAnim.clear(); while (std::getline(datafile, animLine)) { 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[4], ","); for (const std::string& f : framestrs) { int times = 1; size_t repeat_it = f.find("#"); if (repeat_it != std::string::npos) { times = std::stoi(f.substr(repeat_it + 1)); } for (int i=0; i 1) { sprite.animSlowdownProgress++; if (sprite.animSlowdownProgress == sprite.animSlowdown) { sprite.animSlowdownProgress = 0; } else { continue; } } 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; } } } } } } bobbingTimer_.accumulate(dt); while (bobbingTimer_.step()) { for (Sprite& sprite : game_.getSprites() | game_.spriteView()) { if (sprite.isAnimated && sprite.bobbing) { if (sprite.bobbingDown) { sprite.bobAmount--; if (sprite.bobAmount == 0) { sprite.bobbingDown = false; } } else { sprite.bobAmount++; if (sprite.bobAmount == 4) { sprite.bobbingDown = true; } } } } } fadingTimer_.accumulate(dt); while (fadingTimer_.step()) { for (Sprite& sprite : game_.getSprites() | game_.spriteView()) { if (sprite.isAnimated) { if (sprite.shouldBeFadedIn && sprite.opacity < 1.0) { sprite.opacity += 0.05; if (sprite.opacity > 1.0) { sprite.opacity = 1.0; } } else if (!sprite.shouldBeFadedIn && sprite.opacity > 0.0) { sprite.opacity -= 0.05; if (sprite.opacity < 0.0) { sprite.opacity = 0.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; sprite.animFinished = false; sprite.animPaused = false; sprite.animSlowdownProgress = 0; }