Qt精简版贪吃蛇小游戏

游戏说明
按方向键上下左右,可以实现蛇移动方向的改变。
游戏中会实时展示用户得分。

游戏截图:

首先是头文件部分:

#ifndef SNAKE_H
#define SNAKE_H

#include <QApplication>
#include <QWidget>
#include <QPainter>
#include <QTimer>
#include <QKeyEvent>
#include <QMessageBox>
#include <QPushButton>
#include <QLabel>
#include <QString>

#define QPushButton_STYTLE (QString("\
QPushButton\
{\
    font-family:Microsoft Yahei;\
    font-size:8pt;\
    color:white;\
    background-color:rgb(159, 78, 62);\
    border-radius:4px;\
}\
QPushButton:pressed\
{\
    background-color:rgb(14 , 135 , 10);\
    padding-left:2px;\
    padding-top:2px;\
}"))

#define QLabel_STYTLE (QString("\
QLabel\
{\
    font-family:Microsoft Yahei;\
    font-size:10pt;\
    color:orange;\
}"))


class Snake : public QWidget
{
public:
    Snake(QWidget *parent = nullptr);

protected:
    void paintEvent(QPaintEvent *event) override;
    void keyPressEvent(QKeyEvent *event) override;

private:
    enum Direction { Left, Right, Up, Down };
    QList<QPoint> snake;
    QPoint food;
    Direction direction = Left;
    QTimer *timer;
    void updateGame();
    QPushButton * startButton;
    QLabel * score;
    int scores = 0;
};



#endif // SNAKE_H

这是一个基于 Qt 框架的贪吃蛇游戏的类定义。该类继承自 QWidget 类,用于创建游戏窗口。该类中包含了一些私有成员变量和函数:

- `snake`:用于存储蛇的身体坐标;
- `food`:用于存储食物的坐标;
- `direction`:用于存储蛇的移动方向;
- `timer`:用于定时更新游戏状态;
- `startButton`:用于开始游戏的按钮;
- `score`:用于显示游戏得分的标签;
- `scores`:用于存储游戏得分。

该类中还包含了三个保护成员函数:

- `paintEvent`:用于绘制游戏界面;
- `keyPressEvent`:用于处理键盘事件,控制蛇的移动方向;
- `updateGame`:用于更新游戏状态,包括蛇的移动、食物的生成等。

该类中还定义了两个宏,分别用于设置按钮和标签的样式。

---------------------------------------------------------------------------------------------------------------------------------

然后是源文件部分:

#include "snake.h"

Snake::Snake(QWidget *parent)
    : QWidget(parent)
{
    setFixedSize(400, 400);
    this->setWindowTitle("snake");
    score = new QLabel(this);
    score->setText("scores: "+ QString::number(scores));
    score->setFocusPolicy(Qt::NoFocus);
    score->setGeometry(0,0,100,20);
    score->setStyleSheet(QLabel_STYTLE);
    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &Snake::updateGame);
    startButton = new QPushButton("start",this);
    startButton->setFocusPolicy(Qt::NoFocus);
    startButton->setGeometry(width()/2-30,height()/2+115,60,30);
    startButton->setStyleSheet(QPushButton_STYTLE);
    connect(startButton,&QPushButton::clicked,[&](){
        startButton->hide();
        food.setX(10);
        food.setY(10);
        snake.clear();
        snake.append(QPoint(20, 20));
        snake.append(QPoint(21, 20));
        score->setText("scores: 0");
        timer->start(300);
    });
}

void Snake::paintEvent(QPaintEvent *event)
{
    Q_UNUSED(event);
    QPainter painter(this);
    painter.setBrush(Qt::black);
    painter.drawRect(0, 0, width() - 1, height() - 1);
    if(!food.isNull())
    {
        painter.setBrush(Qt::green);
        painter.drawRect(food.x() * 10, food.y() * 10, 10, 10);
    }
    painter.setBrush(Qt::yellow);
    for (auto &part : snake)
        painter.drawRect(part.x() * 10, part.y() * 10, 10, 10);
}

void Snake::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Left && direction != Right)
        direction = Left;
    else if (event->key() == Qt::Key_Right && direction != Left)
        direction = Right;
    else if (event->key() == Qt::Key_Up && direction != Down)
        direction = Up;
    else if (event->key() == Qt::Key_Down && direction != Up)
        direction = Down;
}

void Snake::updateGame()
{
    auto head = snake.first();
    switch (direction) {
    case Left: head.rx()--; break;
    case Right: head.rx()++; break;
    case Up: head.ry()--; break;
    case Down: head.ry()++; break;
    }
    if (head == food) {
        food.setX(qrand() % (width() / 10));
        food.setY(qrand() % (height() / 10));
        score->setText("scores: "+ QString::number(++scores));
    } else {
        snake.removeLast();
    }

    if (head.x() < 0 || head.x() >= width() / 10 ||
            head.y() < 0 || head.y() >= height() / 10 ||
            (snake.count()>=3 && snake.contains(head))) {
        //此时count还没有加头部,实际长度短1,count 4及以上才触发相撞,故(>=4)应写做(>=3)
        timer->stop();
        QMessageBox::information(this, "Game Over", "You lost!");
        startButton->show();
    }

    snake.prepend(head);
    update();
}

其中,`Snake` 类继承自 `QWidget` 类,表示游戏界面。

在 `Snake` 类的构造函数中,设置窗口大小、标题、分数标签等,并连接计时器的超时信号到 `updateGame` 槽函数上。同时,创建一个开始按钮,并连接其点击信号到一个 Lambda 函数上,该函数负责初始化游戏状态并启动计时器。

在 `paintEvent` 函数中,通过 `QPainter` 实例对游戏界面进行绘制,包括绘制背景、食物和蛇身等。在 `keyPressEvent` 函数中,根据按键事件更新蛇的移动方向。

在 `updateGame` 函数中,根据当前蛇头位置和移动方向计算蛇的新位置,并根据新位置更新蛇的状态,包括增加长度、更新分数、判断是否游戏结束等。

最后,通过 `update` 函数触发 `paintEvent` 函数进行界面重绘。

源码下载:https://download.csdn.net/download/qq_73571591/87873476

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值