标题 | 基于QT的飞行射击游戏的实现 |
范文 | 成荣荣++崔志斌+杨克香 摘要:飞行射击游戏因操作简单、娱乐性强而广受欢迎。在Linux操作系统下,以Qt为开发平台,采用C++语言设计了一款小型飞行射击类游戏,主要采用类Element和类GamePad来实现游戏的功能。 关键词:Qt;射击游戏;C++ 中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2017)32-0089-03 Realization of Flight Shooting Game Based on QT CHENG Rong-rong1, CUI Zhi-bin2, YANG Ke-xiang1 (1.Kunshan dengyun college of science and technology, Kunshan 215300, China; 2.suzhou huatian shihang smart equipment technology CO.LTD, Kunshan 215300, China) Abstrsct:The flight shooting game is very popular because of its simple,entertaining.In the Linux operating system,Qt as the development platform,using C++ language design a small flight shooting game,Mainly using class Element and class GamePad to achieve the function of the game. Key words: Qt; shooting game; C++ Qt是一个跨平台应用程序和UI开发框架,具有完整的Qt集成开发环境,其中包括高级C++编译器、项目生成和管理工具,图形化调试器代码管理等等,适用于游戏界面的开发和应用,同时也适用于移动设备软件的设计,例如手机游戏方面[1-2]。在Linux操作系统下,执行完Qt安装包,导入库文件,对环境进行一定的配置之后,就可以在Qt环境中进行C++程序的编辑[3-4]。游戏包括开始(start)、暂停(pause)、结束(end)等,当进入游戏登陆界面时,点击开始(start)开始游戏,点击暂停(pause),可中途停止游戏,当异常或者游戏结束时,可选择结束退出,整个游戏结构如图1所示。 1 类的关系图和作用 游戏主要通过类Element和类GamePad来实现,其中类Element主要存放的是界面右侧的功能键(开始、暂停、结束)、计时器等功能组件。类GamePad的主要功能是生成游戏主界面比如游戏的背景地图等,Map类、Plane类和Bullet类分别在Gamepad类中实现。类的关系如图2所示,各类的作用如表1所示。由于篇幅限制,这里主要介绍类Element和Widget。 2 类Element 2.1 按钮组件 类Element所包含的内容包括:开始,暂停,结束按钮和计时器。定义代码如下: QPushButton*startBtn; QPushButton*pauseBtn; QPushButton*ExitBtn; QPixmapstartMap,pauseMap,exitMap; QLabel*ScoreLab; QLineEdit*ScorePad; QLabel*TimeLab; QLineEdit*TimePad; QLabel*LifeLab; QLineEdit*LifePad; 首先,startBtn,pauseBtn,ExitBtn聲明分别为开始、暂停、结束按钮,三个按钮的公共类为QpushButton,这是代表按钮的类,实例化的三个按钮,便作为游戏界面上的控制按钮。另外,由类QPixmap声明的StartMap,PauseMap,ExitMap导入的是三个绘图,用于按钮上的三个图标,Qpixmap的主要作用就是绘图,其主要依赖于硬件,与同作用的类QImage相比,类QPixMap是针对屏幕显示而最优化设计,而QImage主要是为图像I/O、图片访问和像素修改而设计的。当图片小的情况下,直接用QPixmap进行加载,画图时无所谓,当图片大的时候如果直接用QPixmap进行加载,会占很大的内存,一般一张几十K的图片,用QPixmap加载进来会放大很多倍,所以一般图片大的情况下,用QImage进行加载,然后转乘QPixmap用户绘制。QPixmap绘制效果是最好的。因此在按钮上绘制图标,便优先选择了QPixMap。 其次,TimeLab和LifeLab声明的是两个标签,分别代表时间和生命数,它们的公共类是QLabel类代表标签,其声明的两个类就是两个计数器前的标志。 最后,通过文本编辑器QLineEdit类声明了两个对象,分别为TimePad、LifePad分别代表时间、生命数的三个显示框,QLineEdit表示行编辑器,经过相应的处理最终显示在界面上的就像是LED的效果。 各项组件实例化之后,需要完成的工作就是进行布局安排,如何布局对于游戏的可视性极为重要,一般的布局管理方面,便利的方法是使用布局管理器,常用的布局管理有以下几种: 1) QVBoxLayout(垂直布局)用于位于竖直方向的组件的布局管理。 2) QHBoxLayout(水平布局)管理水平方向的布局。 3) QGridLayout(网格布局)可以在一个网格范围内进行布局管理。 4) QstacketLayout(堆叠布局)管理位于同一坐标上的多个组件。 布局管理的弊端在于,布局呈现的外观略显生硬僵化,無法达到某些特定的预期,例如本游戏的相关组件布局,需要有大小、位置、美观上的严格要求,所以采用的布局是原始的布局方式,即按照坐标点,人为的进行安置,这样便可以随意愿,布置界面的格局。在各组件定义实例化之后,游戏布局的代码如下: ScoreLab→setGeometry(0,30,50,40); ScorePad→setGeometry(50,30,80,40); LifeLab→setGeometry(0,90,50,40); LifePad→setGeometry(50,90,80,40); TimeLab→setGeometry(0,150,50,40); TimePad→setGeometry(50,150,80,40); pauseBtn→setGeometry(0,425,50,50); startBtn→setGeometry(0,425,50,50); ExitBtn→setGeometry(75,425,50,50); 其中,startBtn和pauseBtn所处的坐标位置一致,利用setShown方法设置按钮的可见性,即当点击按钮时该按钮就会消失,相应的同位置的另一个组件就会显示出来,这样就实现了按钮的切换,实现方法如下: 1) 在文件定义两个槽函数,分别为pauseBtnClicked()和startBtnClicked(),定义代码如下: void Element::startBtnClicked() {startBtn→setShown(0); pauseBtn→setShown(1);} void Element::pauseBtnClicked() {pauseBtn→setShown(0); startBtn→setShown(1);} 2) 使用connect方法,将信号与槽相连接,实现如下: connect(startBtn,SIGNAL(clicked()),this,SLOT(startBtnClicked())); connect(pauseBtn,SIGNAL(clicked()),this,SLOT(pauseBtnClicked())); 当setShown()参数为0时表示,组件为不可视,为一时则显现出来,当按钮被点击时,会发出信号,如代码中SIGNAL中的clicked()参数,接受到信号后就会自动调用SLOT中的函数,即先前定义的槽函数。 信号和槽有以下几种关联情况:1)一个信号可以连接多个槽;2)多个信号可以连接一个槽;3)一个信号可以与另外一个信号连接;4)连接可以解除[3]。 所有从Qobject或其子类(例如Qwidget)派生的类都能够包含信号和槽。当对象改变其状态时,信号就由该对象发射(emit)出去,这就是对象所要做的全部事情,它不知道另一端是谁在接收这个信号。这就是真正的信息封装,它确保对象被当作一个真正的软件组件来使用。槽用于接收信号,但它们是普通的对象成员函数。一个槽并不知道是否有任何信号与自己相连接。 2.2 计时器 点击startBtn的同时,计时器响应。首先,我们在主函数中声明并定义几个整型数hour、min、sec分别代表时、分、秒,并将它们初始化为0,所以在未开始之前,计时器的表盘始终是“00:00:00”显示。 其次,利用QTimer定义一个计时器,命名为timer,方法如下: timer = new QTimer(this); timer→setInterval(1000); setInterval()方法的作用是设定响应的时间,时间单位为毫秒(ms),因此设定时间为1000毫秒,1秒钟响应一次。 实现计时器,还需要几组功能函数,用于显示数字,定义一个槽函数,命名为updateTime用于时分秒的转换,再定义一个函数flushTime()用于更新显示的数字,如代码所示: void Element::flushTime() {QString timestr; timestr.sprintf("%02d:%02d:%02d",hour,min,sec); TimePad→setText(timestr);} void Element::updateTime() {sec++; if(sec == 60) { sec = 0; min++; if(min == 60) {min = 0; hour++;} } flushTime();} connect(timer,SIGNAL(timeout()),this,SLOT(updateTime())); 计时器效果如图3所示: 3 类Widget Widget是一个组件类,GamePad和Element可以理解为两个组件,实例化之后进行布局安排。 resize(650,500); gamePad = new GamePad(this); selectionPad = new Element(this); gamePad→setGeometry(0,0,500,500); selectionPad→setGeometry(510,0,200,500); 键盘触发事件,实现角色控制与键盘同步,主要通过系统调用的保护函数keyPressEvent(QKeyEvent *event)实现: void Widget::keyPressEvent(QKeyEvent *event) { if(event→isAutoRepeat()) return; switch(event→key()) {case Qt::Key_W: gamePad→RoleMOveCtl(Up); break; case Qt::Key_S: gamePad→RoleMOveCtl(Down); break; case Qt::Key_A: gamePad→RoleMOveCtl(Left); break; case Qt::Key_D: gamePad→RoleMOveCtl(Right); break; case Qt::Key_J: gamePad→RoleMOveCtl(Other); default: break;}} 其中对应的Key_A,Key_W,Key_S,Key_S,Key_D是对应的键位(A,W,S,D),用于控制角色的上下左右的移动,Key_J对应键位J用于控制子弹射击。敌方爆炸效果如图4所示,我方爆炸效果如图5所示。 4 结束语 本文实现了基于QT的飞行射击游戏的开发,程序中包含的类有Element,GamePad,Map,Plane,Bullet,ResultDialog,Widget,不同的类实现了游戏中的不同功能,这些类的灵活性强,可扩展性高,明显提高了游戏的可操作性,增加了游戏的真实感体验,也在一定程度上实现了玩家的满意度。 参考文献: [1] 郑阿奇. Qt4开发实践[M]. 北京: 电子工业出版社, 2011. [2] 杨盛毅, 文方, 师娇. 实时数据曲线绘制的Qt编程实现[J]. 四川大学学报:自然科学版, 2008, 45(2):61-64. [3] 譚浩强. C++程序设计[M]. 北京: 清华大学出版社, 2006. [4] 杨宗德, 邓玉春. Linux高级程序设计[M]. 北京: 人民邮电出版社, 2009. [5] Jasmin Blanchette, Mark Summerfield. C++GUI编程[M]. 北京: 电子工业出版社, 2008. |
随便看 |
|
科学优质学术资源、百科知识分享平台,免费提供知识科普、生活经验分享、中外学术论文、各类范文、学术文献、教学资料、学术期刊、会议、报纸、杂志、工具书等各类资源检索、在线阅读和软件app下载服务。