Animate idle character frames
This commit is contained in:
+35
-3
@@ -29,6 +29,7 @@ QString previewImagePath()
|
||||
PetWindow::PetWindow(QWidget *parent)
|
||||
: QWidget(parent)
|
||||
, m_imageLabel(new QLabel(this))
|
||||
, m_currentFrameIndex(0)
|
||||
, m_dragging(false)
|
||||
, m_alwaysOnTop(true)
|
||||
{
|
||||
@@ -43,6 +44,10 @@ PetWindow::PetWindow(QWidget *parent)
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
layout->addWidget(m_imageLabel);
|
||||
|
||||
connect(&m_animationTimer, &QTimer::timeout, this, [this]() {
|
||||
advanceIdleFrame();
|
||||
});
|
||||
|
||||
loadInitialImage();
|
||||
}
|
||||
|
||||
@@ -112,14 +117,38 @@ void PetWindow::loadInitialImage()
|
||||
const CharacterState *idleState = package.state(QStringLiteral("idle"));
|
||||
if (idleState != nullptr && !idleState->framePaths.isEmpty())
|
||||
{
|
||||
setDisplayImage(idleState->framePaths.first());
|
||||
startIdleAnimation(*idleState);
|
||||
return;
|
||||
}
|
||||
|
||||
setDisplayImage(previewImagePath());
|
||||
setDisplayImage(previewImagePath(), true);
|
||||
}
|
||||
|
||||
void PetWindow::setDisplayImage(const QString &imagePath)
|
||||
void PetWindow::startIdleAnimation(const CharacterState &idleState)
|
||||
{
|
||||
m_animationTimer.stop();
|
||||
m_idleFrames = idleState.framePaths;
|
||||
m_currentFrameIndex = 0;
|
||||
|
||||
setDisplayImage(m_idleFrames.at(m_currentFrameIndex), true);
|
||||
|
||||
const int intervalMs = qMax(1, 1000 / idleState.fps);
|
||||
m_animationTimer.start(intervalMs);
|
||||
}
|
||||
|
||||
void PetWindow::advanceIdleFrame()
|
||||
{
|
||||
if (m_idleFrames.isEmpty())
|
||||
{
|
||||
m_animationTimer.stop();
|
||||
return;
|
||||
}
|
||||
|
||||
m_currentFrameIndex = (m_currentFrameIndex + 1) % m_idleFrames.size();
|
||||
setDisplayImage(m_idleFrames.at(m_currentFrameIndex), false);
|
||||
}
|
||||
|
||||
void PetWindow::setDisplayImage(const QString &imagePath, bool centerWindow)
|
||||
{
|
||||
QPixmap pixmap(imagePath);
|
||||
if (pixmap.isNull())
|
||||
@@ -134,11 +163,14 @@ void PetWindow::setDisplayImage(const QString &imagePath)
|
||||
m_imageLabel->setPixmap(scaled);
|
||||
resize(scaled.size());
|
||||
|
||||
if (centerWindow)
|
||||
{
|
||||
if (const QScreen *screen = QGuiApplication::primaryScreen())
|
||||
{
|
||||
const QRect available = screen->availableGeometry();
|
||||
move(available.center() - rect().center());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PetWindow::setAlwaysOnTop(bool enabled)
|
||||
|
||||
+10
-1
@@ -2,8 +2,12 @@
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPoint>
|
||||
#include <QStringList>
|
||||
#include <QTimer>
|
||||
#include <QWidget>
|
||||
|
||||
struct CharacterState;
|
||||
|
||||
class PetWindow : public QWidget
|
||||
{
|
||||
public:
|
||||
@@ -17,11 +21,16 @@ protected:
|
||||
|
||||
private:
|
||||
void loadInitialImage();
|
||||
void setDisplayImage(const QString &imagePath);
|
||||
void startIdleAnimation(const CharacterState &idleState);
|
||||
void advanceIdleFrame();
|
||||
void setDisplayImage(const QString &imagePath, bool centerWindow);
|
||||
void setAlwaysOnTop(bool enabled);
|
||||
|
||||
QLabel *m_imageLabel;
|
||||
QTimer m_animationTimer;
|
||||
QStringList m_idleFrames;
|
||||
QPoint m_dragOffset;
|
||||
int m_currentFrameIndex;
|
||||
bool m_dragging;
|
||||
bool m_alwaysOnTop;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user