160 lines
5.1 KiB
C++
160 lines
5.1 KiB
C++
#include "Sprite.h"
|
|
#include "EngineCore/Game.h"
|
|
#include "Text.h"
|
|
Sprite::Sprite()
|
|
{
|
|
}
|
|
|
|
Sprite::Sprite(std::string imgPath, int Index)
|
|
{
|
|
this->imgPath = imgPath;
|
|
this->Index = Index;
|
|
m_texture = new Texture(imgPath, Index);
|
|
Init();
|
|
CalcRenderInfoLogic(); // 第一次计算
|
|
}
|
|
|
|
Sprite::Sprite(std::string PngPath)
|
|
{
|
|
m_texture = new Texture(PngPath);
|
|
Init();
|
|
CalcRenderInfoLogic(); // 第一次计算
|
|
}
|
|
|
|
Sprite::~Sprite()
|
|
{
|
|
}
|
|
|
|
RefPtr<Texture> Sprite::GetTexture()
|
|
{
|
|
return m_texture;
|
|
}
|
|
|
|
void Sprite::SetIterationPos(VecFPos pos)
|
|
{
|
|
RenderBase::SetIterationPos(pos);
|
|
CalcRenderInfo();
|
|
}
|
|
|
|
void Sprite::HandleEvents(SDL_Event *e)
|
|
{
|
|
}
|
|
|
|
void Sprite::Update(float deltaTime)
|
|
{
|
|
if (CalcRenderInfoFlag && Visible)
|
|
CalcRenderInfoLogic();
|
|
}
|
|
|
|
void Sprite::CalcRenderInfoLogic()
|
|
{
|
|
// 计算缩放因子和翻转状态
|
|
float scaleX = transformIter.scale.x * transform.scale.x;
|
|
float scaleY = transformIter.scale.y * transform.scale.y;
|
|
// X轴和Y轴上是否翻转的标志
|
|
bool flipX = scaleX < 0;
|
|
bool flipY = scaleY < 0;
|
|
|
|
_RenderGuidanceInfo.flip = SDL_FLIP_NONE;
|
|
// 更新翻转状态
|
|
if (flipX)
|
|
_RenderGuidanceInfo.flip = static_cast<SDL_RendererFlip>(SDL_FLIP_HORIZONTAL | _RenderGuidanceInfo.flip);
|
|
if (flipY)
|
|
_RenderGuidanceInfo.flip = static_cast<SDL_RendererFlip>(SDL_FLIP_VERTICAL | _RenderGuidanceInfo.flip);
|
|
|
|
// 纹理数据里带的偏移数据 有这个偏移才能保证动画播放时视觉中心点在一个点上
|
|
int texturePosX = flipX ? -(m_texture->TextureSize.width + m_texture->TexturePos.x) + SDL_abs(transform.position.x * 2) : m_texture->TexturePos.x;
|
|
int texturePosY = flipY ? -(m_texture->TextureSize.height + m_texture->TexturePos.y) + SDL_abs(transform.position.y * 2) : m_texture->TexturePos.y;
|
|
|
|
// 先计算Img坐标与精灵坐标合成后的真实坐标
|
|
int RealPosX = transform.position.x + texturePosX;
|
|
int RealPosY = transform.position.y + texturePosY;
|
|
|
|
// 计算在世界中的位置
|
|
int baseX = transformIter.position.x + RealPosX;
|
|
int baseY = transformIter.position.y + RealPosY;
|
|
|
|
// 获取当前帧的原始尺寸
|
|
int frameWidth = m_texture->TextureSize.width;
|
|
int frameHeight = m_texture->TextureSize.height;
|
|
|
|
// 原始锚点偏移(基于帧尺寸)
|
|
int origAnchorOffsetX = static_cast<int>(frameWidth * Anchor.x);
|
|
int origAnchorOffsetY = static_cast<int>(frameHeight * Anchor.y);
|
|
|
|
// 缩放的绝对值
|
|
float absScaleX = SDL_abs(scaleX);
|
|
float absScaleY = SDL_abs(scaleY);
|
|
// 缩放后的尺寸
|
|
int scaledWidth = static_cast<int>(frameWidth * absScaleX);
|
|
int scaledHeight = static_cast<int>(frameHeight * absScaleY);
|
|
// 缩放后的锚点偏移
|
|
int scaledAnchorOffsetX = static_cast<int>(origAnchorOffsetX * absScaleX);
|
|
int scaledAnchorOffsetY = static_cast<int>(origAnchorOffsetY * absScaleY);
|
|
|
|
// 计算缩放后的锚点偏移与原锚点偏移的差值
|
|
int scaleOffsetX = scaledAnchorOffsetX - origAnchorOffsetX;
|
|
int scaleOffsetY = scaledAnchorOffsetY - origAnchorOffsetY;
|
|
|
|
// 最终位置计算:世界位置 + 缩放锚点差值 - 缩放后的锚点偏移 + 纹理数据里带的偏移数据 (计算出绘制点的左上角)
|
|
int Xpos = baseX + scaleOffsetX;
|
|
int Ypos = baseY + scaleOffsetY;
|
|
|
|
// 更新渲染信息
|
|
_RenderGuidanceInfo.rect = {Xpos, Ypos, scaledWidth, scaledHeight};
|
|
_RenderGuidanceInfo.AnchorPos = {scaledAnchorOffsetX, scaledAnchorOffsetY};
|
|
|
|
// 屏幕内检测
|
|
int screenWidth = Game::GetInstance().Screen_W;
|
|
int screenHeight = Game::GetInstance().Screen_H;
|
|
bool isInScreen = (Xpos + scaledWidth >= 0 && Xpos <= screenWidth && Ypos + scaledHeight >= 0 && Ypos <= screenHeight);
|
|
_RenderGuidanceInfo.IsInScreen = isInScreen;
|
|
|
|
this->Size = {scaledWidth, scaledHeight};
|
|
_RenderGuidanceInfo.rotation = transformIter.rotation + transform.rotation;
|
|
|
|
CalcRenderInfoFlag = false;
|
|
}
|
|
|
|
void Sprite::Render()
|
|
{
|
|
if (!Visible)
|
|
return;
|
|
SDL_Renderer *renderer = Game::GetInstance().GetRenderer();
|
|
if (!m_texture)
|
|
return;
|
|
|
|
if (_RenderGuidanceInfo.IsInScreen && _RenderGuidanceInfo.Visible)
|
|
{
|
|
if (_RenderGuidanceInfo.rotation != 0.f || _RenderGuidanceInfo.flip != SDL_FLIP_NONE)
|
|
{
|
|
SDL_Point AnchorPos = _RenderGuidanceInfo.AnchorPos;
|
|
SDL_RenderCopyEx(renderer, m_texture->GetTexture(), NULL, &_RenderGuidanceInfo.rect, _RenderGuidanceInfo.rotation, &AnchorPos, _RenderGuidanceInfo.flip);
|
|
}
|
|
else
|
|
{
|
|
SDL_RenderCopy(renderer, m_texture->GetTexture(), NULL, &_RenderGuidanceInfo.rect);
|
|
// // 设置绘制颜色
|
|
// SDL_SetRenderDrawColor(renderer, 255, 0, 0, 128);
|
|
// // 绘制填充矩形
|
|
// SDL_RenderFillRect(renderer, &_RenderGuidanceInfo.rect);
|
|
}
|
|
Game::GetInstance().RenderCount++;
|
|
}
|
|
}
|
|
|
|
void Sprite::Clear()
|
|
{
|
|
}
|
|
|
|
void Sprite::SetBlendMode(SDL_BlendMode blendMode)
|
|
{
|
|
if (GetBlendMode() != blendMode)
|
|
m_texture->SetBlendMode(blendMode);
|
|
}
|
|
|
|
SDL_BlendMode Sprite::GetBlendMode()
|
|
{
|
|
return m_texture->GetBlendMode();
|
|
}
|