python做的网站有什么漏洞广州最新新闻

张小明 2026/1/19 22:24:03
python做的网站有什么漏洞,广州最新新闻,seo优化工具,wordpress 4.5.1基于QT实现的翻金币游戏一、设计题目基于QT实现的翻金币游戏二、开发环境硬件环境#xff1a;微机系列#xff0c;内存在1G以上软件环境#xff1a;Microsoft Windows 10家庭版三、开发工具Qt Creator 4.11、HM NIS、NSIS#xff08;客户端打包程序#xff09;四、设计思想…基于QT实现的翻金币游戏一、设计题目基于QT实现的翻金币游戏二、开发环境硬件环境微机系列内存在1G以上软件环境Microsoft Windows 10家庭版三、开发工具Qt Creator 4.11、HM NIS、NSIS客户端打包程序四、设计思想4.1 游戏的组成我认为游戏的组成主要是两个部分游戏资源和游戏机制。游戏资源泛指游戏中给用户提供的视听资源比如游戏的场景各种道具和角色的外观游戏音乐与用户进行交互的界面等。游戏机制泛指游戏中实现游戏运作的方式在翻金币小游戏中怎么排列金币如何翻转金币如何判断游戏的胜利与失败这种对于用户来讲相对隐式的存在却在游戏开发中占据核心地位。游戏机制的实现通常需要数据结构与相关算法的结合。4.2 游戏设计要点再设计游戏时因为此项目窗口较多因此在对于各个窗口的选择上是一个比较需要注意的地方。在初始化各种窗口的时候是选择QMainWindowQwidget还是QDialog类型呢这个主要看该窗口的功能如果作为主窗口比如交互窗口游戏窗口存在的话选择QMainWindow类型最合适因为QMainWindow可以搭载工具栏和状态栏这些功能选择组件在小游戏里面是很实用的尤其是工具栏。至于QDialog则用于对话窗口单方向地由软件向用户发送信息一般不做交互游戏的游戏说明提示警告都适合使用QDialog类型。QWidget适合用来自定义组件这次的项目中没有组合类的自定义组件因此没有使用。该项目中自定义的是单个类型的组件新的按钮所以直接去继承QT里面的button类就可以了。4.3 游戏的主内容分析我们结合游戏的规则来分析初始钱币分布的处理方式。在翻金币游戏中银色的钱币实际上是钱币的反面金色的钱币是钱币的正面翻金币游戏的游玩方式是点击一枚硬币一次令其实现一次正反翻转同时使得该硬币的上下左右四个钱币跟随其一起翻转也就是一次最多能翻转五个硬币。翻金币游戏的成功条件是16个硬币全部为正面金币就取得胜利。我们可以简化一下内容再分析其本质比如说“该硬币的上下左右四个钱币跟着一起翻转”这个在设计思路上是不太重要的因为你只要实现了一个硬币的翻转其余的硬币你同时想翻几个就翻几个因此可以暂时不考虑。这样的话游戏流程应该使用代码实现特定的初始的关卡钱币排列、单个钱币的翻转、胜利条件的判断与游戏终止三个主内容。了解研究内容了之后我们继续思考更细节层次的实现。4.4 初始排列方式的分析首先每一个关卡都是一个固定的排列方式其次该排列方式是个二维矩阵。固定阵列一下子就想到二维数组了。我们可以认为应该创建20个二维数组因为一共有20个关卡对应20个关卡的初始阵列当开始初始化加载游戏界面内的钱币时加载对应的二维数组对该二维数组进行遍历后判断阵列中的金币银币分布情况。4.5 游戏核心元素的分析游戏的核心元素显而易见钱币。道理也很简单游戏里银币是钱币金币是钱币玩家能操作的也只有钱币最后构成胜负条件的也还是钱币钱币不当核心元素天理难容。既然是个核心元素就要考虑为它设计一个类。该类从目前来分析应当至少包含以下几个元素1.金币与银币的图片加载2.要区分金币还是银币应该有一个标志位目前来看这两个要素是必须的。4.6 游戏操作的分析游戏内的操作只有翻转硬币这一项。既然我们有了钱币类钱币对象还有判断正反的标志位那么翻转就变得比较简单了。不过游戏的操作过程中肯定不能让钱币瞬间翻转应该是要加入一个动画特效进去的因此在钱币类中应该还要加入3.钱币翻转的动画特效。4.7 游戏胜负判断的分析翻金币游戏本质上和五子棋这类游戏的胜负判断是相同的也就是说每执行一步操作都应当对整个游戏界面内的元素阵列做一个分析来判断是否达成胜利条件。五、设计过程及设计步骤5.1 游戏总体设计翻金币游戏分为三大场景分别为主场景、选择关卡场景、翻金币场景。分别实现不同的游戏功能本游戏一共有二十关可以从第一关开始接着来当完成第一关之后会自动跳到下一关还可以直接选择自己想要闯的关卡。进入关卡之后会有一个4*4的网格里面分布着金币和银币点击银币它本身和附近的币就会翻面当网格中只剩金币时闯关成功。游戏的总体流程图如图6.1下所示图6.1 总体流程图5.2 主场景5.2.1 设置游戏主场景配置点击mainscene.ui文件设计其菜单栏如下设计“退出”菜单项objectName为 actionQuit text 为 退出移除自带的工具栏与状态栏回到MainScene.cpp文件进入构造函数中进行场景的基本配置代码如下//设置固定大小 this-setFixedSize(320,588); //设置应用图片 this-setWindowIcon(QPixmap(:/res/Coin0001.png)); //设置窗口标题 this-setWindowTitle(翻金币);运行效果如图实现点击开始退出游戏功能代码如下//点击退出退出程序 connect(ui-actionQuit,QAction::triggered,[](){this-close();});5.2.2 设置背景图片重写MainScene的PaintEvent事件并添加一下代码绘制背景图片void MainScene::paintEvent(QPaintEvent *) { //创建画家指定绘图设备 QPainter painter(this); //创建QPixmap对象 QPixmap pix; //加载图片 pix.load(:/res/PlayLevelSceneBg.png); //绘制背景图 painter.drawPixmap(0,0,this-width(),this-height(),pix); //加载标题 pix.load(:/res/Title.png); //缩放图片 pix pix.scaled(pix.width()*0.5,pix.height()*0.5); //绘制标题 painter.drawPixmap( 10,30,pix.width(),pix.height(),pix); }运行效果如图5.2.3 创建开始按钮开始按钮点击后有弹跳效果这个效果是我们利用自定义控件实现的QPushButton不会自带这类特效我们可以自己封装出一个按钮控件来实现这些效果。创建MyPushButton继承与QPushButton点击完成。修改MyPushButton的父类提供MyPushButton的构造的重载版本可以让MyPushButton提供正常显示的图片以及按下后显示的图片代码如下//normalImg 代表正常显示的图片 //pressImg 代表按下后显示的图片默认为空 MyPushButton(QString normalImg,QString pressImg ); QString normalImgPath; //默认显示图片路径 QString pressedImgPath; //按下后显示图片路径实现的重载版本MyPushButton构造函数代码如下MyPushButton::MyPushButton(QString normalImg,QString pressImg) { //成员变量normalImgPath保存正常显示图片路径 normalImgPath normalImg; //成员变量pressedImgPath保存按下后显示的图片 pressedImgPath pressImg; //创建QPixmap对象 QPixmap pixmap; //判断是否能够加载正常显示的图片若不能提示加载失败 bool ret pixmap.load(normalImgPath); if(!ret) { qDebug() normalImg 加载图片失败!; } //设置图片的固定尺寸 this-setFixedSize( pixmap.width(), pixmap.height() ); //设置不规则图片的样式表 this-setStyleSheet(QPushButton{border:0px;}); //设置图标 this-setIcon(pixmap); //设置图标大小 this-setIconSize(QSize(pixmap.width(),pixmap.height())); }回到MainScene的构造函数中创建开始按钮//创建开始按钮 MyPushButton * startBtn new MyPushButton(:/res/MenuSceneStartButton.png); startBtn-setParent(this); startBtn-move(this-width()*0.5-startBtn-width()*0.5,this-height()*0.7);运行效果如图不规则的开始按钮添加完成。5.2.4 开始按钮跳跃特效实现连接信号槽监听开始按钮点击//监听点击事件执行特效 connect(startBtn,MyPushButton::clicked,[](){ startBtn-zoom1(); //向下跳跃 startBtn-zoom2(); //向上跳跃 });zoom1与zoom2 为MyPushButton中扩展的特效代码具体如下void MyPushButton::zoom1() { //创建动画对象 QPropertyAnimation * animation1 new QPropertyAnimation(this,geometry); //设置时间间隔单位毫秒 animation1-setDuration(200); //创建起始位置 animation1-setStartValue(QRect(this-x(),this-y(),this-width(),this-height())); //创建结束位置 animation1-setEndValue(QRect(this-x(),this-y()10,this-width(),this-height())); //设置缓和曲线QEasingCurve::OutBounce 为弹跳效果 animation1-setEasingCurve(QEasingCurve::OutBounce); //开始执行动画 animation1-start(QAbstractAnimation::DeleteWhenStopped); } void MyPushButton::zoom2() { QPropertyAnimation * animation1 new QPropertyAnimation(this,geometry); animation1-setDuration(200); animation1-setStartValue(QRect(this-x(),this-y()10,this-width(),this-height())); animation1-setEndValue(QRect(this-x(),this-y(),this-width(),this-height())); animation1-setEasingCurve(QEasingCurve::OutBounce); animation1-start(QAbstractAnimation::DeleteWhenStopped); }运行代码点击按钮测试弹跳效果。5.2.5 创建选择关卡场景点击开始按钮后进入选择关卡场景。首先我们先创建选择关卡场景添加新的C文件类名为ChooseLevelScene 选择基类为QMainWindow点击下一步然后点击完成。5.2.6 点击开始按钮进入选择关卡场景目前点击主场景的开始按钮只有弹跳特效但是我们还需要有功能上的实现特效结束后我们应该进入选择关卡场景在MainScene.h中 保存ChooseScene选择关卡场景对象//选择关卡场景 ChooseLevelScene *chooseScene new ChooseLevelScene;我们在zoom1和zoom2特效后延时0.5秒进入选择关卡场景代码如下//延时0.5秒后 进入选择场景 QTimer::singleShot(500, this,[](){ this-hide(); chooseScene-show(); });测试点击开始执行特效后延时0.5秒进入选择关卡场景5.3 选择关卡场景5.3.1 场景基本设置选择关卡构造函数如下//设置窗口固定大小 this-setFixedSize(320,588); //设置图标 this-setWindowIcon(QPixmap(:/res/Coin0001.png)); //设置标题 this-setWindowTitle(选择关卡); //创建菜单栏 QMenuBar * bar this-menuBar(); this-setMenuBar(bar); //创建开始菜单 QMenu * startMenu bar-addMenu(开始); //创建按钮菜单项 QAction * quitAction startMenu-addAction(退出); //点击退出 退出游戏 connect(quitAction,QAction::triggered,[](){this-close();});运行效果如图5.3.2 背景设置void ChooseLevelScene::paintEvent(QPaintEvent *) { QPainter painter(this); QPixmap pix; pix.load(:/res/OtherSceneBg.png); painter.drawPixmap(0,0,this-width(),this-height(),pix); //加载标题 pix.load(:/res/Title.png); painter.drawPixmap( (this-width() - pix.width())*0.5,30,pix.width(),pix.height(),pix); }创建返回按钮//返回按钮 MyPushButton * closeBtn new MyPushButton(:/res/BackButton.png,:/res/BackButtonSelected.png); closeBtn-setParent(this); closeBtn-move(this-width()-closeBtn-width(),this-height()-closeBtn-height());返回按钮是有正常显示图片和点击后显示图片的两种模式所以我们需要重写MyPushButton中的 MousePressEvent和MouseReleaseEvent//鼠标事件 void MyPushButton::mousePressEvent(QMouseEvent *e) { if(pressedImgPath ! ) { //选中路径不为空显示选中图片 QPixmap pixmap; bool ret pixmap.load(pressedImgPath); if(!ret){ qDebug() pressedImgPath 加载图片失败!; } this-setFixedSize( pixmap.width(), pixmap.height() ); this-setStyleSheet(QPushButton{border:0px;}); this-setIcon(pixmap); this-setIconSize(QSize(pixmap.width(),pixmap.height())); } //交给父类执行按下事件 return QPushButton::mousePressEvent(e); } void MyPushButton::mouseReleaseEvent(QMouseEvent *e) { if(normalImgPath ! ) { //选中路径不为空显示选中图片 QPixmap pixmap; bool ret pixmap.load(normalImgPath); if(!ret) { qDebug() normalImgPath 加载图片失败!; } this-setFixedSize( pixmap.width(), pixmap.height() ); this-setStyleSheet(QPushButton{border:0px;}); this-setIcon(pixmap); this-setIconSize(QSize(pixmap.width(),pixmap.height())); } //交给父类执行 释放事件 return QPushButton::mouseReleaseEvent(e); }5.3.3 返回按钮在这里我们点击返回后延时0.5后隐藏自身并且发送自定义信号告诉外界自身已经选择了返回按钮。//返回按钮功能实现 connect(closeBtn,MyPushButton::clicked,[](){ QTimer::singleShot(500, this,[](){ this-hide(); //触发自定义信号关闭自身该信号写到 signals下做声明 emit this-chooseSceneBack(); } ); });在主场景MainScene中 点击开始按钮显示选择关卡的同时监听选择关卡的返回按钮消息//监听选择场景的返回按钮 connect(chooseScene,ChooseLevelScene::chooseSceneBack,[](){ chooseScene -hide(); this-show(); });测试主场景与选择关卡场景的切换功能。5.3.4 创建选择关卡按钮//创建关卡按钮 for(int i 0 ; i 20;i) { MyPushButton * menuBtn new MyPushButton(:/res/LevelIcon.png); menuBtn-setParent(this); menuBtn-move(25 (i%4)*70 , 130 (i/4)*70); //按钮上显示的文字 QLabel * label new QLabel; label-setParent(this); label-setFixedSize(menuBtn-width(),menuBtn-height()); label-setText(QString::number(i1)); label-setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); //设置居中 label-move(25 (i%4)*70 , 130 (i/4)*70); label-setAttribute(Qt::WA_TransparentForMouseEvents,true); //鼠标事件穿透 }运行效果如果5.3.5 创建翻金币场景点击关卡按钮后会进入游戏的核心场景也就是翻金币的场景首先先创建出该场景的.h和.cpp文件创建PlayScene点击选择关卡按钮后会跳入到该场景建立点击按钮跳转场景的信号槽连接在ChooseLevelScene.h 中声明PlayScene *pScene NULL; //监听选择关卡按钮的信号槽 connect(menuBtn,MyPushButton::clicked,[](){ // qDebug() select: i; if(pScene NULL) //游戏场景最好不用复用直接移除掉创建新的场景 { this-hide(); pScene new PlayScene(i1); //将选择的关卡号 传入给PlayerScene pScene-show(); } });这里pScene new PlayScene(i1); 将用户所选的关卡号发送给pScene也就是翻金币场景当然PlayScene 要提供重载的有参构造版本来接受这个参数5.4 翻金币场景5.4.1 场景基本设置PlayScene.h中 声明成员变量用于记录当前用户选择的关卡//成员变量 记录关卡索引 int levalIndex;PlayScene.cpp中 初始化该场景配置PlayScene::PlayScene(int index) { //qDebug() 当前关卡为 index; this-levalIndex index; //设置窗口固定大小 this-setFixedSize(320,588); //设置图标 this-setWindowIcon(QPixmap(:/res/Coin0001.png)); //设置标题 this-setWindowTitle(翻金币); //创建菜单栏 QMenuBar * bar this-menuBar(); this-setMenuBar(bar); //创建开始菜单 QMenu * startMenu bar-addMenu(开始); //创建按钮菜单项 QAction * quitAction startMenu-addAction(退出); //点击退出 退出游戏 connect(quitAction,QAction::triggered,[](){this-close();}); }5.4.2 背景设置void PlayScene::paintEvent(QPaintEvent *) { //加载背景 QPainter painter(this); QPixmap pix; pix.load(:/res/PlayLevelSceneBg.png); painter.drawPixmap(0,0,this-width(),this-height(),pix); //加载标题 pix.load(:/res/Title.png); pix pix.scaled(pix.width()*0.5,pix.height()*0.5); painter.drawPixmap( 10,30,pix.width(),pix.height(),pix); }5.4.3 返回按钮//返回按钮 MyPushButton * closeBtn new MyPushButton(:/res/BackButton.png,:/res/BackButtonSelected.png); closeBtn-setParent(this); closeBtn-move(this-width()-closeBtn-width(),this-height()-closeBtn-height()); //返回按钮功能实现 connect(closeBtn,MyPushButton::clicked,[](){ QTimer::singleShot(500, this,[](){ this-hide(); //触发自定义信号关闭自身该信号写到 signals下做声明 emit this-chooseSceneBack(); } ); });在ChooseScene选择关卡场景中监听PlayScene的返回信号connect(pScene,PlayScene::chooseSceneBack,[](){ this-show(); delete pScene; pScene NULL; });5.4.4 显示当前关卡//当前关卡标题 QLabel * label new QLabel; label-setParent(this); QFont font; font.setFamily(华文新魏); font.setPointSize(20); label-setFont(font); QString str QString(Leavel: %1).arg(this-levalIndex); label-setText(str); label-setGeometry(QRect(30,this-height() - 50, this-width(),50 )); label-setAttribute(Qt::WA_TransparentForMouseEvents);假设我们选择了第15关卡运行效果如果5.4.5 创建金币背景图片//创建金币的背景图片 for(int i 0 ; i 4;i) { for(int j 0 ; j 4; j) { //绘制背景图片 QLabel* label new QLabel; label-setGeometry(0,0,50,50); label-setPixmap(QPixmap(:/res/BoardNode.png)); label-setParent(this); label-move(57 i*50,200j*50); } }运行效果如图5.4.6 创建金币类我们知道金币是本游戏的核心对象并且在游戏中可以利用二维数组进行维护拥有支持点击翻转特效等特殊性因此不妨将金币单独封装到一个类中完成金币所需的所有功能。创建金币类 MyCoin并修改MyCoin的基类为QPushButton构造函数在资源图片中我们可以看到金币翻转的效果原理是多张图片切换而形成的而以下八张图片中第一张与最后一张比较特殊因此我们在给用户看的时候无非是金币Coin0001或者是银币 Coin0008这两种图。因此我们在创建一个金币对象时候应该提供一个参数代表着传入的是金币资源路径还是银币资源路径根据路径我们创建不同样式的图案。在MyCoin.h中声明MyCoin(QString butImg); //代表图片路径在MyCoin.cpp中进行实现MyCoin::MyCoin(QString butImg) { QPixmap pixmap; bool ret pixmap.load(butImg); if(!ret) { qDebug() butImg 加载图片失败!; } this-setFixedSize( pixmap.width(), pixmap.height() ); this-setStyleSheet(QPushButton{border:0px;}); this-setIcon(pixmap); this-setIconSize(QSize(pixmap.width(),pixmap.height())); }测试在翻金币场景 PlayScene中我们测试下封装的金币类是否可用可以在创建好的金币背景代码后添加如下代码//金币对象 MyCoin * coin new MyCoin(:/res/Coin0001.png); coin-setParent(this); coin-move(59 i*50,204j*50);运行效果如图5.5 引入关卡数据当然上述的测试只是为了让我们知道提供的对外接口可行但是每个关卡的初始化界面并非如此因此需要我们引用一个现有的关卡文件文件中记录了各个关卡的金币排列清空也就是二维数组的数值。5.5.1 添加现有文件dataConfig首先先将dataConfig.h 和 dataConfig.cpp文件放入到当前项目下5.5.2 添加现有文件其次在Qt_Creator项目右键点击添加现有文件5.5.3 完成添加选择当前项目下的文件并进行添加5.5.4 数据分析我们可以看到其实dataConfig.h中只有一个数据是对外提供的如下图在上图中QMapint,QVectorQVectormData;都记录着每个关卡中的数据。其中int代表对应的关卡 也就是QMap中的key值而value值就是对应的二维数组我们利用的是 QVectorQVector来记录着其中的二维数组。5.5.5 测试关卡数据在Main函数可以测试第一关的数据添加如下代码dataConfig config; for(int i 0 ; i 4;i) { for(int j 0 ; j 4; j) { //打印第一关所有信息 qDebug() config.mData[1][i][j]; } qDebug() ; }输出结果如下图对应着dataConfig.cpp中第一关数据来看与之匹配成功以后我们就可以用dataConfig中的数据来对关卡进行初始化了5.6 初始化各个关卡首先可以在playScene中声明一个成员变量用户记录当前关卡的二维数组int gameArray[4][4]; //二维数组数据之后在.cpp文件中初始化这个二维数组//初始化二维数组 dataConfig config; for(int i 0 ; i 4;i) { for(int j 0 ; j 4; j) { gameArray[i][j] config.mData[this-levalIndex][i][j]; } }初始化成功后在金币类 也就是MyCoin类中扩展属性 posXposY以及flag这三个属性分别代表了该金币在二维数组中 x的坐标y的坐标以及当前的正反标志。int posX; //x坐标 int posY; //y坐标 bool flag; //正反标志然后完成金币初始化代码如下//金币对象 QString img; if(gameArray[i][j] 1) { img :/res/Coin0001.png; } else { img :/res/Coin0008.png; } MyCoin * coin new MyCoin(img); coin-setParent(this); coin-move(59 i*50,204j*50); coin-posX i; //记录x坐标 coin-posY j; //记录y坐标 coin-flag gameArray[i][j]; //记录正反标志运行测试各个关卡初始化例如第一关效果如图5.7 翻金币特效5.7.1 MyCoin类扩展属性和行为关卡的初始化完成后下面就应该点击金币进行翻转的效果了那么首先我们先在MyCoin类中创建出该方法。在MyCoin.h中声明void changeFlag();//改变标志,执行翻转效果 QTimer *timer1; //正面翻反面 定时器 QTimer *timer2; //反面翻正面 定时器 int min 1; //最小图片 int max 8; //最大图片MyCoin.cpp中做实现void MyCoin::changeFlag() { if(this-flag) { //如果是正面执行下列代码 timer1-start(30); this-flag false; } else //反面执行下列代码 { timer2-start(30); this-flag true; } }当然在构造函数中记得创建出两个定时器//初始化定时器 timer1 new QTimer(this); timer2 new QTimer(this);5.7.2 创建特效当我们分别启动两个定时器时需要在构造函数中做监听操作并且做出响应翻转金币然后再结束定时器。构造函数中 进行下列监听代码//监听正面翻转的信号槽 connect(timer1,QTimer::timeout,[](){ QPixmap pixmap; QString str QString(:/res/Coin000%1.png).arg(this-min); pixmap.load(str); this-setFixedSize(pixmap.width(),pixmap.height() ); this-setStyleSheet(QPushButton{border:0px;}); this-setIcon(pixmap); this-setIconSize(QSize(pixmap.width(),pixmap.height())); if(this-min this-max) //如果大于最大值重置最小值并停止定时器 { this-min 1; timer1-stop(); } }); connect(timer2,QTimer::timeout,[](){ QPixmap pixmap; QString str QString(:/res/Coin000%1.png).arg((this-max)-- ); pixmap.load(str); this-setFixedSize(pixmap.width(),pixmap.height() ); this-setStyleSheet(QPushButton{border:0px;}); this-setIcon(pixmap); this-setIconSize(QSize(pixmap.width(),pixmap.height())); if(this-max this-min) //如果小于最小值重置最大值并停止定时器 { this-max 8; timer2-stop(); } });测试监听每个按钮的点击效果并翻转金币connect(coin,MyCoin::clicked,[](){ //qDebug() 点击的位置 x coin-posX y coin-posY ; coin-changeFlag(); gameArray[i][j] gameArray[i][j] 0 ? 1 : 0; //数组内部记录的标志同步修改 });5.7.3 禁用按钮此时确实已经可以执行翻转金币代码了但是如果快速点击会在金币还没有执行一个完整动作之后 又继续开始新的动画我们应该在金币做动画期间禁止再次点击并在完成动画后开启点击。在MyCoin类中加入一个标志 isAnimation 代表是否正在做翻转动画默认isAnimation值为false。bool isAnimation false; //做翻转动画的标志在MyCoin做动画期间加入this-isAnimation true;也就是changeFlag函数中将标志设为true加入位置如下并且在做完动画时将标志改为false重写按钮的按下事件判断如果正在执行动画那么直接return掉不要执行后续代码。代码如下void MyCoin::mousePressEvent(QMouseEvent *e) { if(this-isAnimation ){ return; } else{ return QPushButton::mousePressEvent(e); } }5.8 翻周围金币将用户点击的周围 上下左右4个金币也进行延时翻转代码写到监听点击金币下。此时我们发现还需要记录住每个按钮的内容所以我们将所有金币按钮也放到一个二维数组中在.h中声明MyCoin * coinBtn[4][4]; //金币按钮数组并且记录每个按钮的位置coinBtn[i][j] coin;延时翻动其他周围金币QTimer::singleShot(300, this,[](){ if(coin-posX1 3) { coinBtn[coin-posX1][coin-posY]-changeFlag(); gameArray[coin-posX1][coin-posY] gameArray[coin-posX1][coin-posY] 0 ? 1 : 0; } if(coin-posX-10){ coinBtn[coin-posX-1][coin-posY]-changeFlag(); gameArray[coin-posX-1][coin-posY] gameArray[coin-posX-1][coin-posY] 0 ? 1 : 0; } if(coin-posY13) { coinBtn[coin-posX][coin-posY1]-changeFlag(); gameArray[coin-posX][coin-posY1] gameArray[coin-posX1][coin-posY] 0 ? 1 : 0; } if(coin-posY-10){ coinBtn[coin-posX][coin-posY-1]-changeFlag(); gameArray[coin-posX][coin-posY-1] gameArray[coin-posX1][coin-posY] 0 ? 1 : 0; } });5.9 判断是否胜利在PlayScene.h中加入 isWin标志代表是否胜利。bool isWin true; //是否胜利默认设置为true只要有一个反面的金币就将该值改为false视为未成功。代码写到延时翻金币后 进行判断//判断是否胜利 this-isWin true; for(int i 0 ; i 4;i) { for(int j 0 ; j 4; j) { //qDebug() coinBtn[i][j]-flag ; if( coinBtn[i][j]-flag false) { this-isWin false; break; } } }如果isWin依然是true代表胜利了if(this-isWin) { qDebug() 胜利; }5.10 胜利图片显示将胜利的图片提前创建好如果胜利触发了将图片弹下来即可QLabel* winLabel new QLabel; QPixmap tmpPix; tmpPix.load(:/res/LevelCompletedDialogBg.png); winLabel-setGeometry(0,0,tmpPix.width(),tmpPix.height()); winLabel-setPixmap(tmpPix); winLabel-setParent(this); winLabel-move( (this-width() - tmpPix.width())*0.5 , -tmpPix.height());如果胜利了将上面的图片移动下来if(this-isWin) { qDebug() 胜利; QPropertyAnimation * animation1 new QPropertyAnimation(winLabel,geometry); animation1-setDuration(1000); animation1-setStartValue(QRect(winLabel-x(),winLabel-y(),winLabel-width(),winLabel-height())); animation1-setEndValue(QRect(winLabel-x(),winLabel-y()114,winLabel-width(),winLabel-height())); animation1-setEasingCurve(QEasingCurve::OutBounce); animation1-start(QAbstractAnimation::DeleteWhenStopped); }5.11 胜利后禁用按钮当胜利后应该禁用所有按钮的点击状态可以在每个按钮中加入标志位 isWin如果isWin为trueMousePressEvent直接return掉即可MyCoin中.h里添加bool isWin false;//胜利标志在鼠标按下事件中修改为void MyCoin::mousePressEvent(QMouseEvent *e) { if(this-isAnimation|| isWin true ) { return; } else { return QPushButton::mousePressEvent(e); } } //禁用所有按钮点击事件 for(int i 0 ; i 4;i){ for(int j 0 ; j 4; j){ coinBtn[i][j]-isWin true; } }测试胜利后不可以点击任何的金币。5.12 音效添加5.12.1 开始音效QSound *startSound new QSound(:/res/TapButtonSound.wav,this);点击开始按钮播放音效startSound-play(); //开始音效5.12.2 选择关卡音效在选择关卡场景中添加音效//选择关卡按钮音效 QSound *chooseSound new QSound(:/res/TapButtonSound.wav,this);选中关卡后播放音效chooseSound-play();5.12.3 返回按钮音效在选择关卡场景与翻金币游戏场景中分别添加返回按钮音效如下//返回按钮音效 QSound *backSound new QSound(:/res/BackButtonSound.wav,this);分别在点击返回按钮后播放该音效backSound-play();翻金币与胜利音效在PlayScene中添加翻金币的音效以及 胜利的音效//翻金币音效 QSound *flipSound new QSound(:/res/ConFlipSound.wav,this); //胜利按钮音效 QSound *winSound new QSound(:/res/LevelWinSound.wav,this);在翻金币时播放 翻金币音效flipSound-play();胜利时播放胜利音效winSound-play();测试音效使音效正常播放。5.13 优化项目当我们移动场景后如果进入下一个场景发现场景还在中心位置如果想设置场景的位置需要添加如下下图中的代码MainScene中添加ChooseScene中添加测试切换三个场景的进入与返回都在同一个位置下优化成功。六、测试运行6.1 主场景对游戏的每个步骤进行测试首先进入主场景如图7-1所示图7-1 主场景6.2 选择关卡场景进入主场景后点击START按钮进入选择关卡场景如图7-2所示图7-2 选择关卡场景6.3 翻金币场景选择第三关进入第三关卡的翻金币场景如图7-3所示图7-3 翻金币场景6.4 游戏胜利场景再翻金币场景下翻转金币游戏胜利后进入游戏胜利场景。如图7-4所示图7-4 游戏胜利场景七、评价与修订翻金币游戏分为三大场景分别为主场景、选择关卡场景、翻金币场景。分别实现不同的游戏功能本游戏一共有二十关可以从第一关开始接着来当完成第一关之后会自动跳到下一关还可以直接选择自己想要闯的关卡。进入关卡之后会有一个4*4的网格里面分布着金币和银币点击银币它本身和附近的币就会翻面当网格中只剩金币时闯关成功。游戏对游戏资源和游戏机制进行了很好的内外融合不管是背景音乐、游戏成功还是翻金币音效都是找的比较契合的音效。并且与用户交互的界面也是设计的简洁易懂不繁琐一眼就明白游戏的流程和操作方法。在游戏机制方面对于游戏的胜利和失败都有很好的解决办法可以让用户更好的进行下一关和重开游戏。使用户的粘度增加在游戏娱乐和闯关的同时也可以很好的进行益智。达到了在学习中娱乐在娱乐中学习。美中不足的就是游戏的关卡数量和游戏的模式有待增加过于单一会导致游戏用户的厌倦性和积极性后期对于游戏的难度和模式会做出相应的增加。增加用户的登录和游戏记录以及众多用户的pk等功能这个在学习后面的知识的时候会进行与相应的知识结合做出更好的解决方案和游戏机制。
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

留学网站建设红杭州网站建设

Win10开始菜单打不开?微软官方修复工具一键搞定! 【免费下载链接】Win10开始菜单修复工具Windows10StartMenuTroubleShooter Windows 10 Start Menu TroubleShooter是一款由微软官方推出的轻量级修复工具,专门解决Win10开始菜单无法打开或无法…

张小明 2026/1/17 19:47:52 网站建设

高校后勤网站建设要求新网站建设流程

ComfyUI Impact Pack导入失败问题全面解决方案 【免费下载链接】ComfyUI-Impact-Pack 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-Impact-Pack 问题现象识别 近期许多ComfyUI用户在更新Impact Pack扩展包后遇到了令人困扰的"IMPORT FAILED"错误。…

张小明 2026/1/17 19:47:54 网站建设

产品宣传类网站设计注意做网站链接

第一章:Rust与PHP版本匹配全解析(稀缺技术文档公开)在现代Web开发中,Rust以其卓越的性能和内存安全性逐渐成为PHP扩展开发的新选择。然而,将Rust编写的模块集成到PHP环境中时,版本兼容性问题常被忽视&#…

张小明 2026/1/17 19:47:57 网站建设

网站内链怎么删除百度扫一扫

你是否厌倦了在系统偏好设置中来回切换?是否希望在终端中就能完成所有系统控制任务?m-cli正是你需要的解决方案——这款被誉为"macOS多功能工具"的命令行工具,将系统控制功能浓缩到你的指尖。 【免费下载链接】m-cli  Swiss Army…

张小明 2026/1/17 19:47:59 网站建设