游戏说明
按方向键上下左右,可以实现蛇移动方向的改变。
游戏中会实时展示用户得分。
游戏截图:
首先是头文件部分:
#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