欢迎光临
我们一直在努力

24.QT小游戏

一 概述

使用链表数据结构设计一个画圈圈小游戏。

二 整体程序流程

程序启动顺序:

main.cpp创建MainWindow窗口

→ 执行MainWindow构造函数(创建窗口、手写按钮、绑定点击事件)

→ 窗口显示后,鼠标点击空白区域自动生成圆圈存入链表

→ 窗口每次刷新自动执行paintEvent,遍历链表画出所有圆圈

→ 点击按钮调用对应槽函数,修改链表(清空 / 删除最后一个圆),刷新画布

三 源码

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QList>
#include <QPoint>
#include <QColor>
#include <QPushButton>

namespace Ui {
class MainWindow;
}

// 圆圈数据结构体,链表存储单元
struct Circle
{
QPoint center;
int radius;
QColor fillColor;
};

class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = nullptr);
~MainWindow() override;

protected:
// 绘图、鼠标点击事件重写
void paintEvent(QPaintEvent *event) override;
void mousePressEvent(QMouseEvent *event) override;

private slots:
// 按钮点击槽函数
void slotClearAll();
void slotUndoLast();

private:
Ui::MainWindow *ui;
// 按钮控件声明
QPushButton* m_btnClearAll;
QPushButton* m_btnUndoLast;
// Qt双向链表存储所有圆圈
QList<Circle> m_circleList;
};

#endif // MAINWINDOW_H

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QPainter>
#include <QMouseEvent>
#include <QRandomGenerator>

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);

this->setWindowTitle("TEST");
this->resize(900, 650);

// 实例化按钮控件(英文文本)
m_btnClearAll = new QPushButton("Clear All Circles", this);
m_btnUndoLast = new QPushButton("Undo Last Circle", this);

// 按钮绝对坐标布局
m_btnClearAll->setGeometry(20, 20, 160, 35);
m_btnUndoLast->setGeometry(200, 20, 160, 35);

// 信号槽绑定
connect(m_btnClearAll, &QPushButton::clicked, this, &MainWindow::slotClearAll);
connect(m_btnUndoLast, &QPushButton::clicked, this, &MainWindow::slotUndoLast);
}

MainWindow::~MainWindow()
{
delete ui;
}

// 遍历链表,绘制全部圆圈
void MainWindow::paintEvent(QPaintEvent *event)
{
QMainWindow::paintEvent(event);
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
const auto& listRef = m_circleList;
for (const Circle& cir : listRef)
{
painter.setBrush(cir.fillColor);
painter.setPen(Qt::black);
painter.drawEllipse
(
cir.center.x() – cir.radius,
cir.center.y() – cir.radius,
cir.radius * 2,
cir.radius * 2
);
}
}

// 鼠标点击新增圆圈,存入链表尾部
void MainWindow::mousePressEvent(QMouseEvent *event)
{
QPoint clickPos = event->pos();
// 避开顶部按钮区域,防止点击按钮时误生成圆
if (clickPos.y() < 70)
return;

int r = QRandomGenerator::global()->bounded(25, 60);
QColor randColor
(
QRandomGenerator::global()->bounded(256),
QRandomGenerator::global()->bounded(256),
QRandomGenerator::global()->bounded(256)
);

Circle newCircle;
newCircle.center = clickPos;
newCircle.radius = r;
newCircle.fillColor = randColor;
m_circleList.append(newCircle);

update();
}

// 清空链表,销毁所有圆圈
void MainWindow::slotClearAll()
{
m_circleList.clear();
update();
}

// 删除链表最后一个圆圈(撤销)
void MainWindow::slotUndoLast()
{
if (!m_circleList.isEmpty())
{
m_circleList.removeLast();
update();
}
}

#include "mainwindow.h"

#include <QApplication>
#include <QLocale>
#include <QTranslator>

int main(int argc, char *argv[])
{
QApplication a(argc, argv);

QTranslator translator;
const QStringList uiLanguages = QLocale::system().uiLanguages();
for (const QString &locale : uiLanguages) {
const QString baseName = "TEST_" + QLocale(locale).name();
if (translator.load(":/i18n/" + baseName)) {
a.installTranslator(&translator);
break;
}
}
MainWindow w;
w.show();
return a.exec();
}

四 完整交互演示流程举例

  • 打开程序,窗口加载,自动生成两个按钮;
  • 在窗口中间空白处点击 3 次:链表依次存入圆 1、圆 2、圆 3,画面显示 3 个彩色圆;
  • 点击Undo Last Circle:链表删除圆 3,画面只剩圆 1、圆 2;
  • 再次点击空白:链表尾部新增圆 4,画面显示圆 1、圆 2、圆 4;
  • 点击Clear All Circles:链表清空,画布所有圆圈消失。
  • 五 效果演示

    点击3次:

    点击撤销上一次:

    点击销毁所有:

    赞(0)
    未经允许不得转载:171主机测评 » 24.QT小游戏
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址