首页 > 编程知识 正文

qq游戏下载,基于qt的小游戏贪吃蛇

时间:2023-05-05 12:29:17 阅读:43586 作者:73

最近在Web站学习了GUI开发,真的不想看黑框。 制作了翻金币的小游戏。 写完了但是不能打包,没有请人调试。 在我打包之前我先拷贝一下现在这里程序是怎么写的。

老实说,Qt的学习确实稍微理解了程序的工作原理。 最简单的是connect函数只去一次,而不是发信号去一次。 而且现在不是发出信号的时候。

添加资源开发程序需要照片和声音。 虽然我还没有添加声音,但是为了开发我使用的visual studio,vs自动为我创建了. qrc文件。 资源都在这里面。

如果要添加的文件,必须首先将资源打包并放在工程文件夹下。 以下prefix添加了前缀:

将文件放入qrc文件的目的是允许使用相对路径,对需要移植的程序非常重要。

我做这个引用的时候,' :/source/name…' )有前缀就在前面加前缀就可以了。

程序主窗口thefinalgame.cpp

主窗口我做的很粗糙,1280*720的界面上放着“开机按钮”,很容易就设置了标题栏,命名为“Coin Turning”。 菜单栏上只有一个关闭按钮。

的“关闭并连接警告对话框”程序有两种常规方式关闭程序

第一个是菜单栏的“关闭”,第二个是直接点击右上角的叉号。

在菜单栏上关闭后,他是QAction类的,点击它会产生触发信号。 只需在connect中连接lambda表达式并关闭窗口即可。

关闭窗口时将发生关闭事件。 这表明主窗口的父类是virual函数,将在主窗口类中重写。

生成voidthefinalgame :关闭事件(qcloseevent * ce ) /警告对话框intres=qmessagebox : question (this,' Warning ,qmessagebox :3360是| qmessagebox 33603360 no,qmessagebox 33603360是; //点确定结束if时(RES==qmessagebox33603360yes ) this-close ); //else if (RES==65536|| RES==qmessagebox 33603360 no ) ce-ignore ); }加载背景图像在paintevent中加载背景图像

使用QPixmap作为载体

语音事件(qpaintevent * ) qpainterpainter ) this; QPixmap pix; pix.load (:/source/ground.JPEG ); painter.draw pixmap (q rect (q点(0,23 ),q点) 1280,720 ),pix ); /*要绘制背景图像,首先将图像加载到Qpixmap类中,然后创建*/}按钮类(返回到关卡选择),方法是在画家选择的矩形区域中绘制*/}

我想制作一个按下就会改变颜色(其实是改变图像)的按钮,所以更改了所有的构造函数。

发送两张图像的路径不按显示一方,按显示另一方。

my push button :3360 my push button (qstringnormalpath,QString PressPath=' ' ) /第二个是按下时显示的图像。 默认情况下,由于存在不需要改变颜色的按钮,因此为空。 不按{this-normalimgpath} //按钮的路径this-PressImgPath=PressPath; 按下//按钮的路径QPixmap pix; pix.load (正规imgpath; this-setfixedsize (q size (pix.width ),pix.height ); //按钮大小this-set style sheet (qpushbutton { border :0 px; () ); //图像周围的白色this-seticon(qicon ) ) pix ); //设置按钮图标this-seticonsize(qsize ) pix.width ),pix.height ) ); //设定按钮中的图像大小}单击按钮的动画按钮,实现按钮上下跳动的动画。

为按钮类定义两个函数。 一个在下面安装按钮,另一个在上面安装

void myPushButton:弱小的大山1 ((qpropertyanimation * anime=newqpropertyanimation (this,' geometry ) ); //事件间隔anime-setduration(200 ); //开始位置anime-setstartvalue (q rect (this-x )、this-y )、this-width )、this-height ) )//结束位置anime-set

EndValue(QRect(this->x() , this->y() + 10 , this->width() , this->height()));//设置弹跳曲线anime->setEasingCurve(QEasingCurve::OutBounce);anime->start();}void myPushButton::柔弱的大山2(){QPropertyAnimation* anime = new QPropertyAnimation(this , "geometry");//设置事件间隔anime->setDuration(200);//起始位置anime->setStartValue(QRect(this->x() , this->y() + 10 , this->width() , this->height()));//结束位置anime->setEndValue(QRect(this->x() , this->y() , this->width() , this->height()));//设置弹跳曲线anime->setEasingCurve(QEasingCurve::OutBounce);anime->start();}

用connect函数连接lambda表达式,点击就启动
加入了暂停300ms 防止执行过快,观感不好

connect(btn_start , &QPushButton::clicked , [=] () { btn_start->柔弱的大山1(); btn_start->柔弱的大山2(); QTimer::singleShot(300 , this , [=] () { this->hide(); chooselevel->show(); }); }); 选择关卡窗口

chooselevel.h/chooselevel.cpp
设置窗口各种参数和主窗口是同样的方式

设置返回按钮

返回按钮比开始按钮只多了一个功能,就是按下变色(实际上是图片切换)。只需要在鼠标按下事件里加一点东西。

void myPushButton::mousePressEvent(QMouseEvent* me){if(this->PressImgPath != "")this->setIcon(QIcon(this->PressImgPath));//通过pressimgpath判断这个按钮是不是需要变色QPushButton::mousePressEvent(me);//如果不拦截这个信号 交给父亲处理}

还有一个问题 就是按了返回之后如何返回上一个场景。我们在选关窗口里并没有上一个窗口的对象。但是我们在上一个窗口有这个窗口的对象。
我们可以在chooselevel.h里手动实现一个信号
因为在主窗口里我们有选关窗口对象,我们可以接收到chooselevel发出的信号。

thefinalgame.cpp

connect(chooselevel , &ChooseLevel::back() , [=](){this->show();})

back()是实现在chooselevel.h中的信号

设置选关按钮

让我对connect了解更深的地方

for(int i = 1 ; i <= 4 ; i ++)for (int j = 1; j <= 5; j ++){myPushButton* btn_level;btn_level = new myPushButton(":source/Unchoose.png");btn_level->setParent(this);btn_level->setIconSize(QSize(0.8 * btn_level->size()));btn_level->move(QPoint((j - 1) * 0.18 * this->width() , (i - 1) * 0.25 * this->height()));Levels* levels = new Levels(j + (i - 1) * 5);connect(btn_level , &QPushButton::clicked , [=] () {btn_level->柔弱的大山1();btn_level->柔弱的大山2();QTimer::singleShot(300 , this , [=] () {this->hide();levels->show();qDebug() << levels->number;});});//这里很多人可能会问 申请这么多,只用一个指针存。调用怎么办//其实这里是申请之后立马connect了,只是用一下这个地址,这个地址其实就用不到了,没必要再用新的指针存下一个了。QLabel* label_level = new QLabel(btn_level);label_level->setText(QString().number((i - 1) * 5 + j));btn_level->move(QPoint((j - 1) * 0.18 * this->width() , (i - 1) * 0.25 * this->height()));label_level->setFixedSize(QSize(btn_level->size()));label_level->setAlignment(Qt::AlignCenter);QFont font_level;font_level.setPointSize(35);label_level->setFont(QFont(font_level));label_level->setStyleSheet("color:red;");//这里是label 显示关卡号的,注意父亲要设置为按钮,如果设置为窗体会导致按钮按不了connect(levels , &Levels::back , [=] () {this->show();});//下一个窗口返回这里需要的connect} 关卡窗口

选关之后就正式进关了

我们需要创建金币类,一关是4*4的金币,难点是如何翻动附近的金币。

这里我没跟着教程做,凭借算法竞赛的经验,自己口胡出来了一个方法。

for(int i = 1 ; i <= 4 ; i ++)for (int j = 1; j <= 4; j ++){QLabel* label = new QLabel(this);QPixmap pix(":/source/coinbackground.png");pix = pix.scaled(QSize(0.8 * pix.size()));label->setGeometry(0 , 0 , pix.width() , pix.height());label->setPixmap(pix);label->move(250 + pix.width() * (j - 1) , 53 + pix.height() * (i - 1));//贴图部分myCoin* coin = new myCoin(lev[this->number - 1][i - 1][j - 1] , this);v[this->number - 1].push_back(coin);coin->move(230 + pix.width() * (j - 1) , 30 + pix.height() * (i - 1));//创建金币类,每关一个vector, 16个金币地址按顺序存进vector}int f = 0;for (QVector<myCoin*>::iterator it = v[this->number - 1].begin(); it != v[this->number - 1].end(); it ++){f ++;connect(*it , &QPushButton::clicked , [=] () {(*it)->turn();if (f > 4) v[this->number - 1][f - 4 - 1]->turn();if (f <= 12) v[this->number - 1][f + 4 - 1]->turn();if (f % 4 != 1) v[this->number - 1][f - 1 - 1]->turn();if (f % 4 != 0) v[this->number - 1][f + 1 - 1]->turn();isWin();});}

金币是线性存储的,怎么应用的4*4行列里呢
当前数-4就是上一行 注意判断是不是第一行
同理+4是下一行 注意判断是不是最后一行
前后的话好判断 注意判断是不是在头和尾 如果%4 = 0 是最后一列 %4 = 1 是前一列

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。