Qt小游戏:贪吃蛇

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模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

猜你喜欢

转载自blog.csdn.net/m0_73443478/article/details/131686966
今日推荐