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,21 +1,21 @@
/* /*
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"
@ -23,95 +23,63 @@
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)
{
create(ad);
}
void Animation::create(AnimationData& ad)
{
create(ad.length, ad.columns, ad.rows, ad.frame_width, ad.frame_height);
m_backwards = ad.backwards;
m_still = ad.still;
m_column_offset = ad.column_offset;
m_row_offset = ad.row_offset;
m_frame_time = ad.speed;
m_random = false;
}
void Animation::create(i32 frames, i32 columns, i32 rows, i32 frame_width, i32 frame_height)
{
m_frames = frames;
m_columns = columns;
m_frame_width = frame_width;
m_frame_height = frame_height;
m_rows = rows;
m_frame_time = 5;
m_current_time = 0;
m_current_frame = 0;
m_backwards = false;
m_back = false;
m_still = false;
m_random = false;
m_column_offset = 0;
m_row_offset = 0;
} }
void Animation::resetAnimation(void) void Animation::resetAnimation(void)
{ {
m_current_frame = 0; m_currentFrame = 0;
m_current_time = 0;
} }
void Animation::update(void) void Animation::update_animation(void)
{ {
if (m_current_time++ > m_frame_time && !m_still) if (!m_animData.still)
{ {
m_current_time = 0; if (m_animData.random)
if (m_random)
{ {
m_current_frame = ostd::Random::geti32(0, m_frames); m_currentFrame = ostd::Random::geti32(0, m_animData.frameCount);
} }
else if (m_backwards) else if (m_animData.turnBack)
{ {
if (!m_back && m_current_frame >= m_frames - 1) if (!m_back && m_currentFrame >= m_animData.frameCount - 1)
{ {
m_back = true; m_back = true;
m_current_frame--; m_currentFrame--;
} }
else if (!m_back) else if (!m_back)
m_current_frame++; m_currentFrame++;
else if (m_back && m_current_frame <= 0) else if (m_back && m_currentFrame <= 0)
{ {
m_back = false; m_back = false;
m_current_frame++; m_currentFrame++;
} }
else if (m_back) else if (m_back)
m_current_frame--; m_currentFrame--;
} }
else else
{ {
if (m_current_frame++ >= m_frames - 1) if (m_currentFrame++ >= m_animData.frameCount - 1)
m_current_frame = 0; m_currentFrame = 0;
} }
} }
else if (m_still) else if (m_animData.still)
m_current_frame = 1; //TODO: Hardcoded value {
i32 x = ((m_current_frame % m_columns) + m_column_offset) * m_frame_width; if (m_animData.stillFrame >= 0 && m_animData.stillFrame < m_animData.frameCount)
i32 y = m_row_offset * m_frame_height; m_currentFrame = m_animData.stillFrame;
if (m_rows > 1) else
y = ((m_current_frame / m_columns) + m_row_offset) * m_frame_height; m_currentFrame = 0;
}
m_frame_rect = { cast<f32>(x), cast<f32>(y), cast<f32>(m_frame_width), cast<f32>(m_frame_height) }; i32 x = m_animData.pixelOffsetX + (((m_currentFrame % m_animData.columns) + m_animData.columnOffset) * m_animData.frameWidth);
i32 y = m_animData.pixelOffsetY + (m_animData.rowOffset * m_animData.frameHeight);
if (m_animData.rows > 1)
y = m_animData.pixelOffsetY + ((cast<i32>(m_currentFrame / m_animData.columns) + m_animData.rowOffset) * m_animData.frameHeight);
m_frameRect = { cast<f32>(x), cast<f32>(y), m_animData.frameWidth, m_animData.frameHeight };
} }
} }

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 <ostd/utils/Time.hpp>
#include <ogfx/resources/Image.hpp> #include <ogfx/resources/Image.hpp>
namespace ogfx namespace ogfx
{ {
class Animation class Animation
{ {
public: struct AnimationData { public: struct AnimationData : public ostd::__i_stringeable {
i32 length; i32 frameCount { 1 };
i32 speed; i32 stillFrame { 0 };
i32 still_frame; f64 fps { 60.0 };
i32 row_offset; i32 rowOffset { 0 };
i32 column_offset; i32 columnOffset { 0 };
f32 pixelOffsetX { 0.0f };
f32 pixelOffsetY { 0.0f };
i32 rows { 1 };
i32 columns { 1 };
f32 frameWidth{ 32 };
f32 frameHeight { 32 };
i32 rows; bool still { false };
i32 columns; bool turnBack { false };
bool random { false };
i32 frame_width; inline String toString(void) const override
i32 frame_height;
bool still;
bool backwards;
bool random;
AnimationData(void)
{ {
length = 3; String str = "";
speed = 10; str.add("AnimData {");
row_offset = 0; str.add(" ").add("frameCount: ").add(frameCount).add(",\n");
column_offset = 0; str.add(" ").add("stillFrame: ").add(stillFrame).add(",\n");
rows = 1; str.add(" ").add("rowOffset: ").add(rowOffset).add(",\n");
columns = 3; str.add(" ").add("columnOffset: ").add(columnOffset).add(",\n");
frame_width = 32; str.add(" ").add("pixelOffsetX: ").add(pixelOffsetX, 2).add(",\n");
frame_height = 32; str.add(" ").add("pixelOffsetY: ").add(pixelOffsetY, 2).add(",\n");
still = false; str.add(" ").add("rows: ").add(rows).add(",\n");
backwards = true; str.add(" ").add("columns: ").add(columns).add(",\n");
random = false; str.add(" ").add("frameWidth: ").add(frameWidth, 2).add(",\n");
still_frame = 1; str.add(" ").add("frameHeight: ").add(frameHeight, 2).add(",\n");
str.add(" ").add("still: ").add(STR_BOOL(still)).add(",\n");
str.add(" ").add("turnBack: ").add(STR_BOOL(turnBack)).add(",\n");
str.add(" ").add("random: ").add(STR_BOOL(random)).add(",\n");
str.add("}");
return str;
} }
}; };
public: public:
Animation(void); inline Animation(void) { }
Animation(i32 frames, i32 columns, i32 rows, i32 frame_width, i32 frame_height); inline Animation(const AnimationData& ad) { create(ad); };
Animation(AnimationData& ad); inline Animation(const AnimationData& ad, Image& spriteSheet) { create(ad, spriteSheet); };
void create(i32 frames, i32 columns, i32 rows, i32 frame_width, i32 frame_height); inline Animation& create(const AnimationData& ad) { return create(ad, InvalidImage); }
void create(AnimationData& ad); inline void update(void) { m_timer.update(); }
void update(void); Animation& create(const AnimationData& ad, Image& spriteSheet);
void resetAnimation(void); void resetAnimation(void);
inline void setFrameNumber(i32 n) { m_frames = n; } inline void setFrameCount(i32 n) { m_animData.frameCount = n; }
inline void setColumnNumber(i32 n) { m_columns = n; } inline void setStillFrame(i32 n) { m_animData.stillFrame = n; }
inline void setBackwards(bool b) { m_backwards = b; } inline void setColumnOffset(i32 o) { m_animData.columnOffset = o; }
inline void setSpeed(i32 d) { m_frame_time = d; } inline void setRowOffset(i32 o) { m_animData.rowOffset = o; }
inline void setColumnOffset(i32 o) { m_column_offset = o; } inline void setPixelOffsetX(f32 o) { m_animData.pixelOffsetX = o; }
inline void setRowOffset(i32 o) { m_row_offset = o; } inline void setPixelOffsetY(f32 o) { m_animData.pixelOffsetY = o; }
inline void setStill(bool s) { m_still = s; } inline void setNRows(i32 n) { m_animData.rows = n; }
inline void setSpriteSheet(Image& img) { m_spriteSheet = &img; } inline void setNColumns(i32 n) { m_animData.columns = n; }
inline void setFrameWidth(i32 f) { m_animData.frameWidth = f; }
inline void setFrameHeight(i32 f) { m_animData.frameHeight = f; }
inline void enableStill(bool b = true) { m_animData.still = b; }
inline void enableTurnBack(bool b = true) { m_animData.turnBack = b; }
inline void enableRandom(bool b = true) { m_animData.random = b; }
inline i32 getFrameNumber(void) const { return m_frames; } inline i32 getFrameCount(void) { return m_animData.frameCount; }
inline i32 getColumnNumber(void) const { return m_columns; } inline i32 getStillFrame(void) { return m_animData.stillFrame; }
inline bool getBackwards(void) const { return m_backwards; } inline f64 getFPS(void) { return m_animData.fps; }
inline i32 getDelay(void) const { return m_frame_time; } inline i32 getColumnOffset(void) { return m_animData.columnOffset; }
inline i32 getColumnOffset(void) const { return m_column_offset; } inline i32 getRowOffset(void) { return m_animData.rowOffset; }
inline i32 getRowOffset(void) const { return m_row_offset; } inline f32 getPixelOffsetX(void) { return m_animData.pixelOffsetX; }
inline bool isStill(void) const { return m_still; } inline f32 getPixelOffsetY(void) { return m_animData.pixelOffsetY; }
inline Rectangle getFrameRect(void) const { return m_frame_rect; } inline i32 getNRows(void) { return m_animData.rows; }
inline i32 getNColumns(void) { return m_animData.columns; }
inline i32 getFrameWidth(void) { return m_animData.frameWidth; }
inline i32 getFrameHeight(void) { return m_animData.frameHeight; }
inline bool isStill(void) { return m_animData.still; }
inline bool isTurnBackEnabled(void) { return m_animData.turnBack; }
inline bool isRandomEnabled(void) { return m_animData.random; }
inline void setSpriteSheet(Image& img) { m_spriteSheet = &img; }
inline Rectangle getFrameRect(void) const { return m_frameRect; }
inline const Image& getSpriteSheet(void) const { return (m_spriteSheet != nullptr ? *m_spriteSheet : InvalidImage); } inline const Image& getSpriteSheet(void) const { return (m_spriteSheet != nullptr ? *m_spriteSheet : InvalidImage); }
inline Image& getSpriteSheet(void) { return (m_spriteSheet != nullptr ? *m_spriteSheet : InvalidImage); } inline Image& getSpriteSheet(void) { return (m_spriteSheet != nullptr ? *m_spriteSheet : InvalidImage); }
inline bool hasImage(void) const { return m_spriteSheet != nullptr; } inline bool hasImage(void) const { return m_spriteSheet != nullptr; }
inline const AnimationData& getAnimationData(void) const { return m_animData; }
inline AnimationData& getAnimationData(void) { return m_animData; }
inline void removeSpriteSheet(void) { m_spriteSheet = &InvalidImage; }
private:
void update_animation(void);
private: private:
Image* m_spriteSheet { nullptr };
inline static Image InvalidImage; inline static Image InvalidImage;
AnimationData m_animData;
i32 m_frames; ostd::StepTimer m_timer;
i32 m_rows; Image* m_spriteSheet { nullptr };
i32 m_columns; i32 m_currentFrame { 0 };
i32 m_frame_width; bool m_back { false };
i32 m_frame_height; Rectangle m_frameRect { 0, 0, 0, 0 };
i32 m_column_offset;
i32 m_row_offset;
i32 m_frame_time;
i32 m_current_time;
i32 m_current_frame;
bool m_backwards;
bool m_back;
bool m_still;
bool m_random;
Rectangle m_frame_rect;
}; };
} }

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: