Reworked the Animation class

This commit is contained in:
OmniaX-Dev 2026-04-17 17:04:19 +02:00
parent 91fc3e75b9
commit ed3c21bd36
5 changed files with 241 additions and 263 deletions

View file

@ -120,7 +120,7 @@ window.backgroundColor = rgba(160, 160, 160, 255)
% ====== Label ====== % ====== Button ======
(button) { (button) {
textColor = $textColor textColor = $textColor
backgroundColor = #999999FF backgroundColor = #999999FF
@ -135,6 +135,8 @@ window.backgroundColor = rgba(160, 160, 160, 255)
padding = rect(15, 8, 15, 8) padding = rect(15, 8, 15, 8)
margin = rect(0, 0, 0, 0) margin = rect(0, 0, 0, 0)
icon = file("img.png") icon = file("img.png")
showIcon = true
iconANimation = anim(
} }
(button:hover) { (button:hover) {
borderColor = $accentColor borderColor = $accentColor
@ -145,4 +147,4 @@ window.backgroundColor = rgba(160, 160, 160, 255)
textColor = #DDDDDDFF textColor = #DDDDDDFF
backgroundGradient = gradientV(rgb(120, 120, 120) - rgb(160, 160, 160)) backgroundGradient = gradientV(rgb(120, 120, 120) - rgb(160, 160, 160))
} }
% =================== % ====================

View file

@ -1,117 +1,85 @@
/* /*
OmniaFramework - A collection of useful functionality OmniaFramework - A collection of useful functionality
Copyright (C) 2025 OmniaX-Dev Copyright (C) 2025 OmniaX-Dev
This file is part of OmniaFramework. This file is part of OmniaFramework.
OmniaFramework is free software: you can redistribute it and/or modify OmniaFramework is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
OmniaFramework is distributed in the hope that it will be useful, OmniaFramework is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>. along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>.
*/ */
#include "Animation.hpp" #include "Animation.hpp"
#include "../../ostd/math/Random.hpp" #include "../../ostd/math/Random.hpp"
namespace ogfx namespace ogfx
{ {
Animation::Animation(void) Animation& Animation::create(const AnimationData& ad, Image& spriteSheet)
{ {
create(0, 0, 0, 0, 0); m_animData = ad;
} m_spriteSheet = &spriteSheet;
m_timer.create(m_animData.fps, [&](f64 dt) -> void {
Animation::Animation(i32 frames, i32 columns, i32 rows, i32 frame_width, i32 frame_height) update_animation();
{ });
create(frames, columns, rows, frame_width, frame_height); return *this;
} }
Animation::Animation(AnimationData& ad) void Animation::resetAnimation(void)
{ {
create(ad); m_currentFrame = 0;
} }
void Animation::create(AnimationData& ad) void Animation::update_animation(void)
{ {
create(ad.length, ad.columns, ad.rows, ad.frame_width, ad.frame_height); if (!m_animData.still)
m_backwards = ad.backwards; {
m_still = ad.still; if (m_animData.random)
m_column_offset = ad.column_offset; {
m_row_offset = ad.row_offset; m_currentFrame = ostd::Random::geti32(0, m_animData.frameCount);
m_frame_time = ad.speed; }
m_random = false; else if (m_animData.turnBack)
} {
if (!m_back && m_currentFrame >= m_animData.frameCount - 1)
void Animation::create(i32 frames, i32 columns, i32 rows, i32 frame_width, i32 frame_height) {
{ m_back = true;
m_frames = frames; m_currentFrame--;
m_columns = columns; }
m_frame_width = frame_width; else if (!m_back)
m_frame_height = frame_height; m_currentFrame++;
m_rows = rows; else if (m_back && m_currentFrame <= 0)
m_frame_time = 5; {
m_current_time = 0; m_back = false;
m_current_frame = 0; m_currentFrame++;
m_backwards = false; }
m_back = false; else if (m_back)
m_still = false; m_currentFrame--;
m_random = false; }
m_column_offset = 0; else
m_row_offset = 0; {
} if (m_currentFrame++ >= m_animData.frameCount - 1)
m_currentFrame = 0;
void Animation::resetAnimation(void) }
{ }
m_current_frame = 0; else if (m_animData.still)
m_current_time = 0; {
} if (m_animData.stillFrame >= 0 && m_animData.stillFrame < m_animData.frameCount)
m_currentFrame = m_animData.stillFrame;
void Animation::update(void) else
{ m_currentFrame = 0;
if (m_current_time++ > m_frame_time && !m_still) }
{ i32 x = m_animData.pixelOffsetX + (((m_currentFrame % m_animData.columns) + m_animData.columnOffset) * m_animData.frameWidth);
m_current_time = 0; i32 y = m_animData.pixelOffsetY + (m_animData.rowOffset * m_animData.frameHeight);
if (m_random) if (m_animData.rows > 1)
{ y = m_animData.pixelOffsetY + ((cast<i32>(m_currentFrame / m_animData.columns) + m_animData.rowOffset) * m_animData.frameHeight);
m_current_frame = ostd::Random::geti32(0, m_frames); m_frameRect = { cast<f32>(x), cast<f32>(y), m_animData.frameWidth, m_animData.frameHeight };
} }
else if (m_backwards) }
{
if (!m_back && m_current_frame >= m_frames - 1)
{
m_back = true;
m_current_frame--;
}
else if (!m_back)
m_current_frame++;
else if (m_back && m_current_frame <= 0)
{
m_back = false;
m_current_frame++;
}
else if (m_back)
m_current_frame--;
}
else
{
if (m_current_frame++ >= m_frames - 1)
m_current_frame = 0;
}
}
else if (m_still)
m_current_frame = 1; //TODO: Hardcoded value
i32 x = ((m_current_frame % m_columns) + m_column_offset) * m_frame_width;
i32 y = m_row_offset * m_frame_height;
if (m_rows > 1)
y = ((m_current_frame / m_columns) + m_row_offset) * m_frame_height;
m_frame_rect = { cast<f32>(x), cast<f32>(y), cast<f32>(m_frame_width), cast<f32>(m_frame_height) };
}
}

View file

@ -1,119 +1,130 @@
/* /*
OmniaFramework - A collection of useful functionality OmniaFramework - A collection of useful functionality
Copyright (C) 2025 OmniaX-Dev Copyright (C) 2025 OmniaX-Dev
This file is part of OmniaFramework. This file is part of OmniaFramework.
OmniaFramework is free software: you can redistribute it and/or modify OmniaFramework is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or the Free Software Foundation, either version 3 of the License, or
(at your option) any later version. (at your option) any later version.
OmniaFramework is distributed in the hope that it will be useful, OmniaFramework is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>. along with OmniaFramework. If not, see <https://www.gnu.org/licenses/>.
*/ */
#pragma once #pragma once
#include <ostd/data/Types.hpp> #include <ostd/data/Types.hpp>
#include <ostd/math/Geometry.hpp> #include <ostd/math/Geometry.hpp>
#include <ogfx/resources/Image.hpp> #include <ostd/utils/Time.hpp>
#include <ogfx/resources/Image.hpp>
namespace ogfx
{ namespace ogfx
class Animation {
{ class Animation
public: struct AnimationData { {
i32 length; public: struct AnimationData : public ostd::__i_stringeable {
i32 speed; i32 frameCount { 1 };
i32 still_frame; i32 stillFrame { 0 };
f64 fps { 60.0 };
i32 row_offset;
i32 column_offset; i32 rowOffset { 0 };
i32 columnOffset { 0 };
i32 rows; f32 pixelOffsetX { 0.0f };
i32 columns; f32 pixelOffsetY { 0.0f };
i32 rows { 1 };
i32 frame_width; i32 columns { 1 };
i32 frame_height; f32 frameWidth{ 32 };
f32 frameHeight { 32 };
bool still;
bool backwards; bool still { false };
bool random; bool turnBack { false };
bool random { false };
AnimationData(void)
{ inline String toString(void) const override
length = 3; {
speed = 10; String str = "";
row_offset = 0; str.add("AnimData {");
column_offset = 0; str.add(" ").add("frameCount: ").add(frameCount).add(",\n");
rows = 1; str.add(" ").add("stillFrame: ").add(stillFrame).add(",\n");
columns = 3; str.add(" ").add("rowOffset: ").add(rowOffset).add(",\n");
frame_width = 32; str.add(" ").add("columnOffset: ").add(columnOffset).add(",\n");
frame_height = 32; str.add(" ").add("pixelOffsetX: ").add(pixelOffsetX, 2).add(",\n");
still = false; str.add(" ").add("pixelOffsetY: ").add(pixelOffsetY, 2).add(",\n");
backwards = true; str.add(" ").add("rows: ").add(rows).add(",\n");
random = false; str.add(" ").add("columns: ").add(columns).add(",\n");
still_frame = 1; str.add(" ").add("frameWidth: ").add(frameWidth, 2).add(",\n");
} str.add(" ").add("frameHeight: ").add(frameHeight, 2).add(",\n");
}; str.add(" ").add("still: ").add(STR_BOOL(still)).add(",\n");
public: str.add(" ").add("turnBack: ").add(STR_BOOL(turnBack)).add(",\n");
Animation(void); str.add(" ").add("random: ").add(STR_BOOL(random)).add(",\n");
Animation(i32 frames, i32 columns, i32 rows, i32 frame_width, i32 frame_height); str.add("}");
Animation(AnimationData& ad); return str;
void create(i32 frames, i32 columns, i32 rows, i32 frame_width, i32 frame_height); }
void create(AnimationData& ad); };
void update(void); public:
void resetAnimation(void); inline Animation(void) { }
inline Animation(const AnimationData& ad) { create(ad); };
inline void setFrameNumber(i32 n) { m_frames = n; } inline Animation(const AnimationData& ad, Image& spriteSheet) { create(ad, spriteSheet); };
inline void setColumnNumber(i32 n) { m_columns = n; } inline Animation& create(const AnimationData& ad) { return create(ad, InvalidImage); }
inline void setBackwards(bool b) { m_backwards = b; } inline void update(void) { m_timer.update(); }
inline void setSpeed(i32 d) { m_frame_time = d; } Animation& create(const AnimationData& ad, Image& spriteSheet);
inline void setColumnOffset(i32 o) { m_column_offset = o; } void resetAnimation(void);
inline void setRowOffset(i32 o) { m_row_offset = o; }
inline void setStill(bool s) { m_still = s; } inline void setFrameCount(i32 n) { m_animData.frameCount = n; }
inline void setSpriteSheet(Image& img) { m_spriteSheet = &img; } inline void setStillFrame(i32 n) { m_animData.stillFrame = n; }
inline void setColumnOffset(i32 o) { m_animData.columnOffset = o; }
inline i32 getFrameNumber(void) const { return m_frames; } inline void setRowOffset(i32 o) { m_animData.rowOffset = o; }
inline i32 getColumnNumber(void) const { return m_columns; } inline void setPixelOffsetX(f32 o) { m_animData.pixelOffsetX = o; }
inline bool getBackwards(void) const { return m_backwards; } inline void setPixelOffsetY(f32 o) { m_animData.pixelOffsetY = o; }
inline i32 getDelay(void) const { return m_frame_time; } inline void setNRows(i32 n) { m_animData.rows = n; }
inline i32 getColumnOffset(void) const { return m_column_offset; } inline void setNColumns(i32 n) { m_animData.columns = n; }
inline i32 getRowOffset(void) const { return m_row_offset; } inline void setFrameWidth(i32 f) { m_animData.frameWidth = f; }
inline bool isStill(void) const { return m_still; } inline void setFrameHeight(i32 f) { m_animData.frameHeight = f; }
inline Rectangle getFrameRect(void) const { return m_frame_rect; } inline void enableStill(bool b = true) { m_animData.still = b; }
inline const Image& getSpriteSheet(void) const { return (m_spriteSheet != nullptr ? *m_spriteSheet : InvalidImage); } inline void enableTurnBack(bool b = true) { m_animData.turnBack = b; }
inline Image& getSpriteSheet(void) { return (m_spriteSheet != nullptr ? *m_spriteSheet : InvalidImage); } inline void enableRandom(bool b = true) { m_animData.random = b; }
inline bool hasImage(void) const { return m_spriteSheet != nullptr; }
inline i32 getFrameCount(void) { return m_animData.frameCount; }
private: inline i32 getStillFrame(void) { return m_animData.stillFrame; }
Image* m_spriteSheet { nullptr }; inline f64 getFPS(void) { return m_animData.fps; }
inline static Image InvalidImage; inline i32 getColumnOffset(void) { return m_animData.columnOffset; }
inline i32 getRowOffset(void) { return m_animData.rowOffset; }
i32 m_frames; inline f32 getPixelOffsetX(void) { return m_animData.pixelOffsetX; }
i32 m_rows; inline f32 getPixelOffsetY(void) { return m_animData.pixelOffsetY; }
i32 m_columns; inline i32 getNRows(void) { return m_animData.rows; }
i32 m_frame_width; inline i32 getNColumns(void) { return m_animData.columns; }
i32 m_frame_height; inline i32 getFrameWidth(void) { return m_animData.frameWidth; }
inline i32 getFrameHeight(void) { return m_animData.frameHeight; }
i32 m_column_offset; inline bool isStill(void) { return m_animData.still; }
i32 m_row_offset; inline bool isTurnBackEnabled(void) { return m_animData.turnBack; }
inline bool isRandomEnabled(void) { return m_animData.random; }
i32 m_frame_time;
i32 m_current_time; inline void setSpriteSheet(Image& img) { m_spriteSheet = &img; }
i32 m_current_frame; inline Rectangle getFrameRect(void) const { return m_frameRect; }
inline const Image& getSpriteSheet(void) const { return (m_spriteSheet != nullptr ? *m_spriteSheet : InvalidImage); }
bool m_backwards; inline Image& getSpriteSheet(void) { return (m_spriteSheet != nullptr ? *m_spriteSheet : InvalidImage); }
bool m_back; inline bool hasImage(void) const { return m_spriteSheet != nullptr; }
bool m_still; inline const AnimationData& getAnimationData(void) const { return m_animData; }
bool m_random; inline AnimationData& getAnimationData(void) { return m_animData; }
inline void removeSpriteSheet(void) { m_spriteSheet = &InvalidImage; }
Rectangle m_frame_rect;
}; private:
} void update_animation(void);
private:
inline static Image InvalidImage;
AnimationData m_animData;
ostd::StepTimer m_timer;
Image* m_spriteSheet { nullptr };
i32 m_currentFrame { 0 };
bool m_back { false };
Rectangle m_frameRect { 0, 0, 0, 0 };
};
}

View file

@ -599,17 +599,17 @@ namespace ostd
StepTimer& StepTimer::create(f64 updatesPerSecond, StepTimer::Callback callback) StepTimer& StepTimer::create(f64 updatesPerSecond, StepTimer::Callback callback)
{ {
m_targetDt = 1.0 / updatesPerSecond; m_targetDt = 1.0 / updatesPerSecond;
m_callback = std::move(callback); m_callback = std::move(callback);
m_prevTime = Clock::now(); m_prevTime = Clock::now();
m_accumulator = 0.0; m_accumulator = 0.0;
m_valid = true; m_valid = true;
return *this; return *this;
} }
void StepTimer::update(void) void StepTimer::update(void)
{ {
if (!m_valid) return; if (!m_valid) return;
TimePoint currentTime = Clock::now(); TimePoint currentTime = Clock::now();
Duration frameDuration = currentTime - m_prevTime; Duration frameDuration = currentTime - m_prevTime;
@ -634,11 +634,11 @@ namespace ostd
void StepTimer::reset(void) void StepTimer::reset(void)
{ {
if (m_valid) if (m_valid)
{ {
m_accumulator = 0.0; m_accumulator = 0.0;
m_prevTime = Clock::now(); m_prevTime = Clock::now();
} }
} }

View file

@ -32,19 +32,16 @@ class Window : public ogfx::gui::Window
inline Window(void) { } inline Window(void) { }
inline void onInitialize(void) override inline void onInitialize(void) override
{ {
// m_img.loadFromFile("./img.png", m_gfx); m_img.loadFromFile("./img.png", m_gfx);
// ogfx::Animation::AnimationData ad; ogfx::Animation::AnimationData ad;
// ad.backwards = false; ad.columns = 9;
// ad.columns = 9; ad.rows = 4;
// ad.rows = 4; ad.frameWidth = 256;
// ad.frame_width = 256; ad.frameHeight = 256;
// ad.frame_height = 256; ad.frameCount = 36;
// ad.length = 36; ad.fps = 60;
// ad.random = false; m_anim.create(ad);
// ad.still = false; m_anim.setSpriteSheet(m_img);
// ad.speed = 0;
// m_anim.create(ad);
// m_anim.setSpriteSheet(m_img);
m_label1.setText("Show Panel2"); m_label1.setText("Show Panel2");
@ -107,12 +104,12 @@ class Window : public ogfx::gui::Window
void onRedraw(ogfx::BasicRenderer2D& gfx) override void onRedraw(ogfx::BasicRenderer2D& gfx) override
{ {
// gfx.drawAnimation(m_anim, { 200, 200 }); gfx.drawAnimation(m_anim, { 200, 200 });
} }
void onFixedUpdate(void) override void onFixedUpdate(void) override
{ {
// m_anim.update(); m_anim.update();
} }
private: private: