利用Qt实现贪吃蛇小游戏
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 IsEat、IsHit、IsWin
三种方法对当前状态的游戏结果进行判断:
① 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实现贪吃蛇小游戏相关推荐
- Qt入门开发__贪吃蛇小游戏
qt是一个由Qt Company于1991年开发的跨平台C++图形用户界面应用程序开发框架.它既可以开发GUI程序,也可用于开发非GUI程序(比如控制台工具和服务器).在图形用户界面开发相比MFC更加 ...
- C++/QT 贪吃蛇小游戏 界面设计
C++/QT 贪吃蛇小游戏 界面设计 前言:本文所写的贪吃蛇是笔者初学QT练手的小项目,做出来的界面较为粗糙.由于很久没有接触C++,程序中类封装的不是很规范.写这篇文章,权当是记录生活了,手动狗头. ...
- python 贪吃蛇小游戏代码_10分钟再用Python编写贪吃蛇小游戏
Python编写贪吃蛇 前不久我们公众号发布了一篇C++编写贪吃蛇小游戏的推文,反响空前.看来大家对这类简单易上手小游戏还是很喜爱的. 恰逢2018年IEEE Spectrum编程语言排行榜新鲜出炉, ...
- python小游戏编程实例-10分钟教你用Python写一个贪吃蛇小游戏,适合练手项目
另外要注意:光理论是不够的.这里顺便总大家一套2020最新python入门到高级项目实战视频教程,可以去小编的Python交流.裙 :七衣衣九七七巴而五(数字的谐音)转换下可以找到了,还可以跟老司机交 ...
- python编程小游戏-10分钟用Python编写一个贪吃蛇小游戏,简单
贪吃蛇,大家应该都玩过.小编当初第一次接触贪吃蛇的时候 ,还是能砸核桃的诺基亚上,当时玩的不亦乐乎.今天,我们用Python编程一个贪吃蛇游戏,下面我们先看看效果: 好了,先介绍一个思路 所有的游戏最 ...
- 基于stm32、0.96寸OLED实现的贪吃蛇小游戏(详细源码注释)
简介:本实验基于stm32最小系统.0.96寸OLED(68*128)和摇杆实现一个经典的贪吃蛇小游戏.项目源码地址:点击下载. 硬件设计: 普通摇杆,0.96寸OLED 单色屏幕(SPI协议通讯), ...
- java贪吃蛇_如何用Java还原童年回忆?在线教你完成贪吃蛇小游戏
今天我就从零开始来完成这个小游戏,完成的方式也是一步一步的添加功能这样的方式来实现. 额,不好意思,放错了,重来 第一步完成的功能:写一个界面 大家见到的贪吃蛇小游戏,界面肯定是少不了的.因此,第一步 ...
- 10分钟用python编写贪吃蛇小游戏_牛得一批!10分钟用Python编写一个贪吃蛇小游戏...
贪吃蛇,大家应该都玩过.当初第一次接触贪吃蛇的时候 ,还是能砸核桃的诺基亚上,当时玩的不亦乐乎.今天,我们用Python编程一个贪吃蛇游戏,下面我们先看看效果: 好了,先介绍一个思路 所有的游戏最主要 ...
- 10分钟python游戏_牛得一批!10分钟用Python编写一个贪吃蛇小游戏
贪吃蛇,大家应该都玩过.当初第一次接触贪吃蛇的时候 ,还是能砸核桃的诺基亚上,当时玩的不亦乐乎.今天,我们用Python编程一个贪吃蛇游戏,下面我们先看看效果: 好了,先介绍一个思路 所有的游戏最主要 ...
最新文章
- mybatis源码阅读
- We wear culture:Google 艺术与文化项目带你探秘穿在身上的文化
- IP Messenger程序
- 达梦数据迁移工具的使用
- wget for windows
- 数据可视化demo_火出圈的大屏你真的会做吗?这才是老板最爱的可视化大屏
- 从零实现深度学习框架——过拟合与欠拟合
- python中下划线开头的命名_Python中 5 种不同的下划线含义你都知道吗?
- Java工程师职业怎么规划?
- 教程篇(7.0) 10. FortiGate安全 反病毒 ❀ Fortinet 网络安全专家 NSE 4
- 80C51单片机的四组IO口
- PreScan快速入门到精通第三十二讲基于PreScan进行毫米波雷达传感器仿真
- iframe 用法总结
- JSP与JavaScript交互之(一)成绩信息输入的奖学金评定
- mysql成绩表_mysql--学生课程成绩表
- 11.组合查询union
- 群机器人积分怎么转赠_王者荣耀全员冲榜无法获得积分怎么办?全员冲榜积分规则...
- 《zw版·Halcon入门教程与内置demo》
- 将电脑内存插入其他未知导致开机报警
- react实现一个周日历表
热门文章
- 微信小程序商城搭建,微信小程序商城源码,微信小程序商城项目
- android+root+自动开机启动不了,【Android 11正式版】ROOT+Edxposed,解决刷入不兼容模块无法开机...
- 在react中用echarts实现3d地球
- Anaconda 安装FreeCAD
- 一个随机摇号的js脚本
- 清华“洗衣机系”学霸,如何在 GitHub 拿下 50000+Star?
- a标签点击事件,调用layui提示窗口,防止未确认就执行
- Geogebra下载【linux,MacOS,windows,iOS, Android】
- animate inater插件_Indesign插件合集
- JavaScript匿名函数(自调用函数)