132 lines
4.5 KiB
C++
132 lines
4.5 KiB
C++
// IAEngine: 2D Game Engine by IA
|
|
// Copyright (C) 2025 IASoft (PVT) LTD (oss@iasoft.dev)
|
|
//
|
|
// This program 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.
|
|
//
|
|
// This program 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 this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
#include <IAEngine/Engine.hpp>
|
|
|
|
namespace ia::iae
|
|
{
|
|
SpriteComponent::SpriteComponent(IN Node2D *node) : TextureComponent(node)
|
|
{
|
|
}
|
|
|
|
VOID SpriteComponent::Draw()
|
|
{
|
|
const auto &animFrame = m_currentAnimationState;
|
|
PositionOffset() = animFrame.Position;
|
|
ScaleOffset() = animFrame.Scale;
|
|
RotationOffset() = animFrame.Rotation;
|
|
ColorOverlay() = animFrame.ColorOverlay;
|
|
SetTexture(animFrame.Texture);
|
|
TextureComponent::Draw();
|
|
}
|
|
|
|
VOID SpriteComponent::DebugDraw()
|
|
{
|
|
TextureComponent::DebugDraw();
|
|
}
|
|
|
|
VOID SpriteComponent::Update()
|
|
{
|
|
TextureComponent::Update();
|
|
|
|
UpdateAnimation();
|
|
}
|
|
|
|
VOID SpriteComponent::FixedUpdate()
|
|
{
|
|
TextureComponent::FixedUpdate();
|
|
}
|
|
|
|
Handle SpriteComponent::AddAnimation(IN CONST Animation &animation)
|
|
{
|
|
if (animation.Keys.empty())
|
|
return INVALID_HANDLE;
|
|
m_animations.pushBack(animation);
|
|
if(m_animations.size() == 1)
|
|
ForceSetActiveAnimation(0);
|
|
return m_animations.size() - 1;
|
|
}
|
|
|
|
VOID SpriteComponent::SetActiveAnimation(IN Handle animation)
|
|
{
|
|
if (animation == m_activeAnimationHandle)
|
|
return;
|
|
ForceSetActiveAnimation(animation);
|
|
}
|
|
|
|
VOID SpriteComponent::ForceSetActiveAnimation(IN Handle animation)
|
|
{
|
|
IA_RELEASE_ASSERT((animation != INVALID_HANDLE) && (animation < m_animations.size()));
|
|
m_prevAnimationKeyFrameIndex = 0;
|
|
m_activeAnimation = m_animations[animation];
|
|
|
|
m_prevAnimationKeyFrame = GetKeyFrame(m_prevAnimationKeyFrameIndex + 0);
|
|
m_nextAnimationKeyFrame = GetKeyFrame(m_prevAnimationKeyFrameIndex + 1);
|
|
|
|
m_currentAnimationState = m_prevAnimationKeyFrame;
|
|
m_activeAnimationHandle = animation;
|
|
|
|
SetTexture(m_currentAnimationState.Texture);
|
|
}
|
|
|
|
VOID SpriteComponent::SetAnimationFrame(IN INT32 animation, IN INT32 frame)
|
|
{
|
|
m_activeAnimation = {};
|
|
m_currentAnimationState = m_animations[animation].Keys[frame];
|
|
}
|
|
|
|
VOID SpriteComponent::UpdateAnimation()
|
|
{
|
|
const auto keyCount = m_activeAnimation.Keys.size();
|
|
if (keyCount <= 1)
|
|
return;
|
|
|
|
if (m_currentAnimationState.ShouldInterpolate)
|
|
{
|
|
const auto t = m_timelinePosition / m_prevAnimationKeyFrame.Duration;
|
|
#define INTERP_PROPERTY(name) \
|
|
m_currentAnimationState.name = \
|
|
m_prevAnimationKeyFrame.name + (m_nextAnimationKeyFrame.name - m_prevAnimationKeyFrame.name) * t;
|
|
|
|
INTERP_PROPERTY(Position);
|
|
INTERP_PROPERTY(Rotation);
|
|
INTERP_PROPERTY(Scale);
|
|
INTERP_PROPERTY(ColorOverlay);
|
|
|
|
#undef INTERP_PROPERTY
|
|
}
|
|
|
|
if (m_timelinePosition >= m_prevAnimationKeyFrame.Duration)
|
|
{
|
|
m_prevAnimationKeyFrameIndex = (m_prevAnimationKeyFrameIndex + 1) % keyCount;
|
|
if (!m_prevAnimationKeyFrameIndex && !m_activeAnimation.ShouldLoop)
|
|
{
|
|
m_activeAnimation = {};
|
|
return;
|
|
}
|
|
m_prevAnimationKeyFrame = GetKeyFrame(m_prevAnimationKeyFrameIndex + 0);
|
|
m_nextAnimationKeyFrame = GetKeyFrame(m_prevAnimationKeyFrameIndex + 1);
|
|
m_currentAnimationState = m_prevAnimationKeyFrame;
|
|
m_timelinePosition = 0;
|
|
}
|
|
m_timelinePosition += Engine::GetFrameDeltaTime() * 1000;
|
|
}
|
|
|
|
SpriteComponent::AnimationKeyFrame SpriteComponent::GetKeyFrame(IN INT32 index)
|
|
{
|
|
return m_activeAnimation.Keys[index % m_activeAnimation.Keys.size()];
|
|
}
|
|
} // namespace ia::iae
|