半小时教你做大转盘游戏(QT篇)

本文讲述如何在linux系统使用QT开发一个简易的大转盘游戏。
操作系统:uos、debian
qt版本:Qt version 5.11.3
半小时教你做大转盘游戏(QT篇)

大转盘的制作其实很简单,大转盘的整体思想是这样,
1.定时器用来刷新大转盘的界面这样就有动态的旋转效果,
2.监听键盘事件,通过键盘控制大转盘的开关,然后判断当前的状态是已经开始还是停止,如果状态是停止那么就启动定时器,如果状态是开始就关闭定时器,
3. 绘制界面内容。

新建项目

半小时教你做大转盘游戏(QT篇)
半小时教你做大转盘游戏(QT篇)
半小时教你做大转盘游戏(QT篇)
我们的项目中不实用到.ui文件。

定时器使用

QTimer:定时器类主要作用是按照固定间隔时间发送定时器信号,我们通过监听定时信号处理信号内容,修改指针角度,刷新界面内容就可以了。

start() // 启动定时器,设置启动以后会按照固定时间发送信号
stop() // 关闭定时器,关闭之后不再发送定时信号。
setInterval(int) // 设置定时时长,按照毫秒 1秒=1000毫秒 

键盘按键响应

继承父类keyPressEvent(QKeyEvent *event)函数,监听键盘事件。
当用户按下键盘的时候会触发这个监听事件。
QKeyEvent 键盘事件相关的类。我们可以从这个类中获取键盘的内容,例如按下了什么按钮。

    int key() ;// 获取键盘按键的key值
#ifndef QT_NO_SHORTCUT
    bool matches(QKeySequence::StandardKey key) const;
#endif
    Qt::KeyboardModifiers modifiers() const;
    inline QString text() const { return txt; }
    inline bool isAutoRepeat() const { return autor; }
    inline int count() const { return int(c); }

    inline quint32 nativeScanCode() const { return nScanCode; }
    inline quint32 nativeVirtualKey() const { return nVirtualKey; }
    inline quint32 nativeModifiers() const { return nModifiers; }

图片绘制

// 加载背景图片
QImage img("://bk.png");
// 将图片绘制到界面中
painter->drawImage(0,0,img);

图片按照中心旋转

图片旋转需要根据长宽计算偏移量。

QPixmap MainWindow::rotateImageWithTransform(const QPixmap &src, int angle)
{
    QMatrix matri;
    //迁移到中心
    matri.translate(src.width()/2.0,src.height()/2.0);
    //中心旋转
    matri.rotate(angle);
    //回退中心
    matri.translate(-src.width()/2.0,-src.height()/2.0);
    //执行坐标映射变化
    //旋转后图像大小变化了 需要提前进行裁剪 如果在旋转后裁剪
    //则需要计算使用三角函数计算
    //中心偏移
    int cubeWidth = qMin(src.width(),src.height());
    QRect cubeRect(0,0,cubeWidth,cubeWidth);
    cubeRect.moveCenter(src.rect().center());
    auto retImg = src.copy(cubeRect);
    retImg = retImg.transformed(matri,Qt::SmoothTransformation);
    return retImg;
}

源码:
mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
    QTimer * m_fTimer;
    bool m_status;
    int m_time ;
    QPixmap rotateImageWithTransform(const QPixmap &src, int angle);
private:
    void drawBackground(QPainter *painter);     // 绘制背景
    void drawPointe(QPainter *painter);         // 绘制指针
public slots:
    void on_timer_timeout();
protected:
    void paintEvent(QPaintEvent *event);		// update函数执行会触发重绘。
    void keyPressEvent(QKeyEvent *event);		// 按钮消息响应
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include <QPainter>
#include <QTimer>
#include <QKeyEvent>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent),
      m_fTimer(new QTimer(this)),
      m_status(false),
      m_time(0)
{
    setWindowTitle("幸运大转盘");	// 修改窗口标题
    setFixedSize(500,500);		// 更新串口大小
    m_fTimer->stop();
    m_fTimer->setInterval(10);	// 设置定时器
    connect(m_fTimer,SIGNAL(timeout()),this,SLOT(on_timer_timeout()));
}

MainWindow::~MainWindow()
{

}

void MainWindow::paintEvent(QPaintEvent *)
{
    QPainter painter(this);
    drawBackground(&painter);		// 绘制背景。
    drawPointe(&painter);			// 绘制指针。
}

void MainWindow::drawBackground(QPainter *painter)
{
    QImage img("://bk.png");
    painter->drawImage(0,0,img);
}

void MainWindow::drawPointe(QPainter *painter)
{
     QPixmap img("://3.png");
     int rangle = 20*m_time;
     if(rangle % 30 ==0){
         rangle +=1;
     }
     img = rotateImageWithTransform(img,rangle);
     painter->drawPixmap(0,0,500,500,img);
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Return){
        if(m_status){
            m_status = false;
            m_fTimer->stop();
        }
        else{
            m_status = true;
            m_fTimer->start();
        }
    }
}


QPixmap MainWindow::rotateImageWithTransform(const QPixmap &src, int angle)
{
    QMatrix matri;
    //迁移到中心
    matri.translate(src.width()/2.0,src.height()/2.0);
    //中心旋转
    matri.rotate(angle);
    //回退中心
    matri.translate(-src.width()/2.0,-src.height()/2.0);
    //执行坐标映射变化
    //旋转后图像大小变化了 需要提前进行裁剪 如果在旋转后裁剪
    //则需要计算使用三角函数计算
    //中心偏移
    int cubeWidth = qMin(src.width(),src.height());
    QRect cubeRect(0,0,cubeWidth,cubeWidth);
    cubeRect.moveCenter(src.rect().center());
    auto retImg = src.copy(cubeRect);
    retImg = retImg.transformed(matri,Qt::SmoothTransformation);
    return retImg;
}

void MainWindow::on_timer_timeout()
{
    m_time ++;
    if(m_time == 360/20){
        m_time = 0;
    }
    update();
}

上一篇:重新安装IDEA后双击启动无反应


下一篇:如何优雅的开发一个时钟(QT篇)