diff --git a/src/src/Components/AnimationComponent.cpp b/src/src/Components/AnimationComponent.cpp new file mode 100644 index 0000000..1c91809 --- /dev/null +++ b/src/src/Components/AnimationComponent.cpp @@ -0,0 +1,60 @@ +#include "AnimationComponent.h" +#include "Renderer.h" + +AnimationComponent::AnimationComponent(Object* owner): Component(owner) {} + +void AnimationComponent::SetTextureAtlas(const std::string& path, int cols, int rows, float duration) { + texture = std::make_shared(path); + columns = cols; + rows = rows; + totalFrames = cols * rows; + frameDuration = duration; + GenerateUVs(); +} + +void AnimationComponent::GenerateUVs() { + uvOffsets.clear(); + float frameW = 1.0f / float(columns); + float frameH = 1.0f / float(rows); + + for (int y = 0; y < rows; ++y) { + for (int x = 0; x < columns; ++x) { + uvOffsets.emplace_back(core::types::Vec2(x * frameW, y * frameH)); + } + } +} + +void AnimationComponent::Play() { playing = true; } +void AnimationComponent::Stop() { playing = false; } +void AnimationComponent::SetLooping(bool l) { loop = l; } +void AnimationComponent::SetSpeed(float s) { speed = s; } +void AnimationComponent::SetFrame(int f) { currentFrame = f % totalFrames; } + +void AnimationComponent::Update(float dt) { + if (!playing || totalFrames <= 1) return; + + time += dt * speed; + if (time >= frameDuration) { + time -= frameDuration; + currentFrame++; + + if (currentFrame >= totalFrames) { + if (loop) + currentFrame = 0; + else { + currentFrame = totalFrames - 1; + playing = false; + } + } + } +} + +void AnimationComponent::Draw() { + if (!texture) return; + + float frameW = 1.0f / float(columns); + float frameH = 1.0f / float(rows); + core::types::Vec2 uv = uvOffsets[currentFrame]; + + //Renderer::Draw(*texture, GetOwner()->GetWorldPosition(), uv, core::types::Vec2(frameW, frameH)); +} diff --git a/src/src/Components/AnimationComponent.h b/src/src/Components/AnimationComponent.h new file mode 100644 index 0000000..3355645 --- /dev/null +++ b/src/src/Components/AnimationComponent.h @@ -0,0 +1,39 @@ +#pragma once +#include "Component.h" +#include "core/types/Vec2.h" +#include +#include +#include + +class Texture; + +class AnimationComponent : public Component { +public: + AnimationComponent(Object* owner);; + + void SetTextureAtlas(const std::string& path, int cols, int rows, float frameDuration); + void Play(); + void Stop(); + void SetLooping(bool loop); + void SetSpeed(float speed); + void SetFrame(int frame); + + void Update(float dt); + void Draw(); + +private: + std::shared_ptr texture; + std::vector uvOffsets; + int columns = 1; + int rows = 1; + int totalFrames = 1; + + float frameDuration = 0.1f; + float time = 0.0f; + int currentFrame = 0; + bool playing = true; + bool loop = true; + float speed = 1.0f; + + void GenerateUVs(); +}; diff --git a/src/src/core/utils/TextureAtlas.h b/src/src/core/utils/TextureAtlas.h new file mode 100644 index 0000000..a87e750 --- /dev/null +++ b/src/src/core/utils/TextureAtlas.h @@ -0,0 +1,31 @@ +#pragma once +#include +#include "core/types/Vec2.h" + +class Texture; + +struct TextureAtlas { + std::shared_ptr texture; + int columns = 1; + int rows = 1; + + TextureAtlas() = default; + TextureAtlas(std::shared_ptr tex, int cols, int rows) + : texture(std::move(tex)), columns(cols), rows(rows) {} + + core::types::Vec2 GetFrameUV(int index) const { + float w = 1.0f / float(columns); + float h = 1.0f / float(rows); + int x = index % columns; + int y = index / columns; + return core::types::Vec2(x * w, y * h); + } + + core::types::Vec2 GetFrameSizeUV() const { + return core::types::Vec2(1.0f / float(columns), 1.0f / float(rows)); + } + + int GetTotalFrames() const { + return columns * rows; + } +};