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