Qt 스프라이트 애니매이션
C, C++ 2019. 2. 21. 11:06 |반응형
2021.09.25 - [C, C++] - Qt6 설치 및 간단한 사용법
Qt의 Pixmap을 이용해 간단한 스프라이트 애니매이션을 구현 할 수 있다.
아래와 같은 스프라이트 이미지를 준비 한다.
이 중 처음 11개의 달리는 이미지 프레임만 사용한다.
Qt Widgets Application으로 기본 설정들을 적용해서 프로젝트를 만든다. (D:\Horse)
프로젝트를 만든 후 바로 build 디렉토리가 만들어지지 않으므로 build를 한 번 진행 한다.
build 디렉토리에 준비한 스프라이트 이미지를 복사한다.
mainwindow.h 에 아래와 같이 추가 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
|
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTimer>
#include <QPainter>
#include <QDebug>
namespace Ui {
class MainWindow;
}
class Sprite
{
public:
Sprite(QSize winsize);
void Draw(QPainter* painter); // 현재 프레임 그리기
void NextFrame(); // 다음 프레임 지정
private:
QPixmap* SpriteImage; // 스프라이트
int CurrentFrame; // 현재 프레임
int TotalFrame; // 전체 프레임 수(11)
int Column; // 스프라이트내 프레임 열(4)
int Row; // 스프라이트내 프레임 행(3) (실제 사용되지는 않음)
int FramesizeX; // 한 프레임의 X 길이(128)
int FramesizeY; // 한 프레임의 Y 길이(128)
QPoint FramePosition; // 스프라이트내 현재 프레임의 픽셀 단위 위치
QPoint DrawPosition; // 윈도우에서 프레임이 그려질 위치
QSize MainWindowSize; // 윈도우 사이즈
};
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow();
virtual void paintEvent(QPaintEvent* event);
private:
Ui::MainWindow *ui;
Sprite* sprite; // 스프라이트
QTimer* timer; // 타이머
};
#endif // MAINWINDOW_H
|
cs |
mainwindow.cpp 에 아래와 같이 추가 한다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
sprite = new Sprite(this->size());
timer = new QTimer(this);
timer->start(50); // 20Hz 타이머 시작
connect(timer, SIGNAL(timeout()), this, SLOT(update())); // timeout() 시그널이 발생하면 update() 실행
// connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)
// Creates a connection of the given type from the signal in the sender object to the method in the receiver object.
// Returns a handle to the connection that can be used to disconnect it later. You must use the SIGNAL() and SLOT() macros
// when specifying the signal and the method.
}
MainWindow::~MainWindow()
{
delete timer;
delete sprite;
delete ui;
}
void MainWindow::paintEvent(QPaintEvent *event)
{
QPainter paint(this); // The QPainter class performs low-level painting on widgets and other paint devices.
sprite->Draw(&paint);
sprite->NextFrame();
}
// 128X128 사이즈, 4X3배열의 11개 프레임
Sprite::Sprite(QSize winsize) : CurrentFrame(0), TotalFrame(11), Column(4), Row(3), FramesizeX(128), FramesizeY(128), FramePosition(0, 0)
{
MainWindowSize = winsize; // 메인 윈도우 사이즈
qDebug() << "Main Window Size: " << MainWindowSize << endl; // Application Output 창에 메인 윈도우 사이즈(400X300) 출력
SpriteImage = new QPixmap("horse.png"); //The QPixmap class is an off-screen image representation that can be used as a paint device.
qDebug() << "Sprite Size: " << SpriteImage->size() << endl; // Application Output 창에 스프라이트 사이즈(512X1024) 출력
// 메인 윈도우 중앙에 프레임 출력
DrawPosition.setX(MainWindowSize.width() / 2 - FramesizeX / 2);
DrawPosition.setY(MainWindowSize.height() / 2 - FramesizeY / 2);
}
void Sprite::Draw(QPainter* painter)
{
// Draws a pixmap at (x, y) by copying a part of the given pixmap into the paint device.
painter->drawPixmap(DrawPosition.x(), DrawPosition.y(), *SpriteImage, FramePosition.x(), FramePosition.y(), FramesizeX, FramesizeY);
// 'Running horse' 문자열 출력
const QRect rect = QRect(0, 0, MainWindowSize.width(), MainWindowSize.height() / 2);
painter->setPen(Qt::blue);
painter->setFont(QFont("Arial", 30));
painter->drawText(rect, Qt::AlignCenter, "Running horse");
}
void Sprite::NextFrame()
{
if (CurrentFrame >= TotalFrame) // 11번 째 프레임을 넘어가면 0으로 초기화
CurrentFrame = 0;
// 출력할 프레임의 픽셀 단위 위치 지정
FramePosition.setX((CurrentFrame % Column) * FramesizeX);
FramePosition.setY((CurrentFrame / Column) * FramesizeY);
CurrentFrame++;
}
|
cs |
프로젝트를 build하고 실행하면 아래와 같은 애니매이션이 재생된다.
Application Output 창에는 Main Window와 Sprite 사이즈가 표시 된다.
iCCP 관련 warning은 무시하거나 이 링크를 참고해서 제거한다.
반응형
'C, C++' 카테고리의 다른 글
How to open a command prompt on the project's path in Visual Studio (2) | 2019.07.03 |
---|---|
How to make a game save file editor 간단한 게임 에디터 만들기 (1) | 2019.06.30 |
Qt 설치 및 간단한 사용 예 (4) | 2019.01.16 |
How to install and use JsonCpp - JsonCpp 설치 및 사용 (2) | 2019.01.08 |
Console 어플리케이션에 이미지 디스플레이 하기 (0) | 2018.11.22 |