馬 麗,薛根奇,呂海蓮
(1.平頂山學院計算機學院(軟件學院),河南 平頂山467000;2.平高集團有限公司焊接技術及壓力容器實驗室 河南 平頂山 467001;3.河南平高電氣股份有限公司 河南 平頂山 467001)
基于Qt組件的俄羅斯方塊設計
馬 麗1,薛根奇2,3,呂海蓮1
(1.平頂山學院計算機學院(軟件學院),河南 平頂山467000;2.平高集團有限公司焊接技術及壓力容器實驗室 河南 平頂山 467001;3.河南平高電氣股份有限公司 河南 平頂山 467001)
為提高經(jīng)典益智游戲---俄羅斯方塊的趣味性與高效性,提出了基于Qt組件的俄羅斯方塊設計。在實現(xiàn)該游戲傳統(tǒng)功能基礎上,增加了添加障礙方塊和旋轉(zhuǎn)游戲區(qū)域等功能,顯著提升了游戲的趣味性與高效性,帶給玩家更好的游戲體驗。該設計重點從游戲要素、游戲算法、方塊運行判斷等方面進行分析,最終通過運行游戲驗證設計的有效性。
Qt;俄羅斯方塊;碰撞檢測;運行狀態(tài)判斷
俄羅斯方塊游戲是最早的休閑益智游戲之一,是個老幼皆宜的小游戲,它適合無興趣或無精力玩大型網(wǎng)絡游戲的玩家[1-4]。
經(jīng)過多年的發(fā)展,該游戲在網(wǎng)絡已有多種語言的不同版本[5]。最常見的有QQ版和4399網(wǎng)頁上的俄羅斯方塊游戲[6]。QQ版俄羅斯方塊游戲不僅畫面設計優(yōu)美、游戲背景顏色、音樂搭配合理,而且實現(xiàn)了聯(lián)網(wǎng)對戰(zhàn)功能。4399上的小俄羅斯方塊游戲花樣繁多,畫面豐富多彩,吸引了不少‘面控’玩家。這兩種火熱的俄羅斯方塊游戲的優(yōu)點顯而易見,但對網(wǎng)絡的依賴性較大。因此文中基于Qt框架,設計一款電腦版的俄羅斯方塊游戲,使玩家在無網(wǎng)絡的情況下也能體驗該游戲。俄羅斯方塊是一款極易上手并且易于理解的益智類拼圖游戲。這款小游戲使得它的玩家在進行一段時間的游戲后,普遍將這種再度組合的思維慣性應用到了眼前所看見的事物中,這種現(xiàn)象被稱之為“俄羅斯方塊的游戲效應”[7]。文中設計的俄羅斯方塊游戲,在實現(xiàn)該游戲傳統(tǒng)基本功能前提下,增加了添加障礙方塊和旋轉(zhuǎn)游戲區(qū)域等功能,實現(xiàn)了一款看似簡單但功能繁多的俄羅斯方塊游戲[8],讓玩家盡情體驗的樂趣。
QT框架是諾基亞開發(fā)的一款跨平臺C++圖形用戶界面,允許真正的組件編程、易擴展。信號和槽是一種高級接口,應用于對象間的通信,是QT的核心。很多GUI工具包窗口小部件(widget)中,均有一個指向某函數(shù)的指針的回調(diào)函數(shù)響應觸發(fā)的每個動作。而在QT中信號和槽取代了函數(shù)指針,且能攜帶任意數(shù)量和類型的參數(shù),所有從QObject或其子類派生的類都包含信號和槽。當對象狀態(tài)改變時,信號就由該對象發(fā)射出去,實現(xiàn)真正的信息封裝,對象被當作一個真正的軟件組件來使用。采用QT自帶的Wigit()函數(shù)設計游戲界面,利用信號與槽機制將游戲界面上的功能按鍵與業(yè)務代碼相關聯(lián)。
俄羅斯方塊游戲規(guī)則簡單,屏幕上方隨機產(chǎn)生不同形狀的方塊并以一定速度下落,玩家可控制方塊的左、右位置以及旋轉(zhuǎn)方塊,使方塊下落后充分利用屏幕空間。每當方塊排滿屏幕的一整行時,該行方塊從屏幕上消失,其上的方塊依次下降一行,玩家獲得一定的分數(shù)。當方塊堆積達到屏幕頂端的時候,游戲結(jié)束[9]。一個成功的俄羅斯方塊游戲,主要實現(xiàn)游戲方塊的預覽、控制,游戲分數(shù)、等級更新等游戲操作提示功能[10]。本設計在實現(xiàn)傳統(tǒng)俄羅斯方塊基本功能基礎上,增加了添加障礙方塊和旋轉(zhuǎn)游戲區(qū)域等功能。
2.1游戲功能接口設計
設計游戲類gamearae實現(xiàn)該游戲的各功能。利用類的構(gòu)造函數(shù)GameArea::GameArea(int speed,QWidget*parent)初始化游戲,定義了默認的游戲區(qū)域大小、方塊大小、方塊下落速度等。用析構(gòu)函數(shù)GameArea::~GameArea()回收資源。游戲的主要功能函數(shù)設計如下。
1)gamestart()函數(shù),游戲開始接口。
2)setGameAreaColor()、setBoxBrushColor()改變游戲區(qū)域和方塊顏色的接口。
3)setPlaySounds_MoveDown()、setPlaySounds_ItemChange()、setPlaySounds_MoveLeft()、setPlaySounds_Moveright(),方塊左、右移動,以及變換下落時聲音接口。
4)itemChange(),方塊發(fā)生變換的接口。
5)Qpainter(),繪畫圖形的接口。
6)Qtimer(),定時器產(chǎn)生的接口。
7)Qrand(),隨機產(chǎn)生方塊的接口。
2.2游戲要素設計
俄羅斯方塊游戲要素包括方塊設計、控制設計以及結(jié)束設計等。
2.2.1方塊設計
俄羅斯方塊游戲通常有7種方塊模型[11]。方塊是俄羅斯方塊游戲要素最基本的組成部分之一[12],良好的方塊設計可以讓玩家體驗到游戲帶來的樂趣。設計中,需要解決小方塊繪制、圖形隨機出現(xiàn)、不同形狀圖形的存儲數(shù)據(jù)結(jié)構(gòu)、多線程控制等方面的關鍵技術[13]。
本俄羅斯方塊游戲中設計了7種基本方塊模型(Z字型、反Z字型、7字型、反7字型、豎字型、田字型、T字型)。每種方塊均由4個小正方形組成,且有4種形狀變化。故采用4*4矩陣設計方塊,即由4個行高為4的小正方形按規(guī)則組成,矩陣中有顏色的表示有方塊,無顏色表示無方塊,用數(shù)組存儲7種方塊。故設計一個方塊類(Myitem類),將矩陣上的方塊按照坐標轉(zhuǎn)化為二維數(shù)組的下標,實現(xiàn)矩陣和二維數(shù)組的對照。在4x4矩陣(二維數(shù)組)中,用0和1表示方塊的位置,在1的位置上“畫”上顏色則可以清晰的表示1個方塊的形狀。最后用QT自帶的“畫家”將圖片用不同的顏色“畫”出來,如圖1(a)所示。每個4*4矩陣都有自己的橫、縱坐標,通過矩陣逆時針旋轉(zhuǎn)90°實現(xiàn)方塊的形狀變化。矩陣逆時針旋轉(zhuǎn)后,每個小方塊的坐標變換為:橫坐標x1=3-y(旋轉(zhuǎn)前的縱坐標)、縱坐標y1=x(旋轉(zhuǎn)前的橫坐標)。圖1(a)Z形方塊的另外3種形狀變換如圖1(b)、圖1(c)圖1(d)所示。無論怎樣旋轉(zhuǎn),方塊的形狀都不會變化。其余6種方塊形狀變換方法與Z形方塊類似,不再描述。為使設計的方塊能在指定的游戲區(qū)域內(nèi)運行,需定制坐標。左上角為方塊的起始“0”坐標,從上往下,從左往右開始輸出區(qū)域。將方塊變化的坐標和游戲區(qū)域不變的坐標相結(jié)合,實現(xiàn)游戲區(qū)域的控制。方塊的每次移動或旋轉(zhuǎn)都會引起方塊在游戲區(qū)域坐標的變換,每次變換后都需要將游戲區(qū)域與方塊重新繪制。
圖1 Z字型方塊
2.2.2游戲控制設計
采用電腦小鍵盤的控制鍵控制方塊運行。上鍵:方塊有規(guī)律的變換方向,即根據(jù)玩家初始化時的方向依次變換;下鍵:控制加速降落或者直接墜落(取決于上面的功能按鍵設置),通過增加縱坐標來實現(xiàn);左鍵:方塊向左移動一個位置,通過減少橫坐標來實現(xiàn);右鍵:方塊向右移動一個位置,通過增加橫坐標來實現(xiàn);其他鍵:方塊不做任何變化,正常下落。方塊下落時可使用左、右方向鍵控制方塊左、右運動,同時也可使用上方向鍵循環(huán)的改變其形狀。當方塊到達邊界或與其他方塊碰撞時不能移動。
通過QT自帶的“事件”,將硬件觸發(fā)與設計的keypress-Event函數(shù)相結(jié)合,控制方塊移動。按上、下、左、右不同的控制鍵,發(fā)出相應的硬件信號 Key_Up、Key_Down、Key_Left、Key_Right。系統(tǒng)會根據(jù)玩家鍵入的按鍵,判斷、控制方塊移動。若收到上述4種信號外的信號,則不能對游戲方塊進行控制操作。
2.2.3游戲算法設計
為確保該游戲正常運行,游戲規(guī)定:當游戲開始或上一方塊運行結(jié)束時,自動產(chǎn)生下一方塊;方塊運行過程中可移動或旋轉(zhuǎn);當方塊堆滿1行或者多行時,可消行。
2.2.3.1算法的數(shù)據(jù)結(jié)構(gòu)
1)游戲方塊(myitem)設計為含16個元素的二維數(shù)組,其中每一個元素代表方塊在該位置是否繪圖。即myitem[i,j]=1或0,分別表示在與此二維數(shù)組對應的4*4矩陣的坐標為(i,j)的位置上繪制與背景不同或相同的顏色。
2)游戲區(qū)域(gamearae)設計為含有200個元素的二維數(shù)組,其中每一個元素代表方塊在此位置是否有方塊。即gamearae[i,j]=1或0,分別表示在與此二維數(shù)組對應的10*20矩陣的坐標為(i,j)的位置上有、無方塊。
2.2.3.2算法實現(xiàn)
1)初始化開始按鈕,分別對方塊與游戲區(qū)域賦值。
2)方塊運動算法 利用QT的鍵盤方向鍵控制方塊移動,方塊在移動過程中進行碰撞檢測。設鍵盤處理事件按鍵產(chǎn)生信號vigel,碰撞函數(shù)為ismoveend(),則方塊移動算法描述如下:
①如果按下方向鍵的左鍵,發(fā)出Evevt(key_Left)事件,方塊左移。判斷碰撞函數(shù)ismoveend()中ismoveleft()函數(shù)>0?若是則可以移動,否則不能。
②如果按下方向鍵的右鍵發(fā)出Evevt(key_right)事件,方塊右移。判斷碰撞函數(shù)ismoveend()中ismoveright()函數(shù)<10,若是則可以移動,否則不能;
③如果按下方向鍵的下鍵發(fā)出Evevt(key_down)事件,方塊下移。判斷碰撞函數(shù)ismoveend()中ismovedown()函數(shù)> 0,若是則可以移動,否則不能。
3)方塊旋轉(zhuǎn)算法方塊旋轉(zhuǎn)判斷itemchange函數(shù)中定義copymap指針、currunmap指針,與方塊坐標StartX,則方塊旋轉(zhuǎn)算法為:若按下方向鍵的左鍵發(fā)出Evevt(key_up)事件,方塊旋轉(zhuǎn)。判斷旋轉(zhuǎn)函數(shù)startX<0,方塊越界,需要重新確定方塊的邊界(startX=0)。若copymap&&currunmap=1,方塊重疊,不能旋轉(zhuǎn),否則可以旋轉(zhuǎn)。
2.3游戲界面設計
游戲界面設計采用QT自帶的UI界面。根據(jù)前面設定的坐標建立一個20*10的Widgit窗口作為游戲區(qū),行、列交叉處構(gòu)成的方格即為一個方塊的大小。方格大小設定后,游戲區(qū)域區(qū)的終止坐標為(右下角坐標(400,200));用gamearae類中的函數(shù)初始化游戲區(qū)域、起始位置、高、寬、小方塊邊長、圖形出現(xiàn)位置等參數(shù),完成指定區(qū)域的設計。
2.4游戲運行判斷設計
方塊、游戲區(qū)域設計完成,若要實現(xiàn)方塊有條件地在游戲區(qū)域內(nèi)移動,需判斷方塊是否可移動、可變化、可消行等。
移動判斷:先假設方塊可移動,保存現(xiàn)有游戲界面copymap,并繪出方塊移動后的畫面。然后再判斷方塊移動后是否有和其他方塊重疊或者碰到邊界,若無則可以移動,繪出移動后的界面,進行下一步操作,否則不能移動,還原上次保存的界面。判斷是否重疊和方塊的設計息息相關,如果移動后的方塊在‘1’的部分上有重疊,則說明方塊重疊,不能移動。若移動后下一步超過了邊界或者與其他圖形重疊,說明在左、右方向上不能移動,在下落的方向上,則說明該方塊運行結(jié)束。邊界的判斷和游戲區(qū)域坐標有關,方塊移動時對其縱、橫坐標進行加減,加減后,若其縱、橫坐標小于0則說明出界。
判斷方塊是否可左、右移的功能函數(shù)為ismoveleft()和ismoveright(),確認方塊在4*4矩陣上的當前位置函數(shù)為currentItem_endPos()。如果方塊左邊界減去方塊移動的步數(shù)≤0,說明游戲已經(jīng)到達左邊界,方塊不能繼續(xù)移動。將假設可以移動時保存的當前游戲界面copymap與移動后的方塊進行相與運算,若結(jié)果為1,則說明方塊重疊,方塊不能向左移動,返回保存界面,進行下一步操作。
同理右移函數(shù)ismoveright()在確認好方塊當前位置后,如果方塊右邊界加上移動的步數(shù)≥10,則說明游戲超出邊界,不能向右移動。將假設可以移動時保存的當前游戲界面copymap與移動后的方塊進行相與運算,若結(jié)果為1,則說明方塊重疊,方塊不能向右移動,返回保存界面,進行下一步操作。
重疊判斷函數(shù)ismoveend(),利用currentItem_endPos()函數(shù)確認方塊在4*4矩陣上的當前位置,若下邊界加上下移的步數(shù)≥20,則說明方塊到達下邊界,方塊運行停止。先假設可以移動一步,然后將假設可以移動時保存的當前游戲界面copymap與移動后的方塊currentitem進行相與運算,若結(jié)果為1,則說明方塊重疊,不能向下運拓,返回保存界面,該方塊運行結(jié)束,新方塊重新進行下一輪操作。重疊的判斷則是利用方塊的坐標與其所在行進行異或運算,相同為0不同為1,若異或結(jié)果為1則沒有重疊。然后循環(huán)檢測方塊的16個坐標。
變換判斷:首先要判斷方塊是否可下移。若可,則保存現(xiàn)有界面。然后假設可變換,并繪出變換后的圖形,再判斷是否有重疊或者超出游戲邊界。若無則進行變換,將變換后的圖形繪出來。若變換后和障礙物重疊或超出下邊界,則方塊不能變換,運行結(jié)束;若變換后超出左邊界,則令方塊靠左對其,即令方塊的橫坐標為0,縱坐標不變,然后繪出變換后的形狀。若變換后超出右邊界,則令起靠右對其,令方塊的橫坐標為20*4-4=76,縱坐標不變,然后繪出變換后的界面。若其在左、右方向上變換后與其他障礙物重疊且不超出邊界,則不能變換,但可能下落。然后循環(huán)進行變換判斷,直到這個方塊運行結(jié)束,產(chǎn)生下一個方塊。
設計itemchange()功能函數(shù)判斷是否可變換,先保存當前圖形到臨時方塊tempitem中,如果變換后方塊的橫坐標startX小于0,說明方塊左越界,令startX=0,如果變換后方塊的橫坐標 startX+4*step(步數(shù))大于 10,說明右越界,令startX=10-step。然后繪畫出圖片。
設計時定義了ismoveend()函數(shù),先假設可變換,將假設可變換時保存的界面copymap與變換后的方塊進行相與運算,若結(jié)果為1,則說明方塊旋轉(zhuǎn)后和別的圖形有重疊,不能旋轉(zhuǎn)。返回原來保存的界面,游戲繼續(xù)下一步。方塊旋轉(zhuǎn)流程如圖2所示。
圖2 方塊旋轉(zhuǎn)流程圖
消行判斷:每個方塊運行結(jié)束時,判斷是否消行。可以一次消除一行,或者消除多行,消除多行和消除單行的原理一樣[14]。當方塊堆滿一行或者多行時可消行。根據(jù)文中方塊設計可知,若每行網(wǎng)格內(nèi)全為‘1’,則表示此行已堆積滿,需消除。此時縱坐標值比該行小的所有行下移一行,用戶得分增加。繼續(xù)向下檢測,若下一行滿行,消除,再繼續(xù)往下檢測,直到整個游戲區(qū)域檢測一遍為止。檢查完成后,該方塊運行結(jié)束,產(chǎn)生下一方塊。每次產(chǎn)生新的方塊時觸發(fā)重繪事件,重‘畫’游戲區(qū)域和方塊。消行功能函數(shù)clearrow(),利用將假設可以移動時保存的界面copymap的每一行與1進行與運算,若結(jié)果為1,則說明已滿行,將整行的1全部修改為0即消行,且保存界面縱坐標全部減1,再循環(huán)檢查整個游戲區(qū)域是否還有滿行,若無則將游戲區(qū)域畫出來。
該俄羅斯方塊游戲?qū)崿F(xiàn)了開始游戲、暫停游戲、重新開始、更改顏色、旋轉(zhuǎn)游戲、網(wǎng)格顯示、方塊提示、打開聲音、是否墜落、添加方塊等功能。用戶界面中,顯示玩家姓名、級別、得分和消行數(shù),方塊在一定的區(qū)域內(nèi)運動和變形[15]。
文中對經(jīng)典的俄羅斯方塊游戲,提出一種基于Qt框架的設計方法。該設計在確保該游戲傳統(tǒng)功能的基礎上,增加了添加障礙方塊和旋轉(zhuǎn)游戲區(qū)域等功能,顯著提升了游戲的趣味性與高效性,滿足了玩家在游戲中尋求刺激的需求,對類似的游戲開發(fā)也有一定的借鑒作用。
[1]劉步林.Delphi開發(fā)俄羅斯方塊游戲[J].電腦編程技巧與維護,2015(2):26-31.
[2]劉峰國.漫談經(jīng)典游戲系列的起源[J].計算機與網(wǎng)絡,2015(17):20-21
[3]于翀.JAVA開發(fā)網(wǎng)絡化對戰(zhàn)俄羅斯方塊游戲的可行性[J].電子技術與軟件工程,2014(11):271-272.
[4]Vista看天下.俄羅斯方塊憑什么火了30年[J].現(xiàn)代青年(細節(jié)版),2014(8):63-65.
[5]曾慶維,馮鎳.一種基于玩家水平的俄羅斯方塊游戲[J].軟件導刊,2014(1):25-30.
[6]趙志剛.基于J2ME的藍牙聯(lián)網(wǎng)俄羅斯方塊游戲的設計與實現(xiàn)[D].山東大學,2013.
[7]張昱宏,康 翼,葉 喜.基于俄羅斯方塊化的多功能家具設計[J].家具與室內(nèi)裝飾,2016(2):32-34.
[8]樊峰.基于FPGA及NIOS嵌入式處理器的俄羅斯方塊游戲設計[D].武漢:武漢輕工大學,2013.
[9]于龍海,羅辰杰,王曉萍,等.俄羅斯方塊的結(jié)構(gòu)化匯編語言程序設計[J].單片機與嵌入式系統(tǒng)應用,2015(12):15-18.
[10]殷志堅,段曉磊.基于EasyX的俄羅斯方塊游戲的設計和分析[J].科技傳播,2015(21):137,157.
[11]王文舉.C#語言開發(fā)俄羅斯方塊游戲[J].電腦編程技巧與維戶,2013(3):73-79.
[12]孟蕓,朱肖安,羅劉敏,等.基于C語言的俄羅斯方塊的設計與實現(xiàn)[J].硅谷,2014(23):19-20.
[13]楊樺,周春容.俄羅斯方塊游戲中關鍵算法的分析與實現(xiàn)[J].電腦編程技巧與維戶,2013(12):10-12.
[14]孟 蕓,朱肖安,羅劉敏,等.基于C語言的俄羅斯方塊的設計與實現(xiàn)[J].硅谷,2014(23):19-20.
[15]王西艷.俄羅斯方塊游戲的設計與實現(xiàn)[J].辦公自動化,2013(20):63-64.
Tetris design based on Qt components
MA Li1,XUE Gen-qi2,3,LV Hai-lian1
(1.School of Computer(Software),Pingdingshan University,Pingdingshan 467000,China;
2.Welding Technology and Pressure Vessel Laboratory of Pinggao group Co.,Ltd.,Pingdingshan 467001,China;3.Henan Pinggao Electric CO.,Ltd.,Pingdingshan 467001,China)
In order to improve the interest and efficiency of traditional classic tetris game,design scheme based on Qt components is proposed.On the basis of the traditional game function,added obstacle squares and rotating function such as game area,the interest and efficiency of the game is significantly increased,it bring much better experience to game player. The design key is focusing on analysis and judgment game elements,game algorithm and square running way,F(xiàn)inally the effectiveness of the design are verified by running the game.
Qt;tetris;collision detection;running state judgment
TN802
A
1674-6236(2016)21-0027-04
2016-02-24稿件編號:201602125
國家自然科學基金(61503206)
馬 麗(1968—),女,河南輝縣人,碩士,教授。研究方向:計算機方向教學和軟件需求工程、模式識別與智能控制方向的研究。