반응형

2021.09.25 - [C, C++] - Qt6 설치 및 간단한 사용법

 

Qt의 Pixmap을 이용해 간단한 스프라이트 애니매이션을 구현 할 수 있다.

 

아래와 같은 스프라이트 이미지를 준비 한다. 

horse.zip
다운로드

이 중 처음 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(00)
{
    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(00, 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은 무시하거나 이 링크를 참고해서 제거한다.

 

 

반응형
Posted by J-sean
: