成榮榮++崔志斌+楊克香
摘要:飛行射擊游戲因操作簡單、娛樂性強(qiáng)而廣受歡迎。在Linux操作系統(tǒng)下,以Qt為開發(fā)平臺,采用C++語言設(shè)計了一款小型飛行射擊類游戲,主要采用類Element和類GamePad來實(shí)現(xiàn)游戲的功能。
關(guān)鍵詞:Qt;射擊游戲;C++
中圖分類號:TP311 文獻(xiàn)標(biāo)識碼: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是一個跨平臺應(yīng)用程序和UI開發(fā)框架,具有完整的Qt集成開發(fā)環(huán)境,其中包括高級C++編譯器、項(xiàng)目生成和管理工具,圖形化調(diào)試器代碼管理等等,適用于游戲界面的開發(fā)和應(yīng)用,同時也適用于移動設(shè)備軟件的設(shè)計,例如手機(jī)游戲方面[1-2]。在Linux操作系統(tǒng)下,執(zhí)行完Qt安裝包,導(dǎo)入庫文件,對環(huán)境進(jìn)行一定的配置之后,就可以在Qt環(huán)境中進(jìn)行C++程序的編輯[3-4]。游戲包括開始(start)、暫停(pause)、結(jié)束(end)等,當(dāng)進(jìn)入游戲登陸界面時,點(diǎn)擊開始(start)開始游戲,點(diǎn)擊暫停(pause),可中途停止游戲,當(dāng)異?;蛘哂螒蚪Y(jié)束時,可選擇結(jié)束退出,整個游戲結(jié)構(gòu)如圖1所示。
1 類的關(guān)系圖和作用
游戲主要通過類Element和類GamePad來實(shí)現(xiàn),其中類Element主要存放的是界面右側(cè)的功能鍵(開始、暫停、結(jié)束)、計時器等功能組件。類GamePad的主要功能是生成游戲主界面比如游戲的背景地圖等,Map類、Plane類和Bullet類分別在Gamepad類中實(shí)現(xiàn)。類的關(guān)系如圖2所示,各類的作用如表1所示。由于篇幅限制,這里主要介紹類Element和Widget。
2 類Element
2.1 按鈕組件
類Element所包含的內(nèi)容包括:開始,暫停,結(jié)束按鈕和計時器。定義代碼如下:
QPushButton*startBtn;
QPushButton*pauseBtn;
QPushButton*ExitBtn;
QPixmapstartMap,pauseMap,exitMap;
QLabel*ScoreLab;
QLineEdit*ScorePad;
QLabel*TimeLab;
QLineEdit*TimePad;
QLabel*LifeLab;
QLineEdit*LifePad;
首先,startBtn,pauseBtn,ExitBtn聲明分別為開始、暫停、結(jié)束按鈕,三個按鈕的公共類為QpushButton,這是代表按鈕的類,實(shí)例化的三個按鈕,便作為游戲界面上的控制按鈕。另外,由類QPixmap聲明的StartMap,PauseMap,ExitMap導(dǎo)入的是三個繪圖,用于按鈕上的三個圖標(biāo),Qpixmap的主要作用就是繪圖,其主要依賴于硬件,與同作用的類QImage相比,類QPixMap是針對屏幕顯示而最優(yōu)化設(shè)計,而QImage主要是為圖像I/O、圖片訪問和像素修改而設(shè)計的。當(dāng)圖片小的情況下,直接用QPixmap進(jìn)行加載,畫圖時無所謂,當(dāng)圖片大的時候如果直接用QPixmap進(jìn)行加載,會占很大的內(nèi)存,一般一張幾十K的圖片,用QPixmap加載進(jìn)來會放大很多倍,所以一般圖片大的情況下,用QImage進(jìn)行加載,然后轉(zhuǎn)乘QPixmap用戶繪制。QPixmap繪制效果是最好的。因此在按鈕上繪制圖標(biāo),便優(yōu)先選擇了QPixMap。
其次,TimeLab和LifeLab聲明的是兩個標(biāo)簽,分別代表時間和生命數(shù),它們的公共類是QLabel類代表標(biāo)簽,其聲明的兩個類就是兩個計數(shù)器前的標(biāo)志。
最后,通過文本編輯器QLineEdit類聲明了兩個對象,分別為TimePad、LifePad分別代表時間、生命數(shù)的三個顯示框,QLineEdit表示行編輯器,經(jīng)過相應(yīng)的處理最終顯示在界面上的就像是LED的效果。
各項(xiàng)組件實(shí)例化之后,需要完成的工作就是進(jìn)行布局安排,如何布局對于游戲的可視性極為重要,一般的布局管理方面,便利的方法是使用布局管理器,常用的布局管理有以下幾種:
1) QVBoxLayout(垂直布局)用于位于豎直方向的組件的布局管理。
2) QHBoxLayout(水平布局)管理水平方向的布局。
3) QGridLayout(網(wǎng)格布局)可以在一個網(wǎng)格范圍內(nèi)進(jìn)行布局管理。endprint
4) QstacketLayout(堆疊布局)管理位于同一坐標(biāo)上的多個組件。
布局管理的弊端在于,布局呈現(xiàn)的外觀略顯生硬僵化,無法達(dá)到某些特定的預(yù)期,例如本游戲的相關(guān)組件布局,需要有大小、位置、美觀上的嚴(yán)格要求,所以采用的布局是原始的布局方式,即按照坐標(biāo)點(diǎn),人為的進(jìn)行安置,這樣便可以隨意愿,布置界面的格局。在各組件定義實(shí)例化之后,游戲布局的代碼如下:
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所處的坐標(biāo)位置一致,利用setShown方法設(shè)置按鈕的可見性,即當(dāng)點(diǎn)擊按鈕時該按鈕就會消失,相應(yīng)的同位置的另一個組件就會顯示出來,這樣就實(shí)現(xiàn)了按鈕的切換,實(shí)現(xiàn)方法如下:
1) 在文件定義兩個槽函數(shù),分別為pauseBtnClicked()和startBtnClicked(),定義代碼如下:
void Element::startBtnClicked()
{startBtn→setShown(0);
pauseBtn→setShown(1);}
void Element::pauseBtnClicked()
{pauseBtn→setShown(0);
startBtn→setShown(1);}
2) 使用connect方法,將信號與槽相連接,實(shí)現(xiàn)如下:
connect(startBtn,SIGNAL(clicked()),this,SLOT(startBtnClicked()));
connect(pauseBtn,SIGNAL(clicked()),this,SLOT(pauseBtnClicked()));
當(dāng)setShown()參數(shù)為0時表示,組件為不可視,為一時則顯現(xiàn)出來,當(dāng)按鈕被點(diǎn)擊時,會發(fā)出信號,如代碼中SIGNAL中的clicked()參數(shù),接受到信號后就會自動調(diào)用SLOT中的函數(shù),即先前定義的槽函數(shù)。
信號和槽有以下幾種關(guān)聯(lián)情況:1)一個信號可以連接多個槽;2)多個信號可以連接一個槽;3)一個信號可以與另外一個信號連接;4)連接可以解除[3]。
所有從Qobject或其子類(例如Qwidget)派生的類都能夠包含信號和槽。當(dāng)對象改變其狀態(tài)時,信號就由該對象發(fā)射(emit)出去,這就是對象所要做的全部事情,它不知道另一端是誰在接收這個信號。這就是真正的信息封裝,它確保對象被當(dāng)作一個真正的軟件組件來使用。槽用于接收信號,但它們是普通的對象成員函數(shù)。一個槽并不知道是否有任何信號與自己相連接。
2.2 計時器
點(diǎn)擊startBtn的同時,計時器響應(yīng)。首先,我們在主函數(shù)中聲明并定義幾個整型數(shù)hour、min、sec分別代表時、分、秒,并將它們初始化為0,所以在未開始之前,計時器的表盤始終是“00:00:00”顯示。
其次,利用QTimer定義一個計時器,命名為timer,方法如下:
timer = new QTimer(this);
timer→setInterval(1000);
setInterval()方法的作用是設(shè)定響應(yīng)的時間,時間單位為毫秒(ms),因此設(shè)定時間為1000毫秒,1秒鐘響應(yīng)一次。
實(shí)現(xiàn)計時器,還需要幾組功能函數(shù),用于顯示數(shù)字,定義一個槽函數(shù),命名為updateTime用于時分秒的轉(zhuǎn)換,再定義一個函數(shù)flushTime()用于更新顯示的數(shù)字,如代碼所示:
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可以理解為兩個組件,實(shí)例化之后進(jìn)行布局安排。
resize(650,500);
gamePad = new GamePad(this);
selectionPad = new Element(this);endprint
gamePad→setGeometry(0,0,500,500);
selectionPad→setGeometry(510,0,200,500);
鍵盤觸發(fā)事件,實(shí)現(xiàn)角色控制與鍵盤同步,主要通過系統(tǒng)調(diào)用的保護(hù)函數(shù)keyPressEvent(QKeyEvent *event)實(shí)現(xiàn):
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;}}
其中對應(yīng)的Key_A,Key_W,Key_S,Key_S,Key_D是對應(yīng)的鍵位(A,W,S,D),用于控制角色的上下左右的移動,Key_J對應(yīng)鍵位J用于控制子彈射擊。敵方爆炸效果如圖4所示,我方爆炸效果如圖5所示。
4 結(jié)束語
本文實(shí)現(xiàn)了基于QT的飛行射擊游戲的開發(fā),程序中包含的類有Element,GamePad,Map,Plane,Bullet,ResultDialog,Widget,不同的類實(shí)現(xiàn)了游戲中的不同功能,這些類的靈活性強(qiáng),可擴(kuò)展性高,明顯提高了游戲的可操作性,增加了游戲的真實(shí)感體驗(yàn),也在一定程度上實(shí)現(xiàn)了玩家的滿意度。
參考文獻(xiàn):
[1] 鄭阿奇. Qt4開發(fā)實(shí)踐[M]. 北京: 電子工業(yè)出版社, 2011.
[2] 楊盛毅, 文方, 師嬌. 實(shí)時數(shù)據(jù)曲線繪制的Qt編程實(shí)現(xiàn)[J]. 四川大學(xué)學(xué)報:自然科學(xué)版, 2008, 45(2):61-64.
[3] 譚浩強(qiáng). C++程序設(shè)計[M]. 北京: 清華大學(xué)出版社, 2006.
[4] 楊宗德, 鄧玉春. Linux高級程序設(shè)計[M]. 北京: 人民郵電出版社, 2009.
[5] Jasmin Blanchette, Mark Summerfield. C++GUI編程[M]. 北京: 電子工業(yè)出版社, 2008.endprint