1、项目概述

1.1项目目标和主要内容

1)学习GUI图形界面的设计,基于C++ QT框架,创建交互友好的应用程序;

2)实现贪吃蛇游戏基本功能,屏幕上随机出现一个“食物”,称为豆子。玩家能利用上下左右键控制“蛇”的移动,“蛇”吃到“豆子”后“蛇”身体加长一节,得分增加,“蛇”碰到边界或蛇头与蛇身相撞,“蛇”死亡,游戏结束。

3)进行交互界面的设计,要有开始键、暂停键和停止退出的选项,能够控制游戏进程。对蛇吃到豆子进行分值计算,可以设置游戏速度、游戏音乐等拓展元素。

1.2项目的主要功能

1)游戏界面上可进行开始游戏、暂停游戏、重新开始、播放音乐操作;

2)首次打开游戏,用户处于未开始状态,游戏界面网格上存在初始贪吃蛇和食物。

3)点击开始游戏后,贪吃蛇开始按格子直线移动,可通过WASD键控制移动方向;

4)点击暂停游戏后贪吃蛇停止移动,点击开始游戏后继续移动,点击重新开始后游戏开新局,点击播放音乐后游戏播放音乐;

5)贪吃蛇吃到食物后自身长度加一、游戏分数加10分,贪吃蛇撞墙或撞自身后提示是否重新开始。

2、项目设计

2.1项目总体框架

整体项目分为UI绘制、贪吃蛇初始化、定时器、按键检测、UI更新、开始暂停逻辑按钮功能几个部分,通过定时器的开始关闭实现关联,程序功能都在程序MainWindow类中实现。

2.2系统详细设计

2.2.1 UI布局

首先在mainwindow.ui中添加控件进行初始布局,主要有四个按钮和spacer,布局界面如下:

贪吃蛇网格和显示结果等将通过程序进行布局添加。

2.2.2 构造函数

构造函数中首先将界面窗口尺寸固定为600*480,然后将ui文件中布局的四个逻辑QPushButton进行槽函数绑定实现各种功能,程序如下:

connect(ui->btn_start,SIGNAL(clicked()),this,SLOT(slot_start()));

connect(ui->btn_pause,SIGNAL(clicked()),this,SLOT(slot_pause()));

connect(ui->btn_restart,SIGNAL(clicked()),this,SLOT(slot_restart()));

connect(ui->btn_music,SIGNAL(clicked()),this,SLOT(slot_music()));

开始按钮与slot_start()绑定,实现开启定时器timer->start();暂停按钮与slot_ pause()绑定,实现关闭定时器timer->stop();停止按钮与slot_restart()绑定,弹窗提示是否重开,若不重开则直接返回,若重开则重新初始化再打开定时器:

if(box==QMessageBox::Yes){

InitSnake();

slot_update();

timer->start();

}

播放音乐按钮与slot_music绑定,通过QSound加载本地的音乐文件,然后播放:

QSound *startSound = new QSound(":/music.wav",this);

startSound->play();

2.2.3 paintEvent

若想将绘图加入事件循环中,QT共有两种方式:绘图事件和定时器事件,本程序通过定时器实现贪吃蛇的定时移动,通过绘图事件paintEvent进行绘图。paintEvent当窗口部件第一次加载显示时,系统会自动产生一个绘图事件从而触发执行,同时当执行函数调用update时也可以强制触发。如果多次调用update(),Qt会把连续多次的绘制事件压缩成一个单一的绘制事件,这样可避免闪烁现象。

paintEvent函数中首先调用InitSnake对贪吃蛇进行初始化,然后用QPainter先后画游戏背景、界面网格、显示分数、画蛇、画食物,在每次定时器执行刷新update时会重复执行上述过程。其中,画蛇是通过painter.drawRects对贪吃蛇信息vSnakeRect中数据进行方格绘制;画食物是通过painter.drawPixmap对本地的一张方格图进行铺放表示食物,该部分程序如下:

//画蛇

painter.setPen(Qt::black);

painter.setBrush(QBrush(Qt::white));

painter.drawRects(&vSnakeRect[0],vSnakeRect.size());

//画食物

painter.drawPixmap(Food,QPixmap(":/food.jpg"));

2.2.4 InitSnake

InitSnake在程序开始执行或需要重开时发生调用。首先通过初始设置blsRun、blsOver两个标志位来判断是否开始、是否结束,然后设置初始移动方向nDirection为2表示向下移动,然后通过调用CreateFood()方法随机初始化食物位置,CreateFood()程序如下:

QRect MainWindow::CreateFood()

{

int x,y;

x=qrand()%25;

y=qrand()%25;

QRect rect(10+x*10,80+y*10,10,10);

return rect;

}

然后对贪吃蛇进行初始化,贪吃蛇利用QVector<QRect>进行表示,n个小方块组成的vector代表蛇,初始化蛇长度为5。

最后设置定时器并绑定槽函数,QTimer计时器事件设置定时300ms,开启定时器后300ms执行一次slot_update函数,实现贪吃蛇移动和结果反馈,定时器部分程序如下:

timer=new QTimer(this);

timer->start(Speed);

timer->stop();

connect(timer,SIGNAL(timeout()),SLOT(slot_update()));

2.2.5 slot_update

slot_update为游戏开始后触发执行,实现控制贪吃蛇移动和结果判断功能。首先获取贪吃蛇vSnakeRect的头位置用于移动,然后将蛇身最后位置向前移动一位实现蛇身移动,程序如下:

SnakeHead=vSnakeRect.first();

for(int j=0;j<vSnakeRect.size()-1;j++){

vSnakeRect[vSnakeRect.size()-1-j]=vSnakeRect[vSnakeRect.size()-2-j];

}

对键盘按键keyPressEvent监听按下的键号,根据键号改变方向变量nDirection,W、S、A、D四个键分别表示上下左右,即nDirection的值分别为1、2、3、4。然后在slot_update中通过switch对nDirection进行判断,然后对SnakeHead进行位置更新,判断部分程序如下:

switch (nDirection) {

case 1:

SnakeHead.setTop(SnakeHead.top()-10);

SnakeHead.setBottom(SnakeHead.bottom()-10);

break;

case 2:

SnakeHead.setTop(SnakeHead.top()+10);

SnakeHead.setBottom(SnakeHead.bottom()+10);

break;

case 3:

SnakeHead.setLeft(SnakeHead.left()-10);

SnakeHead.setRight(SnakeHead.right()-10);

break;

case 4:

SnakeHead.setLeft(SnakeHead.left()+10);

SnakeHead.setRight(SnakeHead.right()+10);

break;

default:;

}

完成位置更新后,依次判断调用IsEat()、IsHit()、IsWin()三种方法对当前状态的游戏结果进行判断,即是否吃到、是否撞击、是否胜利。最后完成判断,调用update()触发paintEvent,实现游戏界面的重绘。

2.2.6 IsEatIsHitIsWin

三种方法对当前状态的游戏结果进行判断:

① IsEat:通过判断贪吃蛇头部SnakeHead方块与食物方块Food是否相等来确定是否吃到食物,若相等则在蛇身vSnakeRect末尾增加一位,并生成新的食物,同时游戏分数加10分,否则不执行任何操作,判断程序如下:

if(SnakeHead==Food){

SnakeHead=Food;

vSnakeRect.push_back(vSnakeRect.last());

Food = CreateFood();

Score=Score+10;

}

② IsHit:通过判断贪吃蛇头部SnakeHead方块位置来判断是否发生撞击,撞击分为两种:撞到了自己或墙壁。撞击自己通过遍历蛇身vSnakeRect的值,判断SnakeHead与vSnakeRect[i]是否相等实现,若相等则弹窗提示"游戏结束,是否重新开始?",点否则直接关闭定时器,继续游戏则重新初始化贪吃蛇并打开定时器执行,遍历判断部分程序如下:

for(int i=1;i<vSnakeRect.size();i++){

if(SnakeHead==vSnakeRect[i]){

撞墙则通判断SnakeHead的上下左右值分别与游戏运行边界值进行比较,若超过边界则弹窗提示"游戏结束,是否重新开始?",点否则直接关闭定时器,继续游戏则重新初始化贪吃蛇并打开定时器执行,判断边界的程序如下:

if (SnakeHead.left() <= 0 || SnakeHead.right() >= 599 || SnakeHead.y() <= 70 || SnakeHead.bottom() >= 479)

③ IsWin:通过判断当前得分是否到达500分来决定,达到500分则弹窗提示"恭喜获得胜利",同时将是否结束的标志位blsOver置为true。

3、项目实现及结果分析

3.1运行效果

下图为贪吃蛇运行打开默认界面:

下图为贪吃蛇游戏运行界面:

下图为贪吃蛇撞墙导致失败界面:

下图为贪吃蛇撞到自导致失败界面:

利用Qt实现贪吃蛇小游戏相关推荐

  1. Qt入门开发__贪吃蛇小游戏

    qt是一个由Qt Company于1991年开发的跨平台C++图形用户界面应用程序开发框架.它既可以开发GUI程序,也可用于开发非GUI程序(比如控制台工具和服务器).在图形用户界面开发相比MFC更加 ...

  2. C++/QT 贪吃蛇小游戏 界面设计

    C++/QT 贪吃蛇小游戏 界面设计 前言:本文所写的贪吃蛇是笔者初学QT练手的小项目,做出来的界面较为粗糙.由于很久没有接触C++,程序中类封装的不是很规范.写这篇文章,权当是记录生活了,手动狗头. ...

  3. python 贪吃蛇小游戏代码_10分钟再用Python编写贪吃蛇小游戏

    Python编写贪吃蛇 前不久我们公众号发布了一篇C++编写贪吃蛇小游戏的推文,反响空前.看来大家对这类简单易上手小游戏还是很喜爱的. 恰逢2018年IEEE Spectrum编程语言排行榜新鲜出炉, ...

  4. python小游戏编程实例-10分钟教你用Python写一个贪吃蛇小游戏,适合练手项目

    另外要注意:光理论是不够的.这里顺便总大家一套2020最新python入门到高级项目实战视频教程,可以去小编的Python交流.裙 :七衣衣九七七巴而五(数字的谐音)转换下可以找到了,还可以跟老司机交 ...

  5. python编程小游戏-10分钟用Python编写一个贪吃蛇小游戏,简单

    贪吃蛇,大家应该都玩过.小编当初第一次接触贪吃蛇的时候 ,还是能砸核桃的诺基亚上,当时玩的不亦乐乎.今天,我们用Python编程一个贪吃蛇游戏,下面我们先看看效果: 好了,先介绍一个思路 所有的游戏最 ...

  6. 基于stm32、0.96寸OLED实现的贪吃蛇小游戏(详细源码注释)

    简介:本实验基于stm32最小系统.0.96寸OLED(68*128)和摇杆实现一个经典的贪吃蛇小游戏.项目源码地址:点击下载. 硬件设计: 普通摇杆,0.96寸OLED 单色屏幕(SPI协议通讯), ...

  7. java贪吃蛇_如何用Java还原童年回忆?在线教你完成贪吃蛇小游戏

    今天我就从零开始来完成这个小游戏,完成的方式也是一步一步的添加功能这样的方式来实现. 额,不好意思,放错了,重来 第一步完成的功能:写一个界面 大家见到的贪吃蛇小游戏,界面肯定是少不了的.因此,第一步 ...

  8. 10分钟用python编写贪吃蛇小游戏_牛得一批!10分钟用Python编写一个贪吃蛇小游戏...

    贪吃蛇,大家应该都玩过.当初第一次接触贪吃蛇的时候 ,还是能砸核桃的诺基亚上,当时玩的不亦乐乎.今天,我们用Python编程一个贪吃蛇游戏,下面我们先看看效果: 好了,先介绍一个思路 所有的游戏最主要 ...

  9. 10分钟python游戏_牛得一批!10分钟用Python编写一个贪吃蛇小游戏

    贪吃蛇,大家应该都玩过.当初第一次接触贪吃蛇的时候 ,还是能砸核桃的诺基亚上,当时玩的不亦乐乎.今天,我们用Python编程一个贪吃蛇游戏,下面我们先看看效果: 好了,先介绍一个思路 所有的游戏最主要 ...

最新文章

  1. mybatis源码阅读
  2. We wear culture:Google 艺术与文化项目带你探秘穿在身上的文化
  3. IP Messenger程序
  4. 达梦数据迁移工具的使用
  5. wget for windows
  6. 数据可视化demo_火出圈的大屏你真的会做吗?这才是老板最爱的可视化大屏
  7. 从零实现深度学习框架——过拟合与欠拟合
  8. python中下划线开头的命名_Python中 5 种不同的下划线含义你都知道吗?
  9. Java工程师职业怎么规划?
  10. 教程篇(7.0) 10. FortiGate安全 反病毒 ❀ Fortinet 网络安全专家 NSE 4
  11. 80C51单片机的四组IO口
  12. PreScan快速入门到精通第三十二讲基于PreScan进行毫米波雷达传感器仿真
  13. iframe 用法总结
  14. JSP与JavaScript交互之(一)成绩信息输入的奖学金评定
  15. mysql成绩表_mysql--学生课程成绩表
  16. 11.组合查询union
  17. 群机器人积分怎么转赠_王者荣耀全员冲榜无法获得积分怎么办?全员冲榜积分规则...
  18. 《zw版·Halcon入门教程与内置demo》
  19. 将电脑内存插入其他未知导致开机报警
  20. react实现一个周日历表

热门文章

  1. 微信小程序商城搭建,微信小程序商城源码,微信小程序商城项目
  2. android+root+自动开机启动不了,【Android 11正式版】ROOT+Edxposed,解决刷入不兼容模块无法开机...
  3. 在react中用echarts实现3d地球
  4. Anaconda 安装FreeCAD
  5. 一个随机摇号的js脚本
  6. 清华“洗衣机系”学霸,如何在 GitHub 拿下 50000+Star?
  7. a标签点击事件,调用layui提示窗口,防止未确认就执行
  8. Geogebra下载【linux,MacOS,windows,iOS, Android】
  9. animate inater插件_Indesign插件合集
  10. JavaScript匿名函数(自调用函数)