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

View file

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

View file

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