当前位置:   article > 正文

Qt实战案例(7)——利用Qt实现贪吃蛇小游戏_qt成功案例

qt成功案例

一、项目介绍

利用Qt实现贪吃蛇小游戏。

  1. 贪吃蛇的游戏界面为40*40的网格。
  2. 游戏界面上包括菜单栏、工具栏和按钮,三者均实现开始游戏、暂停游戏、继续游戏、重新开始、退出游戏、保存游戏、载入游戏的功能。
  3. 首次打开游戏,用户处于未开始状态,游戏界面上只存在初始贪吃蛇,初始贪吃蛇长度为2个网格,自行设定初始位置。
  4. 用户处于未开始状态时,通过鼠标点击空白网格,可以将对应网格置为障碍,再次点击障碍将其重置为空白网格。

二、详细介绍

2.1 开始游戏后

当点击开始游戏后,用户处于游戏状态,程序随机选择一个空白网格生成一个果实。此后,按任意方向键,贪吃蛇将向对应方向移动,并开始计时,移动速度由程序自行确定。要求游戏过程中,实时显示时间,即贪吃蛇头部移动的格子数。贪吃蛇吃到果实后,在接下来的3步中,头部延长3个格子,与此同时尾部保持不变。
点击暂停游戏后,游戏处于暂停状态,贪吃蛇的移动停止,游戏时间停止。

2.2 游戏暂停时

当处于暂停状态时,点击保存游戏,可以保存当前格局。由用户指定保存文件的名称与位置。文件格式自行设计,需包含贪吃蛇的状态,贪吃蛇的移动方向,障碍和果实位置,以及当前时间。
点击继续游戏后,贪吃蛇恢复移动,恢复计时,进入游戏状态 。

2.3 游戏失败后

满足失败条件时,游戏进入终止状态,提示游戏失败,游戏计时停止,贪吃蛇无法移动。失败条件:

  • 贪吃蛇碰到周围边界
  • 贪吃蛇碰到障碍
  • 贪吃蛇碰到自己的身体

2.4 未开始状态时

当游戏处于未开始状态时,点击载入游戏,可以选择文件,载入一个已保存的格局,此时游戏进入暂停状态。

2.5 暂停或终止状态时

当处于暂停状态或终止状态时,点击重新开始,用户变为未开始状态,计时清零,格局恢复为初始状态

2.6 其他说明

  • 游戏处于任何状态时,点击退出游戏,游戏直接关闭;
  • 特定状态下,某些按钮处于不可用状态:
    未开始状态:暂停游戏、继续游戏、重新开始、保存游戏处于不可用状态,开始游戏、退出游戏、载入游戏处于可用状态。
    游戏状态:开始游戏、载入游戏、继续游戏、重新开始、保存游戏处于不可用状态,退出游戏、暂停游戏处于可用状态。
    暂停状态:开始游戏、暂停游戏、载入游戏处于不可用状态,退出游戏、继续游戏、重新开始、保存游戏处于可用状态。
    终止状态:开始游戏、暂停游戏、继续游戏、载入游戏、保存游戏处于不可用状态,退出游戏、重新开始处于可用状态。

三、项目基本配置

3.1 新建

新建一个Qt案例,项目名称为“Snake”,基类选择“QMainWindow”。

四、UI界面设计

UI界面如下:
在这里插入图片描述

界面中包含了菜单栏、状态栏和工具栏,其中菜单栏和状态栏的主要内容如下:

名称类型包含的子控件
menubar菜单栏Game、Load/Save
toolbar工具栏startGame、pauseGame、continueGame、restartGame、quitGame、loadGame、saveGame

菜单栏menubar包含的子菜单名称如下表所示:

名称包含的子菜单名称
GamestartGame、pauseGame、continueGame、restartGame、quitGame
Load/SavestartGame、pauseGame、continueGame、restartGame、quitGame、loadGame、saveGame

【注】:这里菜单栏的子菜单(工具)与下文工具栏中的子控件相同,因此其详细功能将在下表中进行介绍。

工具栏toolbar包含的子控件如下表所示:

名称含义
startGame开始游戏
pauseGame暂停游戏
continueGame继续游戏
restartGame重新开始游戏
quitGame停止游戏
loadGame加载游戏
saveGame保存游戏

工具栏下方的7个QToolButton与底部的7个QPushButton与上方子控件功能一致,这里不再进行介绍。

五、主程序实现

完整程序由于太大,因此这里不再进行详细介绍,只对其中主要功能进行简要介绍。

5.1 mainwindow.h头文件

地图上每一个点看作一个Node结构体,结构体中对应记录了每一个节点的横、纵坐标,以及节点类型(0=empty, 1=border, 2=snake, 3=food)。Node结构体构造如下:

//包含每一个节点的横纵坐标和类型
struct Node {
    int x;
    int y;
    int type;
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

type类型包含包含空、障碍物、蛇、果实信息,定义为枚举类型,如下:

//type
enum Label {
    empty_lable,
    border_lable, 
    snake_label,
    food_label
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

定义游戏地图范围:

#define xlen 40
#define ylen 40
Node map[xlen+10][ylen+10]; //游戏地图
  • 1
  • 2
  • 3

5.2 mainwindow.cpp源文件

在代码中进行了详细注释,可以参考源程序。

六、游戏逻辑

地图上每一个点看作一个Node结构体,结构体中对应记录了每一个节点的横、纵坐标,以及节点类型(0=empty, 1=border, 2=snake, 3=food)。gameWidget包含一个40*40的节点二维数组记录所有节点信息。地图上所有的障碍物,蛇,果实信息都记录在了三个QList(border, snake, food)中,通过QList的remove, append函数结合update()调用的paintEvent()函数实现地图外观的动态变化。
gameWidget通过mousePressEvent(左键添加障碍物,右键取消障碍物),keyPressEvent(上下左右键改变dx,dy,空格键暂停游戏)来响应鼠标与键盘的操作。
初始化前,可以通过鼠标点击将空白节点设置为障碍物,蛇位于地图的左上角位置。游戏开始后,首先会随机生成一个食物。通过QTime类的timeout()信号触发gameWidget的moveSnakeSlot()槽:进入槽函数时,由于一个果实对应蛇长度伸长三,首先通过判断是否还没有完全伸长(通过int型成员bonus记录)判断尾巴是否需要“消失”。之后结合dx,dy判断蛇头下一个位置对应的节点类型:border与snake对应游戏结束,empty对应bonus不变,food对应bonus加3。更新地图信息与地图外观之后进入下一个moveSnake槽函数,从而实现了地图的动态变化。

七、效果演示

在这里插入图片描述

完整代码可参考:https://download.csdn.net/download/didi_ya/29077133
打包后的exe可执行文件可参考:https://download.csdn.net/download/didi_ya/29082456

ok,以上便是全部内容了,如果对你有所帮助,记得点个赞哟~
参考:
http://www.4399.com/flash/55486_4.htm

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/109957
推荐阅读