#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()) { if (sprite.isAnimated) { 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; }