用qt中的Widget类写一个完整的打地鼠小游戏
时间: 2023-06-15 07:06:58 浏览: 57
好的,以下是一个基于Qt Widget类的打地鼠小游戏的实现示例:
首先,我们需要一个地鼠的图片资源,可以在Qt的资源管理器中添加一个图片资源。
在窗口类中,我们需要定义一些变量和函数来实现游戏逻辑:
```cpp
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr);
~Widget();
private:
QTimer* m_timer;
QLabel* m_label;
QLabel* m_scoreLabel;
int m_score;
QVector<QLabel*> m_holes;
int m_currentHoleIndex;
QPixmap m_mousePixmap;
private slots:
void onTimerTimeout();
void onHoleClicked();
};
```
其中,`m_timer`是用于定时切换地鼠出现位置的计时器,`m_label`是用于显示地鼠的标签控件,`m_scoreLabel`是用于显示分数的标签控件,`m_score`是记录当前分数的变量,`m_holes`是存储地鼠出现位置标签控件的向量,`m_currentHoleIndex`是记录当前地鼠出现位置的索引变量,`m_mousePixmap`是地鼠的图片资源。
在构造函数中,我们需要初始化这些变量和控件,并启动计时器:
```cpp
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
// 初始化分数和地鼠图片
m_score = 0;
m_mousePixmap = QPixmap(":/images/mouse.png");
// 初始化地鼠出现位置标签控件
for (int i = 0; i < 9; i++) {
QLabel* hole = new QLabel(this);
hole->setPixmap(QPixmap(":/images/hole.png"));
hole->setScaledContents(true);
hole->setGeometry(50 + 120 * (i % 3), 50 + 120 * (i / 3), 100, 100);
hole->installEventFilter(this);
m_holes.push_back(hole);
}
// 初始化分数标签控件
m_scoreLabel = new QLabel(this);
m_scoreLabel->setText("Score: 0");
m_scoreLabel->setGeometry(20, 20, 100, 30);
// 初始化地鼠标签控件
m_label = new QLabel(this);
m_label->setPixmap(m_mousePixmap);
m_label->setScaledContents(true);
m_label->setVisible(false);
// 初始化计时器
m_timer = new QTimer(this);
connect(m_timer, SIGNAL(timeout()), this, SLOT(onTimerTimeout()));
m_timer->start(1000);
}
```
在`onTimerTimeout`函数中,我们需要在地鼠出现位置随机选择一个位置,并设置地鼠的位置和显示状态:
```cpp
void Widget::onTimerTimeout()
{
// 随机选择一个地鼠出现位置
m_currentHoleIndex = qrand() % m_holes.size();
QLabel* hole = m_holes[m_currentHoleIndex];
// 设置地鼠位置和显示状态
m_label->setGeometry(hole->x() + 20, hole->y() + 20, 60, 60);
m_label->setVisible(true);
}
```
在`onHoleClicked`函数中,我们需要处理玩家点击地鼠的事件,并更新分数和显示:
```cpp
void Widget::onHoleClicked()
{
// 如果地鼠显示中,则判断是否被击中
if (m_label->isVisible()) {
int x = m_label->x();
int y = m_label->y();
// 判断是否在地鼠位置范围内
if (x >= m_holes[m_currentHoleIndex]->x() && x <= m_holes[m_currentHoleIndex]->x() + 100 &&
y >= m_holes[m_currentHoleIndex]->y() && y <= m_holes[m_currentHoleIndex]->y() + 100) {
// 击中地鼠,分数加一
m_score++;
m_scoreLabel->setText(QString("Score: %1").arg(m_score));
}
// 隐藏地鼠
m_label->setVisible(false);
}
}
```
最后,我们需要在窗口类中实现`eventFilter`函数来处理地鼠出现位置标签控件的点击事件:
```cpp
bool Widget::eventFilter(QObject* watched, QEvent* event)
{
if (event->type() == QEvent::MouseButtonRelease) {
// 如果点击了地鼠出现位置标签控件,则处理点击事件
for (int i = 0; i < m_holes.size(); i++) {
if (m_holes[i] == watched) {
onHoleClicked();
return true;
}
}
}
return QWidget::eventFilter(watched, event);
}
```
完整代码如下:
```cpp
#include "widget.h"
#include <QTimer>
#include <QLabel>
#include <QPixmap>
#include <QVector>
#include <QEvent>
Widget::Widget(QWidget *parent)
: QWidget(parent)
{
// 初始化分数和地鼠图片
m_score = 0;
m_mousePixmap = QPixmap(":/images/mouse.png");
// 初始化地鼠出现位置标签控件
for (int i = 0; i < 9; i++) {
QLabel* hole = new QLabel(this);
hole->setPixmap(QPixmap(":/images/hole.png"));
hole->setScaledContents(true);
hole->setGeometry(50 + 120 * (i % 3), 50 + 120 * (i / 3), 100, 100);
hole->installEventFilter(this);
m_holes.push_back(hole);
}
// 初始化分数标签控件
m_scoreLabel = new QLabel(this);
m_scoreLabel->setText("Score: 0");
m_scoreLabel->setGeometry(20, 20, 100, 30);
// 初始化地鼠标签控件
m_label = new QLabel(this);
m_label->setPixmap(m_mousePixmap);
m_label->setScaledContents(true);
m_label->setVisible(false);
// 初始化计时器
m_timer = new QTimer(this);
connect(m_timer, SIGNAL(timeout()), this, SLOT(onTimerTimeout()));
m_timer->start(1000);
}
Widget::~Widget()
{
}
void Widget::onTimerTimeout()
{
// 随机选择一个地鼠出现位置
m_currentHoleIndex = qrand() % m_holes.size();
QLabel* hole = m_holes[m_currentHoleIndex];
// 设置地鼠位置和显示状态
m_label->setGeometry(hole->x() + 20, hole->y() + 20, 60, 60);
m_label->setVisible(true);
}
void Widget::onHoleClicked()
{
// 如果地鼠显示中,则判断是否被击中
if (m_label->isVisible()) {
int x = m_label->x();
int y = m_label->y();
// 判断是否在地鼠位置范围内
if (x >= m_holes[m_currentHoleIndex]->x() && x <= m_holes[m_currentHoleIndex]->x() + 100 &&
y >= m_holes[m_currentHoleIndex]->y() && y <= m_holes[m_currentHoleIndex]->y() + 100) {
// 击中地鼠,分数加一
m_score++;
m_scoreLabel->setText(QString("Score: %1").arg(m_score));
}
// 隐藏地鼠
m_label->setVisible(false);
}
}
bool Widget::eventFilter(QObject* watched, QEvent* event)
{
if (event->type() == QEvent::MouseButtonRelease) {
// 如果点击了地鼠出现位置标签控件,则处理点击事件
for (int i = 0; i < m_holes.size(); i++) {
if (m_holes[i] == watched) {
onHoleClicked();
return true;
}
}
}
return QWidget::eventFilter(watched, event);
}
```
最后,在主函数中创建窗口并运行应用程序:
```cpp
#include "widget.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
```
运行后,即可看到一个简单的打地鼠小游戏界面。