1、项目目的:
本项目主要通过编写贪吃蛇游戏来学习,熟悉Qt中封装的类。
2、编译环境
VS2019+Qt5.9
3、功能实现
主要实现下面所列基本功能:
控制贪吃蛇吃食物
表示蛇
控制贪吃蛇上下左右移动
控制食物的随机分配
控制蛇的增长
暂停游戏
结束游戏
本文福利,莬费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓
4、需求分析
4.1、控制贪吃蛇吃食物
4.1.1、表示蛇
贪吃蛇的核心功能就是控制贪吃蛇吃食物,我们很容易可以想到可以用一个个小方块来表示蛇身,那我们应该用什么样的容器来存储这些小方块呢?
蛇的移动我们可以理解为在蛇头处添加一个小方块,在蛇尾处删除掉一个小方块,如下图:
因此会在容器的头部进行插入操作,所以底层数据结构为数组的容器肯定不能选,因为数组的头部插入时间复杂度是o(n),链表就是个非常合适的数据结构,因为它在头部插入的时间复杂度是o(1),所以我们应该选底层数据结构为链表的容器,这里选的是QList,它是Qt中封装的一个类。用该容器存储蛇身后,在构造函数中对其进行初始化,再通过渲染函数将其画在界面里。
//SnakeWidget.h文件
class Snake : public QMainWindow
{
Q_OBJECT
public:
Snake(QWidget *parent = nullptr);
~Snake();
private:
Ui::SnakeClass ui;
//表示蛇
QList<QRectF> snake;
//表示蛇身的小方块的宽高
int nodeWidth = 20;
int nodeHeight = 20;
//渲染(绘图)
void paintEvent(QPaintEvent* event);
};
4.1.2、控制蛇上下移动
使用QTimer类定义一个定时器,该定时器不断地发出timeout信号,相应的槽函数就会不断地接收该信号来执行动作以控制蛇移动,然后不断地进行重新渲染,以达到蛇不断移动的效果。前面说过蛇的移动实际上是在头部增加一个小方块,在尾部删除一个小方块,因此我们可以封装4个成员函数分别控制蛇在4个方向的头部增加,同时再封装一个成员函数表示尾部的删除。
//SnakeWidget.h文件
class Snake : public QMainWindow
{
Q_OBJECT
public:
Snake(QWidget *parent = nullptr);
~Snake();
private:
Ui::SnakeClass ui;
//表示蛇
QList<QRectF> snake;
//表示蛇身的小方块的宽高
int nodeWidth = 20;
int nodeHeight = 20;
//定时器
QTimer* timer;
int time = 100;//超时时间间隔,单位毫秒
//渲染(绘图)
void paintEvent(QPaintEvent* event);
//4个成员函数控制蛇4个方向头部的增加
void addUp();
void addDown();
void addLeft();
void addRight();
//删除尾部
void deleteLast();
private slots:
void timeout();
};
4.1.3、控制食物的随机分配
食物可以用一个小方块来表示,然后封装一个成员函数来随机分配食物这个小方块的位置,先在构造函数中对其进行初始化,最后通过渲染函数将其画在界面中。
//SnakeWidget.h文件
class Snake : public QMainWindow
{
Q_OBJECT
public:
Snake(QWidget *parent = nullptr);
~Snake();
private:
Ui::SnakeClass ui;
//表示蛇
QList<QRectF> snake;
//食物
QRectF food;
//表示蛇身的小方块的宽高
int nodeWidth = 20;
int nodeHeight = 20;
//渲染(绘图)
void paintEvent(QPaintEvent* event);
//4个成员函数控制蛇4个方向的移动
void addUp();
void addDown();
void addLeft();
void addRight();
//添加食物
void addFood();
};
4.1.4、控制蛇的增长
我们只需判断蛇头小方块是否和食物小方块重合,一旦重合,那我们在头部多增加一个小方块,就表示蛇增长了。比如蛇朝右移动,我们在头部增加一个小方块,尾部删除一个小方块,表示蛇的移动,那现在,我们在头部增加两个小方块,在尾部删除一个小方块,就表示蛇增长了。
4.2、暂停游戏
当定时器调用stop()函数时就会停止发送timeout()信号,那么timeout()信号相应的槽函数也就停止执行,timeout()相应的槽函数是控制蛇移动的,timeout相应的槽函数停止执行,那么对应的蛇也就停止了移动,也就呈现出暂停的效果了。
timer->stop();
4.3、结束游戏
可以封装一个成员函数来判断游戏是否结束,这里判断游戏结束的标志就是蛇头碰到蛇身。
bool SnakeWideget::checkContact()
{
for (int i = 0; i < snake.length(); i++)
{
for (int j = i+1;j < snake.length(); j++)
{
if (snake[i] == snake[j])
return true;
}
}
return false;
}
本文福利,莬费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓