From ed3c21bd36344e12bdd1f38fa887ce990007bd0d Mon Sep 17 00:00:00 2001 From: OmniaX-Dev Date: Fri, 17 Apr 2026 17:04:19 +0200 Subject: [PATCH] Reworked the Animation class --- extra/DefaultTheme.oss | 6 +- src/ogfx/utils/Animation.cpp | 202 ++++++++++++---------------- src/ogfx/utils/Animation.hpp | 249 ++++++++++++++++++----------------- src/ostd/utils/Time.cpp | 20 +-- src/test/GuiTest.cpp | 27 ++-- 5 files changed, 241 insertions(+), 263 deletions(-) diff --git a/extra/DefaultTheme.oss b/extra/DefaultTheme.oss index 8982bb0..2dc031a 100644 --- a/extra/DefaultTheme.oss +++ b/extra/DefaultTheme.oss @@ -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)) } -% =================== +% ==================== diff --git a/src/ogfx/utils/Animation.cpp b/src/ogfx/utils/Animation.cpp index 3cb9cb5..8b35022 100644 --- a/src/ogfx/utils/Animation.cpp +++ b/src/ogfx/utils/Animation.cpp @@ -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 . -*/ - -#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(x), cast(y), cast(m_frame_width), cast(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 . +*/ + +#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(m_currentFrame / m_animData.columns) + m_animData.rowOffset) * m_animData.frameHeight); + m_frameRect = { cast(x), cast(y), m_animData.frameWidth, m_animData.frameHeight }; + } +} diff --git a/src/ogfx/utils/Animation.hpp b/src/ogfx/utils/Animation.hpp index 4b98d36..8ea31cd 100644 --- a/src/ogfx/utils/Animation.hpp +++ b/src/ogfx/utils/Animation.hpp @@ -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 . -*/ - -#pragma once - -#include -#include -#include - -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 . +*/ + +#pragma once + +#include +#include +#include +#include + +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 }; + }; +} diff --git a/src/ostd/utils/Time.cpp b/src/ostd/utils/Time.cpp index 713e3b6..c4f96c8 100644 --- a/src/ostd/utils/Time.cpp +++ b/src/ostd/utils/Time.cpp @@ -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(); - } + } } diff --git a/src/test/GuiTest.cpp b/src/test/GuiTest.cpp index ad3e85e..3e970ed 100644 --- a/src/test/GuiTest.cpp +++ b/src/test/GuiTest.cpp @@ -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: