108 lines
3.6 KiB
C++
108 lines
3.6 KiB
C++
#include "AnimationManager.h"
|
||
#include "EngineCore/Game.h"
|
||
|
||
AnimationManager::AnimationManager()
|
||
{
|
||
SDL_Renderer *renderer = Game::GetInstance().GetRenderer();
|
||
m_Texture = SDL_CreateTexture(
|
||
renderer,
|
||
SDL_PIXELFORMAT_ARGB8888,
|
||
SDL_TEXTUREACCESS_TARGET,
|
||
Game::GetInstance().Screen_W,
|
||
Game::GetInstance().Screen_H);
|
||
}
|
||
|
||
void AnimationManager::PreRender()
|
||
{
|
||
Actor::PreRender();
|
||
// 标记是否是第一个子对象(用于初始化min/max值)
|
||
bool isFirst = true;
|
||
float minX = 0.0f, minY = 0.0f; // 所有子对象的最小X、Y坐标
|
||
float maxX = 0.0f, maxY = 0.0f; // 所有子对象的最大X、Y坐标(右下角)
|
||
|
||
RefPtr<BaseNode> child = m_BaseNodes.GetFirst();
|
||
while (child)
|
||
{
|
||
// 转换为Animation对象
|
||
Animation *ani = static_cast<Animation *>(child.Get());
|
||
|
||
float width = ani->CurrentFrame->_RenderGuidanceInfo.rect.w;
|
||
float height = ani->CurrentFrame->_RenderGuidanceInfo.rect.h;
|
||
float x = ani->CurrentFrame->_RenderGuidanceInfo.rect.x;
|
||
float y = ani->CurrentFrame->_RenderGuidanceInfo.rect.y;
|
||
|
||
// 计算子对象的右下角坐标(左上角 + 宽高)
|
||
float currentMaxX = x + width;
|
||
float currentMaxY = y + height;
|
||
// 初始化或更新min/max值
|
||
if (isFirst)
|
||
{
|
||
minX = x;
|
||
minY = y;
|
||
maxX = currentMaxX;
|
||
maxY = currentMaxY;
|
||
isFirst = false;
|
||
}
|
||
else
|
||
{
|
||
minX = std::min(minX, x);
|
||
minY = std::min(minY, y);
|
||
maxX = std::max(maxX, currentMaxX);
|
||
maxY = std::max(maxY, currentMaxY);
|
||
}
|
||
|
||
child = child->GetNext();
|
||
}
|
||
// 计算最终的包围盒矩形
|
||
if (!isFirst) // 至少有一个子对象时才计算
|
||
{
|
||
m_RenderRect.x = minX; // 矩形左上角X
|
||
m_RenderRect.y = minY; // 矩形左上角Y
|
||
m_RenderRect.w = maxX - minX; // 矩形宽度(右下角X - 左上角X)
|
||
m_RenderRect.h = maxY - minY; // 矩形高度(右下角Y - 左上角Y)
|
||
}
|
||
}
|
||
|
||
void AnimationManager::Render()
|
||
{
|
||
SDL_Renderer *renderer = Game::GetInstance().GetRenderer();
|
||
// 设定渲染目标为纹理
|
||
SDL_SetRenderTarget(renderer, m_Texture);
|
||
|
||
SDL_RenderClear(renderer);
|
||
// 渲染所有子对象
|
||
Actor::Render();
|
||
// 恢复渲染目标为默认窗口
|
||
SDL_SetRenderTarget(renderer, nullptr);
|
||
|
||
SDL_Rect srcRect = {
|
||
static_cast<int>(m_RenderRect.x), // 子对象包围盒左上角X(纹理中的位置)
|
||
static_cast<int>(m_RenderRect.y), // 子对象包围盒左上角Y(纹理中的位置)
|
||
static_cast<int>(m_RenderRect.w), // 包围盒宽度(有效区域宽度)
|
||
static_cast<int>(m_RenderRect.h) // 包围盒高度(有效区域高度)
|
||
};
|
||
|
||
// SDL_FRect renderToWindow = {
|
||
// m_RenderRect.x, // 窗口上的X位置(可自定义)
|
||
// m_RenderRect.y, // 窗口上的Y位置(可自定义)
|
||
// m_RenderRect.w, // 渲染到窗口的宽度(与源区域等大)
|
||
// m_RenderRect.h // 渲染到窗口的高度(与源区域等大)
|
||
// };
|
||
SDL_FRect renderToWindow = {
|
||
0, 0, 1080, 720};
|
||
|
||
// SDL_Log("m_Texture rect: %f %f %f %f", renderToWindow.x, renderToWindow.y, renderToWindow.w, renderToWindow.h);
|
||
// SDL_RenderCopyF(renderer, m_Texture, &srcRect, &renderToWindow);
|
||
SDL_RenderCopyF(renderer, m_Texture, NULL, &renderToWindow);
|
||
}
|
||
|
||
void AnimationManager::AddAnimation(RefPtr<Animation> ani)
|
||
{
|
||
this->AddChild(ani);
|
||
}
|
||
|
||
void AnimationManager::Clear()
|
||
{
|
||
this->RemoveAllChild();
|
||
}
|