畢業(yè)論文-勞拉方塊游戲設(shè)計與實現(xiàn)_第1頁
畢業(yè)論文-勞拉方塊游戲設(shè)計與實現(xiàn)_第2頁
畢業(yè)論文-勞拉方塊游戲設(shè)計與實現(xiàn)_第3頁
畢業(yè)論文-勞拉方塊游戲設(shè)計與實現(xiàn)_第4頁
畢業(yè)論文-勞拉方塊游戲設(shè)計與實現(xiàn)_第5頁
已閱讀5頁,還剩60頁未讀, 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

太原理工大學(xué)畢業(yè)設(shè)計(論文)用紙.緒論1.1課題研究的目的及意義勞拉方塊曾經(jīng)是一款非常熱門的小游戲,頻頻出現(xiàn)在電視機游戲和掌上游戲里。它簡單易上手,但是變化無窮,充滿了挑戰(zhàn)。相信很多我的同齡人還記得小時候坐在小霸王游戲機前,緊握著游戲手柄,盯著屏幕上的游戲,玩到忘記了吃飯。大部分人應(yīng)該都是在那個時候接觸并喜歡上這款游戲的。人們不僅從這款游戲中得到了樂趣,而且從其中收獲了成就感。在游戲設(shè)計領(lǐng)域,勞拉方塊不僅僅是一款充滿其妙體驗的小游戲,更是一個啟蒙。無數(shù)人編寫游戲程序都是從勞拉方塊開始的,因為這既是一個檢驗RAD開發(fā)工具的好方法,也是檢驗一個人對開發(fā)語言、環(huán)境和基本數(shù)據(jù)結(jié)構(gòu)知識熟練程度的便捷途徑。本次的設(shè)計與實現(xiàn)是在Linux[1]平臺上完成的。1.2電子游戲的發(fā)展?fàn)顩r游戲最早的雛形,可以追溯到人類原始社會流行的活動:扔石頭、投擲帶尖的棍子。這些最早的游戲顯然是以增強生存技能作為初衷。社會進步后,棋牌類游戲、競技類游戲甚至電子游戲開始出現(xiàn)。電子游戲是其中的主角之一。勞拉方塊在紅白機時代曾是電子游戲中的天王之一,我國的用戶大部分是通過紅白機了解、喜歡上它的,無數(shù)人和它一起留在了那個年代。對于普通用戶來說,它容易上手,操作簡單,且游戲過程中變化無窮,在其多個衍生版本中,更是出現(xiàn)了聯(lián)機版勞拉方塊,使其成為一款競技游戲,給用戶提供了一個展現(xiàn)自己高超水平的場所。勞拉方塊隨著PC機的更迭不斷演變,現(xiàn)在已經(jīng)成為經(jīng)典。這款游戲的核心是通過不斷變化的方塊來訓(xùn)練人的反應(yīng)能力。隨著開發(fā)工具的更新?lián)Q代,現(xiàn)在這款游戲已經(jīng)成為學(xué)習(xí)軟件設(shè)計入門的一個經(jīng)典案例。本文中實現(xiàn)勞拉方塊是利用數(shù)組作為方塊的數(shù)據(jù)結(jié)構(gòu)[2],對于初學(xué)者可仿照此類方法進行設(shè)計,從而了解游戲軟件的設(shè)計與開發(fā)過程。1.2.1電子游戲及其分類電子游戲,也就是運行在家用電腦、家用電子游戲機或是掌中寶游戲機及街機上的電子游戲程序。電子游戲作為一款互動娛樂型軟件,結(jié)合了劇情、程序、動畫、美術(shù)、音樂等技術(shù),從電子游戲的分類來看,有著多種分類方式。按照游戲類型,傳統(tǒng)的游戲分類將其分為第一人稱射擊游戲、角色扮演游戲、即時戰(zhàn)略類游戲、策略類游戲等。而按照游戲運行平臺的不同,又可以將電子游戲分為手機游戲、在線游戲、單機版PC游戲、游戲機游戲、互動電視游戲?,F(xiàn)在,雖然未制定標(biāo)準(zhǔn),但行業(yè)內(nèi)將游戲進行標(biāo)準(zhǔn)分類,分為街機游戲、網(wǎng)絡(luò)游戲、單機版PC游戲、互動電視游戲四大類。論文中采用此標(biāo)準(zhǔn)。在互聯(lián)網(wǎng)(局域網(wǎng))技術(shù)出現(xiàn)以前,電子游戲都是以單機版游戲的形式出現(xiàn)的?;ヂ?lián)網(wǎng)技術(shù)出現(xiàn)后,玩家之間實現(xiàn)了同時在線娛樂,電子游戲的一部分步入網(wǎng)絡(luò)游戲的陣營。所謂“網(wǎng)絡(luò)游戲”,是指通過人與人之間的互動達到交流、休閑和娛樂的目的。網(wǎng)絡(luò)游戲的實現(xiàn),大大增加了游戲的互動性、真實性,豐富了電子游戲的內(nèi)涵?,F(xiàn)在,隨著計算機與網(wǎng)絡(luò)技術(shù)的發(fā)展,電子游戲獲得了長足的進步,已經(jīng)成為當(dāng)今社會不可缺少的精神食糧。1.2.2電子游戲發(fā)展現(xiàn)狀電子游戲最初誕生于美國,一個還在MIT就讀的學(xué)生于1971年設(shè)計了世界上第一個業(yè)務(wù)用游戲機[3],游戲的名字叫做《電腦空間》。繼第一款游戲問世之后,各類游戲開始紛紛被制作出來娛樂玩家。以歐美市場和日本市場最為成功。目前,世界第一大游戲市場仍是美國,其遵循以發(fā)行商為主的產(chǎn)業(yè)開發(fā)鏈模式,根據(jù)美國市場調(diào)查公司NPDGroup調(diào)查統(tǒng)計,美國2006年游戲總銷售金額(包括家用、掌上型主機及軟件)為137億美元,占了全球游戲市場的43%。日本的游戲市場也是淵源已久。從上世紀(jì)六十年代初的街機,到六七十年代的家用游戲機,再到八九十年代的掌上游戲機,經(jīng)過30多年的發(fā)展,如今的日本游戲產(chǎn)業(yè)已經(jīng)成為第一娛樂產(chǎn)業(yè),電玩業(yè)已經(jīng)變成國家的經(jīng)濟支柱之一,每年占到GDP的1/5。韓國則是當(dāng)今網(wǎng)絡(luò)游戲產(chǎn)業(yè)最發(fā)達的國家之一。如今國內(nèi)市場超過60%的游戲產(chǎn)品都來自韓國的游戲軟件開發(fā)商。韓國的游戲產(chǎn)業(yè)一度得到政府的大力支持。由文化觀光部出面組建韓國游戲支援中心[4],向韓國游戲產(chǎn)業(yè)提供從資金到技術(shù)上的多方面支援;成立游戲投資聯(lián)盟,政府每年向游戲產(chǎn)業(yè)投入的資金多達500億韓元,并為游戲企業(yè)提供長期的低息貸款;設(shè)立信息化基金和文化產(chǎn)業(yè)基金,為游戲產(chǎn)業(yè)服務(wù);對指定的風(fēng)險企業(yè)實行各種稅制優(yōu)惠政策,減少甚至免除游戲企業(yè)的稅務(wù)負擔(dān);建設(shè)游戲產(chǎn)業(yè)基地以扶持中小游戲企業(yè)的發(fā)展;對從事游戲產(chǎn)業(yè)的高科技人才免除兩年的兵役。此外,韓國還開設(shè)了眾多的游戲院校,以大力培養(yǎng)游戲人才,從而為游戲生產(chǎn)提供了基礎(chǔ)保障。與電子游戲發(fā)達的國家相比,在電子游戲方面,我國還與它們存在較大的差距。目前,我國的游戲市場正處在發(fā)展階段,但在市面上流動的游戲軟件主要還是來自于美國、日本、韓國等地,但在一些政策和市場的機遇下,國內(nèi)的廠家正在蓬勃發(fā)展,國產(chǎn)原創(chuàng)游戲即將成為游戲的發(fā)展主流。中國的游戲產(chǎn)業(yè)經(jīng)過80年代初期臺灣廠商的探索至90年代,開始了自己的研發(fā)、發(fā)行的歷程,直至網(wǎng)絡(luò)游戲的風(fēng)行,中國的網(wǎng)絡(luò)游戲開始有了飛速的發(fā)展。1983年,智冠科技有限公司在中國臺灣成立,為全球第一家簽訂授權(quán)重制中文版產(chǎn)品代理銷售合約的公司,2000年智冠在臺灣股票上市,2002年其控股的中華網(wǎng)龍在臺灣上市。1996年底,UBISOFT上海分公司暨上海育碧電腦軟件有限公司成立。同年,全球游戲軟件領(lǐng)軍企業(yè)EA在中國上海成立辦事處。1997年,由尚洋公司制作的《血獅》正式上市。1997年,北京新天地互動多媒體技術(shù)有限公司成立,該公司引進了《古墓麗影III》(TombRaiderIII)、《盟軍敢死隊》等著名歐美游戲,并在1999年在中國率先掀起“游戲軟件價格革命”,全面推行50元的價格體系,從此正版游戲價格開始貼近大眾消費者。1999年,業(yè)內(nèi)估算中國電腦游戲市場(正版)約1.5億元人民幣。2000年,大陸華彩軟件代理發(fā)行第一款中文MMORPG《萬王之王》正式推出,該游戲于1999年在臺灣發(fā)行,由臺灣雷爵資訊(Lager)開發(fā)。也在2000年,繼《萬王之王》、《石器時代》、《網(wǎng)絡(luò)三國》在臺灣上市之后,游戲桔子推出了《天堂》,游戲桔子成立于1995年,1999年以《便利店》在臺灣奠定了地位。《天堂》這款由韓國著名游戲公司Ncsoft研發(fā)的網(wǎng)絡(luò)游戲不但在本國大獲成功,也在臺灣再次奪冠。2001年初,北京華義在中國大陸地區(qū)正式推出了《石器時代》,華義國際股份有限公司于1993年在臺北成立,2001年在臺灣股票上市?!妒鲿r代》成為大陸當(dāng)時最流行的網(wǎng)絡(luò)游戲。2001年,天人互動軟件技術(shù)有限公司在北京成立。當(dāng)年與SEGA結(jié)成PC游戲業(yè)務(wù)的戰(zhàn)略合作關(guān)系,發(fā)行了《櫻花大戰(zhàn)Ⅱ》《文明Ⅲ》《無冬之夜》等經(jīng)典游戲,2002年,引進在歐美網(wǎng)絡(luò)游戲《魔劍》(ShadowBane),這是首款在中國測試的歐美網(wǎng)絡(luò)游戲。2001年5月,“聯(lián)眾世界”經(jīng)過3年多的迅速成長,以同時在線17萬人、注冊用戶約1800萬的規(guī)模,成為當(dāng)時世界用戶數(shù)量第一的在線游戲網(wǎng)站。2005年1月21日,中央電視臺報道:我國網(wǎng)絡(luò)游戲產(chǎn)業(yè)當(dāng)年增加了50%,今后幾年都將以50%以上的速度增長;第一屆中國網(wǎng)絡(luò)游戲年會報道:中國國內(nèi)網(wǎng)絡(luò)游戲2004年規(guī)模達24.7億元,2009年規(guī)模將達到109.6億元。1.3研究的主要內(nèi)容俄羅斯方塊是一款風(fēng)靡全球的電視游戲機和掌上游戲機游戲,它曾經(jīng)造成的轟動與造成的經(jīng)濟價值可以說是游戲史上的一件大事。這款游戲最初是由蘇聯(lián)的游戲制作人AlexPajitnov制作的,它看似簡單但卻變化無窮,令人上癮。相信大多數(shù)用戶都還記得為它癡迷得茶不思飯不想的那個俄羅斯方塊時代。從游戲的基本玩法出發(fā),主要就是俄羅斯方塊的形狀和旋轉(zhuǎn),我在設(shè)計中在一個圖片框中構(gòu)造了一些的網(wǎng)狀小塊,由這些小塊組合成新的形狀,每四個小塊連接在一起就可以構(gòu)造出一種造型,因此我總共設(shè)計了7種造型,每種造型又可以通過旋轉(zhuǎn)而變化出2到4種形狀,利用隨機函數(shù)在一個預(yù)覽窗體中提前展示形狀供用戶參考,在游戲窗體中用戶就可以使用鍵盤的方向鍵來控制方塊的運動,然后對每一行進行判斷,如果有某行的方塊是滿的,則消除這行的方塊,并且使上面的方塊自由下落,最后就可以得出用戶的分數(shù)。1.4研究的目的和意義那么研究基于Qt的勞拉方塊游戲有什么意義呢?雖然目前勞拉方塊游戲已經(jīng)有各種語言的不同版本,并且已經(jīng)將其搬上了網(wǎng)絡(luò)的平臺,單人、雙人單機對戰(zhàn)和雙人網(wǎng)絡(luò)對戰(zhàn)等各種模式均已被大眾熟知。由于開發(fā)平臺不統(tǒng)一,造成軟件的管理和使用極不方便,并且容易受到軟硬件環(huán)境更新的影響,限制了這些新技術(shù)在科研生產(chǎn)中發(fā)揮更好的作用.如果舍棄原有軟件而重新開發(fā),將會耗費大量的人力和資金,而且浪費了許多成熟的軟件成果。而Qt在源代碼級上實現(xiàn)了跨平臺特性,極大的支持了跨平臺通用軟件的開發(fā)。Qt可以用同一個源程序在不同平臺上編譯鏈接,生成目標(biāo)代碼,并取得相同的運行效果,稱為“一次編寫,隨處編譯”,利用這種方法充分實現(xiàn)了程序的跨平臺運行。這種基于源代碼的跨平臺特性不僅解決了性能的問題,而且可以發(fā)揮各個平臺的優(yōu)勢,充分利用每個平臺自身的特點;并且即可以在新環(huán)境下實現(xiàn)原有軟件的功能和特點,減少開發(fā)費用,還可以改進原有軟件的不足,增加新的需求,從而提高軟件的質(zhì)量,延長軟件生命期。因此,利用Linux下基于Qt的應(yīng)用程序開發(fā)是一個非常有意義的課題,具有重要的研究和商業(yè)價值。另外,通過本游戲的設(shè)計,檢驗了學(xué)習(xí)效果和動手能力,進一步深入Qt的學(xué)習(xí),提高自己的編程水平,從而達到理論與實踐相結(jié)合的目的。在成為一個真正的游戲開發(fā)者的路上,勞拉方塊是一個完美開始。為什么?因為它包括任何一個游戲中所有的元素。并且,不需要藝術(shù)家般的才能就能做出非常好看的勞拉方塊游戲。任何一個能畫出方塊的人,每個作圖形程序的人,就能做出商業(yè)品質(zhì)的勞拉方塊游戲。以勞拉方塊開始還有另外一個好處,不僅能做出一個完整的既好玩又容易上癮游戲,而且它看上來和那些商業(yè)版本沒什么區(qū)別。方塊就是方塊,不管是誰畫出它們的,而且tetraminos(勞拉方塊中使用的形狀)也不過是一些方塊的組合。勞拉方塊擁有所有游戲共通的獨立成份。它有一個游戲循環(huán)(這個過程被反復(fù)執(zhí)行直到游戲退出)。這個游戲循環(huán)讀取玩家的輸入,處理這個輸入,然后更新游戲的元素(下落的tetraminos),并且檢查是輸還是贏。以后要做的所有的簡單的游戲都要用到這些東西,所以學(xué)習(xí)這個過程并且實現(xiàn)它是非常重要的。當(dāng)?shù)谝淮瓮瓿伤?,以后再做游戲時就能看出那個游戲有多難以及要花多長時間。如果沒有完整的完成過這些,哪怕一次,就永遠不能完整地正確領(lǐng)會其中的每個元素。當(dāng)做大的項目時,就更不能確定其復(fù)雜性及所要的時間。如果甚至不能正確地領(lǐng)會這整個過程(因為你沒能完成它),可能是沒能建立一個合適的時間表或估計合適的時間,更有可能的是不夠努力。還有,玩勞拉方塊可以練習(xí)人的反映能力,開始時快速的下降會讓人手無足措,但適應(yīng)了之后就會發(fā)現(xiàn)自己的反應(yīng)力變的很快了。另外長時間的手指活動可以讓人血液流通加快有利健康。還有勞拉方塊高手都知道要想贏,就要有遠大的布局,決不能只局限于一點一點的減,這在無形中就提高了人的智慧。

2.可行性研究2.1設(shè)計目的通過本游戲的設(shè)計,結(jié)合自己在杰普軟件所學(xué)到的知識,設(shè)計開發(fā)勞拉方塊游戲,能培養(yǎng)自己的動手和思考能力,初步掌握軟件工程的系統(tǒng)理論,加強自身對Qt基礎(chǔ)編程知識的理解,提高自己編寫程序的水平,從而達到理論與實踐相結(jié)合的目的。2.2軟件的定義該游戲軟件開發(fā)的主要任務(wù)是實現(xiàn)游戲的可視化界面操作。開發(fā)過程遵循工程開發(fā)規(guī)范,采用C++來實現(xiàn)界面和事件的控制,用戶可以通過菜單欄的相應(yīng)選項和上下左右四個方向鍵對游戲進行可視化的操控。游戲的開始、結(jié)束、方塊變換、積分以及等級等功能都可以通過這些來進行調(diào)節(jié)。本游戲開發(fā)過程中還有很多生疏和疑問,實現(xiàn)的功能也較為簡單,旨在能更好地了解C++的編寫技巧和規(guī)范,為今后的工作積累經(jīng)驗。2.3可行性分析技術(shù)可行性:C++語言中集成了很多標(biāo)準(zhǔn)類庫,可以直接調(diào)用,Qt中大量的圖形界面庫和優(yōu)良的封裝和跨平臺機制,使得實現(xiàn)界面的可視化以及事件的操控簡單了很多。經(jīng)濟可行性:本游戲的開發(fā)旨在提升自己的語言邏輯水平,完成畢業(yè)設(shè)計,考慮到的其他因素并不多,外界阻力很小,對經(jīng)濟要求不高。社會可行性:本游戲設(shè)計完成后僅作畢業(yè)設(shè)計和私人使用,且設(shè)計內(nèi)容健康,不會違反法律,不會對社會造成不良影響。2.4結(jié)論意見綜上所述,本游戲軟件的技術(shù)成熟、完備。各方面均無重大問題,因此本游戲軟件可開始著手編寫。3.需求分析3.1引言對軟件需求完全理解對于軟件開發(fā)工作的成功是至關(guān)重要的,需求說明的任務(wù)是發(fā)現(xiàn)、規(guī)范的過程,有益于提高軟件開發(fā)過程中的能見度,便于對軟件開發(fā)過程中的控制與管理,便于采用工程方法開發(fā)軟件,提高軟件的質(zhì)量,便于開發(fā)人員、維護人員、管理人員之間的交流、協(xié)作,并作為工作成果的原始依據(jù),并且在向潛在用戶傳遞軟件功能、性能需求,使其能夠判斷該軟件是否與自己的需求相關(guān)。3.2游戲需求28種狀態(tài)的方塊隨機產(chǎn)生,自由下落,落下時可由玩家用上、下、左、右控制鍵控制翻轉(zhuǎn)和移動,以便以玩家所需要的形態(tài)和位置落下。如果落下時,方塊的方格能填滿某一行,則這一行可消去。消去一行后,游戲可給玩家加分,若由存在空格的方塊填滿整個窗口,則游戲失敗。游戲功能需求如下:游戲界面需求:設(shè)計良好的游戲界面可以讓玩家充分感受到游戲帶來的娛樂性,在設(shè)計好的一定的區(qū)域內(nèi)運動和變形,不同的色塊讓其擁有不同的顏色,這樣看起來會有一定的美感。游戲形狀需求:用數(shù)組作為存儲方塊8種狀態(tài)的數(shù)據(jù)結(jié)構(gòu),即長條形、Z字形、反Z形、田字形、7字形、反7形、T字型,各個方塊要能實現(xiàn)它的變形,可設(shè)為順時針或逆時針變形。鍵盤處理事件需求:方塊下落時,可通過鍵盤方向鍵(上、下、左、右鍵)對該方塊進行順時針變形、逆時針變形、向左、向右移動,D鍵可以使方塊加速下落,SPACE鍵可以使方塊瞬間落下。鼠標(biāo)處理事件需求:通過點擊菜單欄中相應(yīng)的菜單項,可以實現(xiàn)游戲的開始、結(jié)束,方塊形狀的變換,分數(shù)、等級的顯示,以及游戲幫助等功能。顯示需求:當(dāng)不同的方塊填滿一行時可以消行,剩余方塊向下移動并統(tǒng)計分數(shù)。當(dāng)達到一定分數(shù)的時候,會增加相應(yīng)的等級。3.3開發(fā)環(huán)境介于開發(fā)工具和軟件使用的環(huán)境,我選擇了如下的開發(fā)環(huán)境:操作系統(tǒng):MicrosoftWindows7Ultimate(32位)內(nèi)存:3G硬盤:500GCPU:Intel(R)CORE(TM)I5CPUM480交互工具:鍵盤/鼠標(biāo)顯示器:通用顯示器開發(fā)工具:Qt5.33.4接口控制本游戲通過鍵盤進行操作,在Linux操作系統(tǒng)下,利用鍵盤的上、下、左、右、D以及SPACE鍵對方塊進行移動變形,要使用鍵盤的接口事件。3.5方案論證學(xué)?,F(xiàn)已開設(shè)的課程有C語言、C++、java,我自學(xué)了Qt,加上自己瀏覽了一些其它相關(guān)的資料,通過網(wǎng)上以及圖書館的資料,知道可以通過C,C++和Qt,VB,Delphi,Java實現(xiàn)勞拉方塊游戲的設(shè)計。下面簡單介紹下VB、Java、Qt各自的優(yōu)缺點:3.5.1VB的特點全稱VisualBasic,它是以Basic語言作為其基本語言的一種可視化編程工具。在中國乃至全世界都能看到它的身影,它曾是在中國最為流行的編程工具,到現(xiàn)在還占據(jù)著非常重要的地位,對于它的好壞大家都有一定的了解,VB作為一種較早出現(xiàn)的開發(fā)程序以其容易學(xué)習(xí),開發(fā)效率較高,具有完善的幫助系統(tǒng)等優(yōu)點曾影響了好幾代編程人員,但是由于VB不具備跨平臺這個特性,從而也決定了VB在未來的軟件開發(fā)中將會逐漸地退出其歷史舞臺;它對組件技術(shù)的支持是基于COM和ActiveX,對于組件技術(shù)不斷完善發(fā)展的今天,它也顯出了它的落后性;同時VB在進行系統(tǒng)底層開發(fā)的時候也是相對復(fù)雜的,調(diào)用API函數(shù)需聲明,調(diào)用不方便,不能進行DDK編程,不可能深入Ring0編程,不能嵌套匯編;而且面向?qū)ο蟮奶匦圆?;網(wǎng)絡(luò)功能和數(shù)據(jù)庫功能也沒有非常突出的表現(xiàn),綜上所述,VB作為一種可視化的開發(fā)工具由于其本身的局限性,導(dǎo)致了它在未來軟件開發(fā)中逐步被其他工具所代替。3.5.2Java的特點(1)安全性Java是一種安全的網(wǎng)絡(luò)編程語言,不支持指針類型,一切對內(nèi)存的訪問都必須通過對象的實例來實現(xiàn)。這樣能夠防止他人使用欺騙手段訪問對象的私有成員,也能夠避免在指針操作中易產(chǎn)生的錯誤。此外,Java的安全性體現(xiàn)在多個層次上:在編譯層,有語法檢查;在解釋層,有字節(jié)碼校驗器,可進行代碼段格式測試和規(guī)則檢查、訪問權(quán)限和類型轉(zhuǎn)換合法性檢查、操作數(shù)堆棧的上溢和下溢檢測、代碼參數(shù)類型合法性檢查等;在平臺層上,通過配置策略,可設(shè)定訪問資源域,無須區(qū)分本地或遠程。(2)可移植性Java具備有很好的移植性,這主要得益于它與平臺無關(guān)的特性。同時,Java的類庫中也實現(xiàn)了與平臺無關(guān)的接口,這使得這些類庫也能移植。同時,Java編譯器主要是由Java本身來實現(xiàn)的,Java的運行系統(tǒng)(解釋器)由標(biāo)準(zhǔn)C語言實現(xiàn),因而整個Java系統(tǒng)都具有可移植性。(3)多線程機制Java具有多線程機制,這使得應(yīng)用程序能夠并行地執(zhí)行。它的同步機制也保證了對共享數(shù)據(jù)的共享操作,而且線程具有優(yōu)先級的機制,有助于分別使用不同線程完成特定行為,也提高了交互的實時響應(yīng)能力。Java的多線程技術(shù)使網(wǎng)上實時交互實現(xiàn)很容易,從而為解決網(wǎng)上大數(shù)量的客戶訪問提供了技術(shù)基礎(chǔ)。(4)跨平臺通常,在Windows下編寫的程序是不能直接拿到UNIX上運行的,因為程序的執(zhí)行最終必須轉(zhuǎn)換成為計算機硬件的機器指令來執(zhí)行,專門為某種計算機硬件和操作系統(tǒng)編寫的程序是不能夠直接放到其他類型的計算機硬件上執(zhí)行的,至少要做移植工作。要想讓程序能夠在不同的計算機上運行,就要求程序設(shè)計語言能夠跨越各種軟件和硬件平臺,而Java恰恰滿足了這一需求。Java編譯器能夠產(chǎn)生一種與計算機體系結(jié)構(gòu)無關(guān)的字節(jié)指令,只要安裝了Java虛擬機,Java就可以在相應(yīng)的處理機上執(zhí)行。3.5.3Qt的特點Qt擁有一個單一的Library,讓你開發(fā)各種不同平臺的程序,目前支持Windows、Linux、Mac、UNIX、EmbeddedLinux,講白話點,就是它提供了一個Library讓你開發(fā)GUI程序,寫好之后,只要在各平臺重新Compile后,就可以在各平臺執(zhí)行,而且使用完整的ANSIC++語言,且不限Compiler,只要是C++的Compiler都可以,重要的是,該Library相當(dāng)漂亮,寫出來的程序很像C++Builder或.NETFramework的那樣精簡,不會向MFC那樣復(fù)雜。目前Qt已經(jīng)到第四個版本,GUI部分算支持的相當(dāng)完整,且支持數(shù)據(jù)庫、XML、Multi-Thread、Socket等方面的programming。若以后臺角度來說,無論后端是什么數(shù)據(jù)庫,只要透過相同的Interface,不同數(shù)據(jù)庫的Class來實做這個Interface,前端GUI的程序?qū)懛ㄍ耆挥酶淖?,同理,面對不同的OS,理論上只要透過相同的Interface,不同OS的Class各自實做這個Interface,前端GUI的程序也完全不用改變,最后只要靠Compiler將程序compile成各平臺的原生程序即可,這樣即可保證其執(zhí)行速度,不用再靠VirtualMachine。但很可惜這個理想,這么多年來都沒人可以做出來。Qt無疑是GUI終極解決方案,有強力的ANSIC/C++語言背書,又有單一的GUILibrary,且精簡漂亮,又能Compile成各平臺的原生執(zhí)行檔,幾乎是最完美的解決方案了。3.5.4方案的選擇經(jīng)過以上比較好,考慮到Qt的眾多良好特性,尤其是其跨平臺性,決定使用Qt開發(fā)俄羅斯方塊游戲。3.6Qt簡介Qt是一個1991年由奇趣科技開發(fā)的跨平臺C++圖形用戶界面應(yīng)用程序開發(fā)框架。它既可以開發(fā)GUI程序,也可用于開發(fā)非GUI程序,比如控制臺工具和服務(wù)器。Qt是面向?qū)ο蟮目蚣埽褂锰厥獾拇a生成擴展(稱為元對象編譯器(MetaObjectCompiler,moc))以及一些宏,易于擴展,允許組件編程。2008年,奇趣科技被諾基亞公司收購,QT也因此成為諾基亞旗下的編程語言工具。2012年,Qt被Digia收購。但是真正使得Qt在自由軟件界的眾多Widgets(如Lesstif,Gtk,EZWGL,Xforms,fltk等等)中脫穎而出的還是基于Qt的重量級軟件KDE。有趣的是,KDE也是使得Trolltech公司承受巨大壓力的一個原因。下面我們將來看看這場著名的自由軟件圣戰(zhàn)--"KDE/QT.VS.Gnome/Gtk"是怎么發(fā)生的。在Unix的圖形界面一向是以MIT[5]的XWindow系統(tǒng)為標(biāo)準(zhǔn),可是在商業(yè)應(yīng)用上有兩大流派,一派是以Sun公司領(lǐng)導(dǎo)的Openlook陣營,一派IBM/HP領(lǐng)導(dǎo)的OSF(OpenSoftwareFoundation)的Motif,雙方經(jīng)過多年競爭之后,Motif最終勝出,成為最普遍使用的界面庫,后來雙方又妥協(xié)出一個CDE(CommonDesktopEnviroment)作為一個標(biāo)準(zhǔn)的圖形界面。但是Motif/CDER的價格非常昂貴,在這同時微軟的Windows圖形界面發(fā)展速度非常快,而Unix界的后起之秀Linux也急需一個可靠并且免費的圖形界面。1996年10月,由開發(fā)圖形排版工具Lyx的德國人MatthiasEttrich發(fā)起了KDE計劃。KDE的全稱為KDesktopEnvironment,可以看出是針對CDE。KDE本身是采用GPL宣言的,但是KDE卻是使用Qt來作為其底層庫,因為當(dāng)時Qt已經(jīng)將其Unix版本自由發(fā)布了,但是Qt并不遵循GPL,因此KDE被很多自由軟件的作者攻擊,認為利用非自由軟件開發(fā)違背了GPL的精神,于是GNU的狂熱信徒兵分兩路,一路是去制作Harmonny,試圖重寫一套兼容于Qt的替代品,另一路是由一個26歲的墨西哥程序員MiguelDeIcaza領(lǐng)導(dǎo)下重新開發(fā)一套叫GNOME(GNUNetworkObjectEnviroment)來替代KDE。由于Linux界的老大RedHat不喜歡KDE/Qt的版權(quán),因此RedHat甚至專門派出了幾個全職程序員來加入GNOME進行開發(fā)工作,于是一場同MotifVSOpenlook相似的圣戰(zhàn)就這么打起來了。Trolltech為了KDE曾數(shù)次修改Qt的版權(quán),從成立KDEFreeQt基金會到采用QPL,可謂是費盡心機,但是GNOME采用的GTK一開始就是完全的GPL,因此在這個方面GNOME有一定的優(yōu)勢,加上Qt/KDE采用C++開發(fā),入門的門檻比較高,而GTK/Gnome采用C,因此GNOME吸引了更多的自由軟件開發(fā)者,但是KDE畢竟先走了一步,推出的KDE1.1.2十分穩(wěn)定,而當(dāng)時急忙中推出的GNOME1.0的系統(tǒng)穩(wěn)定性奇差,有人甚至笑稱GNOME1.0還沒有KDE1.0Alpha穩(wěn)定。但是GNOME后來發(fā)展比較快,大有迎頭趕上的勢頭。當(dāng)時雙方的開發(fā)者在網(wǎng)絡(luò)上炒得天翻地覆,連Linux之父Linus只是說了一句喜歡用KDE都倍受指責(zé)。戰(zhàn)爭到了第三個年頭,也就是2000年,可謂是風(fēng)云突變,一個接一個重大的事件先后發(fā)生:首先是一批從Apple公司出來的工程師成立了一個叫Eazel的公司替GNOME設(shè)計界面,然后是一批GNOME程序員成立了一個HelixCode公司替GNOME提供商業(yè)支持,而大家期待以久的KDE2.0也終于發(fā)布了,這恐怕是目前最為龐大的自由軟件了之一,除了KDE本身,還包括Koffice套件,和集成開發(fā)環(huán)境Kdevelop等等大批軟件,其主力軟件Kounqueror也是第一個可以同微軟的InternetExploer相抗衡的瀏覽器。而Sun公司,RedHat公司,Eazel公司,HelixCode等一批公司成立了一個GNOME基金會,Sun還宣布將把重量級辦公軟件Staroffice同GNOME集成,Trolltech公司自然不能坐以待斃,于今年10月4日將Qt的freeedition變?yōu)镚PL宣言,徹底解決了KDE的版權(quán)問題,又推出了嵌入式Qt,給了GNOME陣營一個有力的回擊。到現(xiàn)在為止,這場戰(zhàn)爭還在繼續(xù),相信我們不能很快看到結(jié)果。一般說來,目前GNOME吸引的公司比較多,但是KDE/Qt的開發(fā)的效率和質(zhì)量比GNOME高,而且在Office/嵌入式環(huán)境中先走一步,在一定時間內(nèi)還將處于優(yōu)勢地位。那么對于用戶來說,如何在Qt/GTK中作出選擇呢?一般來說,如果用戶使用C++,對庫的穩(wěn)定性,健壯性要求比較高,并且希望跨平臺開發(fā)的話,那么使用Qt是較好的選擇,但是值得注意的是,雖然Qt的FreeEdition采用了GPL宣言,但是如果你開發(fā)Windows上的Qt軟件或者是Unix上的商業(yè)軟件,還是需要向Trolltech公司支付版權(quán)費用的。QtCreator是一個用于Qt開發(fā)跨平臺集成開發(fā)環(huán)境(IDE),QtCreator可帶來兩大關(guān)鍵益處:提供首個專為支持跨平臺開發(fā)而設(shè)計的集成開發(fā)環(huán)境(IDE),并確保首次接觸Qt框架的開發(fā)人員能迅速上手和操作。并且它包含了一套用于創(chuàng)建和測試基于Qt應(yīng)用程序的高效工具,包括:一個高級的C++代碼編輯器、上下文感知幫助系統(tǒng)、可視化調(diào)試器、源代碼管理、項目和構(gòu)建管理工具。QtCreator2.3.1和Qt4.7共同構(gòu)成的QtSDK,包含了開發(fā)跨平臺應(yīng)用程序所需的全部功能。Qt支持windows平臺、linux/unix平臺、macintosh平臺、Embedded平臺等,所以Qt所開發(fā)的應(yīng)用具有良好地可移植性。Qt官網(wǎng)()上有完整的SDK下載,下載開發(fā)平臺的SDK,下載完成后點擊即可安裝。安裝完成后,運行Qt。3.7Qt的類庫Qt類庫大致可以分為三個部分:控件,框架和工具。(1)控件控件部分包括環(huán)境控件,主窗口控件,標(biāo)準(zhǔn)對話框,基本的GUI控件,擴展GUI控件,GUI組織控件,以及幫助系統(tǒng)控件。環(huán)境控件為應(yīng)用程序提供全局服務(wù)的類,包括系統(tǒng)設(shè)定、國際化等。例如QTranslator,Qapplication。主窗口類為應(yīng)用程序提供界面框架,可以在上面添加菜單、工具條等,為應(yīng)用程序提供集裝箱的功能,如QMainWindow。標(biāo)準(zhǔn)對話框類是為打開/關(guān)閉文件,選擇顏色等預(yù)先設(shè)計的標(biāo)準(zhǔn)對話框,如QColorDialog,QFileDialog?;究丶ㄋ械腉UI控件,如按鈕、組合框等,如QPushButton。擴展的控件包括樹狀視圖、進度條等,如QListView。GUI組織類負責(zé)對各種控件進行組織以構(gòu)成復(fù)雜的對話框,如QGroupBox。幫助系統(tǒng)控件是為應(yīng)用程序提供在線幫助的類,QStatusBar,QToolTip。(2)框架框架部分包括的是一些抽象的類,通常不可見,如對象模型、抽象控件、繪圖、拖放、控件外觀。對象模型是框架的基礎(chǔ),如QObject??梢姷目丶话銖某橄罂丶缮?,如QButton。繪圖類控制繪圖,如QBrush。拖放類控制拖放操作,如QDragObject??丶庥^類控制控件的外觀如顏色、字體等。例如QColor。(3)工具工具部分包括時間日期和鏈表樹等數(shù)據(jù)結(jié)構(gòu),它們和GUI無關(guān)。普通工具包括鏈表、堆棧、隊列、樹等常見數(shù)據(jù)結(jié)構(gòu),如QArray。圖形處理工具控制圖像的編碼/解碼算法。如QImageIO。I/O控制工具處理I/O的一些類,如QFile。時間和日期工具類處理時間和日期,如Qdate,QTime。另外還有其他雜類如Qsignal,QIconSet等。3.8Qt相比其他圖形界面庫的優(yōu)點(1)優(yōu)良的跨平臺特性。Qt支持下列操作系統(tǒng):MicrosoftWindows95/98、MicrosoftWindowsNT、Linux、Solaris、SunOS、HP-UX、DigitalUNIX(OSF/1、Tru64)、Irix、FreeBSD、BSD/OS、SCO、AIX、OS390和QNX等。(2)面向?qū)ο?。Qt的良好封裝機制使得Qt的模塊化程度非常高,可重用性較好,對于用戶開發(fā)來說是非常方便的。Qt提供了一種稱為signals/slots的安全類型來替代callback,這使得各個元件之間的協(xié)同工作變得十分簡單。(3)豐富的API。Qt包括多達250個以上的C++類,還提供基于模板的collections、serialization、file、I/Odevice、directorymanagement和date/time類。甚至還包括正則表達式的處理功能。(4)支持2D/3D圖形渲染,支持OpenGL。(5)大量的開發(fā)文檔。(6)XML支持。3.9Qt對象間通訊機制對象間通訊是面向?qū)ο蟪绦蛟O(shè)計的一個極其重要的內(nèi)容,類似于MicrosoftMFC的消息映射和事件循環(huán),Qt的對象間通訊采用的是信號—槽(signal—slot)機制,信號就好像是事件,而槽則是響應(yīng)事件的方法。如果需要實現(xiàn)對象間的通訊,只需要把一個對象的信號和另外一個對象的槽使用連接(connect)起來[6]。信號—槽機制說明:Qt下對象間的通訊用信號—槽機制來實現(xiàn)。信號—槽機制是Qt的一個中心特征并且也是它與其它圖形工具包的最不相同的部分。圖3-1直觀地表示了這種機制是如何工作的。圖3-1信號與槽的連接原理圖在圖形用戶界面編程中,經(jīng)常希望一個窗口部件的一個變化被通知給另一個窗口部件。更一般地,希望任何一類對象可以和其它對象進行通訊。例如,如果正在解析一個XML文件,當(dāng)遇到一個新的標(biāo)簽時,也許要通知列表視圖正在用來表達XML文件的結(jié)構(gòu)。較老的工具包是使用一種被稱作回調(diào)的通訊方式來實現(xiàn)同一目的?;卣{(diào)是指一個函數(shù)的指針,所以如果希望一個處理函數(shù)通知一些事件,可以把另一個函數(shù)(回調(diào))的指針傳遞給處理函數(shù),處理函數(shù)在適當(dāng)?shù)臅r候調(diào)用回調(diào)函數(shù)?;卣{(diào)有兩個主要缺點:首先他們不是類型安全的,從來都不能確定處理函數(shù)使用了正確的參數(shù)來調(diào)用回調(diào);其次回調(diào)和處理函數(shù)是非常強有力地聯(lián)系在一起的,因為處理函數(shù)必須知道要調(diào)用哪個回調(diào)。在Qt中有一種可以替代回調(diào)的技術(shù):使用信號和槽。當(dāng)一個特定事件發(fā)生的時候,一個信號被發(fā)射。Qt的窗口部件有很多預(yù)定義的信號,但是總是可以通過繼承來加入自己定義的信號。槽就是一個可以被調(diào)用處理特定信號的函數(shù)。Qt的窗口部件有很多預(yù)定義的槽,通常也可以加入自己的槽,這樣就可以處理感興趣的信號了。信號—槽機制是類型安全的:一個信號的簽名必須與它的接收槽的簽名相匹配。實際上一個槽的簽名可以比它接收的信號的簽名少,因為它可以忽略額外的簽名。因為簽名是一致的,編譯器就可以幫助檢測類型是否匹配。信號和槽是寬松地聯(lián)系在一起的:一個發(fā)射信號的類不用知道哪個槽要接收這個信號。Qt的信號和槽的機制可以保證如果把一個信號和一個槽連接起來,槽會在正確的時間使用信號的參數(shù)而被調(diào)用。信號和槽可以使用任何數(shù)量、任何類型的參數(shù)。它們是完全類型安全的,不會再有回調(diào)核心轉(zhuǎn)儲。從QObject類或者它的一個子類(比如QWidget類)繼承的所有類都可以包含信號槽。當(dāng)對象的狀態(tài)發(fā)生改變的時候,信號被發(fā)送給其它對象,從而實現(xiàn)了該對象與其它對象的通信。對象在發(fā)射信號時,無須知道有沒有槽接收它所發(fā)射的信號,而槽是正常的成員函數(shù),一個槽不知道它是否被任何信號連接,這就是信息封裝,這種封裝確保了對象可以用作一個軟件組件。此外,使用對象時也無須知道這種通訊機制的實現(xiàn)細節(jié)。在信號—槽機制實現(xiàn)的過程中,可以把許多信號和單一槽相連,也可以把一個信號和許多槽相連。把一個信號和另一個信號直接相連也是可以的。(這時,只要第一個信號被發(fā)射時,第二個信號立刻就被發(fā)射)??傮w來看,信號和槽構(gòu)成了一個強有力的組件編程機制。

4.游戲的詳細設(shè)計4.1勞拉方塊游戲功能圖在項目設(shè)計中,項目的詳細設(shè)計環(huán)節(jié)必不可少。一些可能存在的問題在詳細設(shè)計的過程中將會得到糾正。4.1.1游戲運行流程圖游戲開始后,方塊下落,期間我們可以通過方向鍵來調(diào)整方塊的下落姿態(tài),當(dāng)落下的方塊占滿窗口后,游戲?qū)Y(jié)束。圖4-1詳細地描述了此過程。勞拉方塊游戲開始勞拉方塊游戲開始通過方向鍵來調(diào)整方塊下落姿態(tài)通過方向鍵來調(diào)整方塊下落姿態(tài)調(diào)整過后的勞拉方塊落下調(diào)整過后的勞拉方塊落下方塊占滿窗口是否游戲結(jié)束YESYESNO退出游戲退出游戲圖4-1游戲運行流程圖

4.1.2方塊下落得分圖NONOYESLEVEL增加LINESREMOVED增加YESYES是否消除行數(shù)n是否更改方塊姿態(tài)SCORE增加是否暫停方塊落下方塊下落NONOYESLEVEL增加LINESREMOVED增加YESYES是否消除行數(shù)n是否更改方塊姿態(tài)SCORE增加是否暫停方塊落下方塊下落 圖4-2方塊下落得分流程4.1.3游戲系統(tǒng)流程結(jié)構(gòu)設(shè)計勞拉方塊游戲中,我們將事先設(shè)計好的產(chǎn)生方塊的模塊稱作圖形工場,而和玩家交互的部分簡單地歸納為處理按鍵事件和處理邏輯部分,而游戲面板部分負責(zé)顯示。這三部分通過不用的方式進行交互。圖4-3和圖4-4詳細地描述了此過程。圖4-3游戲系統(tǒng)流程結(jié)構(gòu)設(shè)計圖圖4-4系統(tǒng)數(shù)據(jù)流圖4.2圖形實體類TetrixPiece實現(xiàn)4.2.1圖形的產(chǎn)生定義一個枚舉類型,表示方塊的七種形狀,通過圖形實體類TetrixPieced文件中的setRandomShape()方法隨機產(chǎn)生一個初值,用于產(chǎn)生圖形的某種狀態(tài),如圖3和圖4中圖例所示:隨機產(chǎn)生一個數(shù)隨機產(chǎn)生一個數(shù)隨機數(shù)Z字形S字形直線型T字形正方形L字形反L型4-5圖形的隨機產(chǎn)生每個形狀由4個小方塊組成,這里每行的四個坐標(biāo)即4個小方塊的坐標(biāo),其中橫向為X,縱向為Y,上圖分別為Z字形、S字形、直線型、T字形、正方形、L字形和反L字形,各個圖形的坐標(biāo)依次如下:圖4-6色塊的存儲數(shù)組4.2.2圖形的旋轉(zhuǎn)圖形的旋轉(zhuǎn)是通過繪制4個方向的方塊,在不同旋轉(zhuǎn)角度顯示不同方向的方塊來實現(xiàn)的。定義一個函數(shù)rotatedLeft()const,當(dāng)每次響應(yīng)鍵盤向上的方向鍵時,方塊旋轉(zhuǎn)90度,同時畫布刷新一次,這樣,方塊的變形就實現(xiàn)了。4.3游戲內(nèi)容的實現(xiàn)4.3.1關(guān)于存儲勞拉方塊的關(guān)鍵部分,一定程度上是基于對存儲結(jié)構(gòu)的理解。游戲中,每一塊落下的方塊都由四個小色塊組成,這四個小色塊存儲在一個數(shù)組的四個元素中[6]。我們在TetrixPiece類下setShape(TetrixShapeshape)函數(shù)中創(chuàng)建這個數(shù)組,即staticconstintcoordsTable[8][4][2],該三維數(shù)組中,第一維表示類型,第二維表示x坐標(biāo),最后一維表示y坐標(biāo),這樣我們就能用坐標(biāo)的方式描述出勞拉方塊中的七種不同形狀的方塊。然后通過下文中的函數(shù)調(diào)用這個數(shù)組中的方塊。4.3.2關(guān)于七種色塊的調(diào)用要在前一塊色塊已經(jīng)完成落下的情況下,怎樣隨機生成不同的色塊,這也是游戲設(shè)計中的一個重要部分。這時,我們需要在框架類board中添加一個計時器事件[7],這是下一步的關(guān)鍵。計算機此時通過setRandomShape()來產(chǎn)生不同類型的七種方塊,而在timerEvent()中規(guī)定了一些功能,比如WaitingAfterLine()來有效的控制方塊的產(chǎn)生時機。并且用Timer控件,每隔一段時間方塊的y坐標(biāo)+1,并檢測下是否有可以消除的方塊然后根據(jù)計算機時鐘控制色塊在一定的時間不停的產(chǎn)生。4.3.3關(guān)于色塊的變形色塊變形,這是勞拉方塊游戲的一個玩點。這個在游戲設(shè)計之初很難被實現(xiàn)。因為思路和語法問題,修正中也遇到不少問題,出現(xiàn)如下圖的情況:圖4-7變形模塊修正過程中曾經(jīng)出現(xiàn)的問題首先,這個功能是通過對色塊數(shù)組坐標(biāo)的修正來實現(xiàn)的,當(dāng)我們按下←鍵時,通過event->key()接受到信號并對色塊的X坐標(biāo)進行-1操作,Y值不變?!I同樣的原理,Y不變,X+1操作。向上和向下鍵通過rotatedLeft()和rotatedRight()分別實現(xiàn)色塊的向左和向右旋轉(zhuǎn)。D鍵通過oneLineDown()實現(xiàn)了方塊的加速下落,空格鍵則通過dropDown()實現(xiàn)方塊的瞬間落下,同時,也加入了誤操規(guī)避,通過QFrame::keyPressEvent(event)[8]進行歸納,不進行任何操作。當(dāng)然,在方塊變形的過程中,為了防止在游戲框邊界[9]變形引起錯誤,加入了變形范圍。4.3.4關(guān)于方塊下落功能:判斷圖形能否向下移動,顯示下移后的界面,或者游戲結(jié)束。實現(xiàn):先向下移動一步,此時并不在界面上顯示下移后的界面,判斷是否到底,若到底則消行記錄分數(shù)、出現(xiàn)下一個圖形;判斷是否是否一開始就與其它圖形重合,若是則游戲結(jié)束;經(jīng)過以上判斷,此時方可顯示一下一步后的界面,并進入下一次計時。4.3.5關(guān)于滿行及消行判斷功能:判斷是否有已滿行,然后把該行消去。實現(xiàn):游戲在方塊下移到底后,利用循環(huán)判斷有幾行已滿,并對已滿行進行清零和進行加分操作,同時更新窗口,從而實現(xiàn)消行的效果。4.3.6關(guān)于繪制游戲區(qū)域及方塊通過調(diào)用QPainter的drawLine的方法繪制游戲網(wǎng)格,調(diào)用QPainter和drawRect繪制方塊背景和邊框。4.3.7關(guān)于鍵盤事件響應(yīng)勞拉方塊是通過上下左右移動來控制游戲的運行,那么是具體如何實現(xiàn)的呢?這就需要用到鍵盤的按下事件,通過響應(yīng)鍵盤的按下事件來實現(xiàn)。本游戲設(shè)計的是用上下左右方向鍵鍵來控制游戲的操作,其中左右方向鍵控制方塊向左向右移,向上和向下鍵控制方塊的形狀,SPACE鍵則方塊直接下墜,D鍵方塊加速下落。鍵盤響應(yīng)事件功能圖如圖6所示:判斷按鍵判斷按鍵判斷可否變形,圖形變化調(diào)用函數(shù)判斷可否移動??梢詣t移動判斷可否移動。可以則移動判斷可否移動??梢詣t默認下移一步,否則下到底如不是這4個按鍵,則接收其他按鍵。圖4-8鍵盤事件功能圖具體代碼實現(xiàn):通過重新實現(xiàn)虛函數(shù)QWidget::keyPressEvent來響應(yīng)相應(yīng)的鍵盤按鍵事件。4.4游戲主窗體的實現(xiàn)游戲主窗體是整個游戲的顯示部分,主要用于放置繪制好的游戲區(qū)域,顯示游戲玩家的得分情況、關(guān)卡和其它基本信息。游戲區(qū)域的寬分成10等分,高分成22等分,也就是說每行有10小矩形,總共有22行(BoardWidth=10,BoardHeight=22)。左邊是LCD的顯示部分,LCD的顯示最大為五位數(shù)。分為得分(scoreLcd)、等級(levelLcd)、消行(linesLcd)。另外,主窗體還設(shè)計了游戲的暫停按鈕,方便游戲者的操作。游戲的設(shè)計在Qt中整個工程下完成。

5.游戲主要功能選項的實現(xiàn)與檢驗5.1主要功能的驗證(1)計分功能(SCORE)該部分是用來統(tǒng)計游戲玩家的得分:自由下落增加1分score+=dropHeight+1;每消去n行,多增加10nscore+=10*numFullLines;(2)暫停功能(PAUSE)通過PAUSE鍵來控制游戲的暫停。quitButton->setFocusPolicy(Qt::NoFocus);pauseButton=newQPushButton(tr("&Pause"));//暫停按鈕(3)消行數(shù)功能(LINESREMOVED)當(dāng)方塊落下的時候,剛好將一行或n行填滿,則消去n行if(numFullLines>0){numLinesRemoved+=numFullLines;/*LCD數(shù)字顯示[11]消除行數(shù)等于滿行數(shù)*/(4)游戲等級功能(LEVEL)該類功能是用于統(tǒng)計游戲者所能達到的等級數(shù)/*聲明信號*/signals:voidscoreChanged(intscore);//得分該表觸發(fā)該信號voidlevelChanged(intlevel);//級別改變觸發(fā)該信號if(numPiecesDropped%5==0){++level;//每當(dāng)分數(shù)達到了5的某個倍數(shù)時,level增加1(5)游戲退出功能(QUIT)當(dāng)按下QUIT鍵時,游戲可視化窗口[12]關(guān)閉,退出勞拉方塊游戲startButton->setFocusPolicy(Qt::NoFocus);quitButton=newQPushButton(tr("&Quit"));//退出按鈕5.2游戲快捷鍵簡簡介(1)方向鍵(4個方向鍵)switch(event->key()){//左鍵按下,X左移,Y不變caseQt::Key_Left:tryMove(curPiece,curX-1,curY); break;caseQt::Key_Right://右鍵按下,X右移,Y不變tryMove(curPiece,curX+1,curY); break;caseQt::Key_Down://向下鍵按下,X,Y交換tryMove(curPiece.rotatedRight(),curX,curY); break;caseQt::Key_Up://向上鍵按下,X,Y交換tryMove(curPiece.rotatedLeft(),curX,curY); break;(2)加速下落鍵(D) caseQt::Key_D://按下D,加速下落 oneLineDown(); break;(3)立即落下鍵(空格鍵) caseQt::Key_Space://按下空格鍵,方塊直接落下 dropDown(); break;5.3調(diào)試程序打開QT,如圖5-1:圖5-1QT主界面點擊“openproject”選項,在“打開文件”窗口中選擇想要打開的文件,如圖5-2:圖5-2打開已存在的項目打開文件后,點擊“Debug”按鈕,對項目進行編譯,如圖5-3:圖5-3游戲編譯成功5.4加載成功,觀察效果游戲編譯成功,點擊綠色箭頭按鈕,程序?qū)⒈痪幾g運行,運行結(jié)果如圖5-4和5-5所示:圖5-4游戲開始界面圖5-5游戲運行界面點擊面板上的“Pause”后,游戲?qū)⑦M入暫停狀態(tài),如圖5-6所示:圖5-6游戲暫停界面游戲運行一段時間后,游戲的等級和分數(shù)均獲得了提升,能夠正常運行,如圖5-7:圖5-7游戲運行一段時間后的截圖5.5代碼詳解5.5.1main.cpp該部分為程序的主入口,即main函數(shù),從代碼中可以看出,程序的運行流程為先定義圖形用戶界面類,調(diào)用庫函數(shù)和創(chuàng)建頭文件,自定TetrixWindow類的對象并以時間為隨機參數(shù)變量改變方塊下落形狀,讓窗口在后臺循環(huán)運行,達到顯示窗口的目的#include<QtGui>//定義圖形用戶界面類#include<stdlib.h>//調(diào)用庫函數(shù)#include"tetrixwindow.h"http://調(diào)用創(chuàng)建的頭文件intmain(intargc,char*argv[])//c++程序入口,(argc是命令行參數(shù)的數(shù)目,*argv[]是指向參數(shù)的各個指針?biāo)鶚?gòu)成的數(shù)組){QApplicationapp(argc,argv);//,Qt程序入口TetrixWindowwindow;//自定TetrixWindow類的對象,其實就是QWidget類的子類window.show();//顯示qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));//以時間為隨機參數(shù)變量改變方塊下落形狀returnapp.exec();//讓窗口在后臺循環(huán)運行,達到顯示窗口的目的} 5.5.2tetrixboard.cpp該部分為代碼的“黑盒”部分,所有關(guān)乎程序的邏輯處理部分全部集合在其中,如游戲的行消除、計分、等級等功能,都是在這個文件中進行定義的。值得一說的是,該部分還用到了QT中的一些自帶的框架風(fēng)格及其相應(yīng)的設(shè)置功能,這些功能使得游戲?qū)崿F(xiàn)的過程變得容易。#include<QtGui>//定義圖形用戶界面類#include"tetrixboard.h"TetrixBoard::TetrixBoard(QWidget*parent):QFrame(parent){/*設(shè)置框架風(fēng)格為Panel|Sunken,API有圖可參照*/setFrameStyle(QFrame::Panel|QFrame::Sunken);setFocusPolicy(Qt::StrongFocus);/*設(shè)置框架焦點策略*/isStarted=false;/*初始化開始和暫停均為false*/isPaused=false;clearBoard();/*清空界面*/nextPiece.setRandomShape();/*指名下一個圖形隨機生成*/}/*設(shè)置nextPieceLabel的值為輸入值*/voidTetrixBoard::setNextPieceLabel(QLabel*label){nextPieceLabel=label;}QSizeTetrixBoard::sizeHint()const/*顯示尺寸*/{returnQSize(BoardWidth*15+frameWidth()*2,BoardHeight*15+frameWidth()*2);}QSizeTetrixBoard::minimumSizeHint()const{returnQSize(BoardWidth*5+frameWidth()*2,BoardHeight*5+frameWidth()*2);}voidTetrixBoard::start(){if(isPaused)return;isStarted=true;isWaitingAfterLine=false;numLinesRemoved=0;numPiecesDropped=0;score=0;level=1;clearBoard();//清屏/*emit關(guān)鍵字表示發(fā)送信號*/emitlinesRemovedChanged(numLinesRemoved);emitscoreChanged(score);emitlevelChanged(level);newPiece();/*開始計時器,該框架類會接受到一個計時器事件*/timer.start(timeoutTime(),this);}/*暫停*/voidTetrixBoard::pause(){/*沒有開始,即返回*/if(!isStarted)return;isPaused=!isPaused;/*暫停則停止計時*/if(isPaused){timer.stop();}else{/*沒有停止,且是正在進行,則計時*/timer.start(timeoutTime(),this);}/*更新控件顯示*/update();}voidTetrixBoard::paintEvent(QPaintEvent*event){QFrame::paintEvent(event);/*在這個框架上畫圖*/QPainterpainter(this);QRectrect=contentsRect();/*在rect中間顯示文本信息*/if(isPaused){painter.drawText(rect,Qt::AlignCenter,tr("Pause"));return;}intboardTop=rect.bottom()-BoardHeight*squareHeight();for(inti=0;i<BoardHeight;++i){for(intj=0;j<BoardWidth;++j){TetrixShapeshape=shapeAt(j,BoardHeight-i-1);if(shape!=NoShape)drawSquare(painter,rect.left()+j*squareWidth(),boardTop+i*squareHeight(),shape);}}if(curPiece.shape()!=NoShape){for(inti=0;i<4;++i){intx=curX+curPiece.x(i);inty=curY-curPiece.y(i);drawSquare(painter,rect.left()+x*squareWidth(),boardTop+(BoardHeight-y-1)*squareHeight(),curPiece.shape());}}}voidTetrixBoard::keyPressEvent(QKeyEvent*event){if(!isStarted||isPaused||curPiece.shape()==NoShape){QFrame::keyPressEvent(event);return;}switch(event->key()){//左鍵按下,X左移,Y不變caseQt::Key_Left:tryMove(curPiece,curX-1,curY); break;caseQt::Key_Right://右鍵按下,X右移,Y不變tryMove(curPiece,curX+1,curY); break;caseQt::Key_Down://向下鍵按下,X,Y交換tryMove(curPiece.rotatedRight(),curX,curY); break;caseQt::Key_Up://向上鍵按下,X,Y交換tryMove(curPiece.rotatedLeft(),curX,curY); break;caseQt::Key_Space://按下空格鍵,方塊直接落下 dropDown(); break;caseQt::Key_D://按下D,加速下落 oneLineDown(); break;default://按錯其他鍵,不執(zhí)行錯誤操作QFrame::keyPressEvent(event);}}以上的部分,完整地定義了游戲中的鍵盤事件處理機制以及游戲隨機生成方塊的產(chǎn)生原理,通過以上代碼的處理及相應(yīng),才能對鍵盤發(fā)出的信號做出相應(yīng)的反應(yīng)。接下來的部分是色塊的生成部分,以時間作為隨機變量,隨機產(chǎn)生方塊,每當(dāng)分數(shù)達到了5的某個倍數(shù)時,level增加1。voidTetrixBoard::timerEvent(QTimerEvent*event)//以時間作為隨機變量{if(event->timerId()==timer.timerId()){if(isWaitingAfterLine){isWaitingAfterLine=false; newPiece(); timer.start(timeoutTime(),this);}else{neLineDown();}}else{QFrame::timerEvent(event);}}voidTetrixBoard::clearBoard()//{for(inti=0;i<BoardHeight*BoardWidth;++i)board[i]=NoShape;}voidTetrixBoard::dropDown()//方塊下落{intdropHeight=0;intnewY=curY;while(newY>0){if(!tryMove(curPiece,curX,newY-1))break;--newY;++dropHeight;}pieceDropped(dropHeight);}voidTetrixBoard::oneLineDown()//{if(!tryMove(curPiece,curX,curY-1))pieceDropped(0);}voidTetrixBoard::pieceDropped(intdropHeight)//游戲級數(shù)、分數(shù){for(inti=0;i<4;++i){intx=curX+curPiece.x(i);inty=curY-curPiece.y(i);shapeAt(x,y)=curPiece.shape();}++numPiecesDropped;if(numPiecesDropped%5==0){++level;//每當(dāng)分數(shù)達到了5的某個倍數(shù)時,level增加1timer.start(timeoutTime(),this);emitlevelChanged(level);}score+=dropHeight+1;emitscoreChanged(score);removeFullLines();if(!isWaitingAfterLine)newPiece();}下面的部分是關(guān)于游戲界面中LEVEL的設(shè)定。得分的機制也做了設(shè)定。LCD數(shù)字顯示消除行數(shù)等于滿行數(shù),消除一行增加10分。voidTetrixBoard::removeFullLines(){intnumFullLines=0;for(inti=BoardHeight-1;i>=0;--i){boollineIsFull=true;/*假設(shè)剛開始就滿行*//*每行都沒有障礙物*/for(intj=0;j<BoardWidth;++j){if(shapeAt(j,i)==NoShape){/*則設(shè)置滿行標(biāo)志false*/lineIsFull=false;break;}}if(lineIsFull){/*LCD數(shù)字自加*/++numFullLines;/*j:橫坐標(biāo)k:縱坐標(biāo)*/for(intk=i;k<BoardHeight-1;++k){for(intj=0;j<BoardWidth;++j)/*用上一行的圖形填充滿行的位置*/shapeAt(j,k)=shapeAt(j,k+1); }/*將頂行設(shè)置為空白行*/for(intj=0;j<BoardWidth;++j)shapeAt(j,BoardHeight-1)=NoShape;}}if(numFullLines>0){/*LCD數(shù)字顯示消除行數(shù)等于滿行數(shù)*/numLinesRemoved+=numFullLines;/*消除一行增加十分*/score+=10*numFullLines;/*發(fā)分數(shù)和消行信號*/emitlinesRemovedChanged(numLinesRemoved);emitscoreChanged(score);/*每500ms框架會接收到一個定時器事件*/timer.start(500,this);isWaitingAfterLine=true;/*設(shè)置當(dāng)當(dāng)前的方塊為空白*/curPiece.setShape(NoShape);/*更新控件顯示*/update();}}/*生成新方塊*/voidTetrixBoard::newPiece(){/*將當(dāng)前顯示的方塊設(shè)置為即將顯示的方塊*/curPiece=nextPiece;/*設(shè)置下一個方塊隨機產(chǎn)生*/nextPiece.setRandomShape();/*顯示方塊*/showNextPiece();/*設(shè)置當(dāng)前的橫坐標(biāo)為框架的中心*/curX=BoardWidth/2+1;/*設(shè)置curY為框架頂點+方塊最小高度*/curY=BoardHeight-1+curPiece.minY();if(!tryMove(curPiece,curX,curY)){curPiece.setShape(NoShape);timer.stop();isStarted=false;}}下面的部分是上色部分,色塊的顏色就是由這些決定的。在一個數(shù)組中定義了若干顏色,通過設(shè)置畫筆,然后使用定制顏色來畫圖。voidTetrixBoard::showNextPiece(){if(!nextPieceLabel)return;intdx=nextPiece.maxX()-nextPiece.minX()+1;intdy=nextPiece.maxY()-nextPiece.minY()+1;/*squareWidth:一個正方塊的寬squareHeight:正方塊的高*構(gòu)建一個圖像映射*QPixmap為QPaiterDevice的子類*/QPixmappixmap(dx*squareWidth(),dy*squareHeight());/*構(gòu)建繪畫這個pixmap的painter*/QPainterpainter(&pixmap);/*畫一個小方塊*/painter.fillRect(pixmap.rect(),nextPieceLabel->palette().background());/*畫方塊*/for(inti=0;i<4;++i){intx=nextPiece.x(i)-nextPiece.minX();inty=nextPiece.y(i)-nextPiece.minY();drawSquare(painter,x*squareWidth(),y*squareHeight(),nextPiece.shape());}/*設(shè)置標(biāo)簽的圖片映像*/nextPieceLabel->setPixmap(pixmap);}boolTetrixBoard::tryMove(constTetrixPiece&newPiece,intnewX,intnewY){for(inti=0;i<4;++i){intx=newX+newPiece.x(i);inty=newY-newPiece.y(i);/*設(shè)置邊界*/if(x<0||x>=BoardWidth||y<0||y>=BoardHeight)returnfalse;/*沒有方塊則返回false*/if(shapeAt(x,y)!=NoShape)returnfalse;//循環(huán)}curPiece=newPiece;curX=newX;//賦值新坐標(biāo)curY=newY;/*更新控件*/update();returntrue;//循環(huán)}voidTetrixBoard::drawSquare(QPainter&painter,intx,inty,TetrixShapeshape)//方塊顏色的控制{/*定義顏色,并初始化*/staticconstQRgbcolorTable[8]={0x000000,0xCC6666,0x66CC66,0x6666CC,0xCCCC66,0xCC66CC,0x66CCCC,0xDAAA00};QColorcolor=colorTable[int(shape)];/*使用制定顏色畫圖*/painter.fillRect(x+1,y+1,squareWidth()-2,squareHeight()-2,color);/*設(shè)置畫筆*/painter.setPen(color.light());/*畫直線*/painter.drawLine(x,y+squareHeight()-1,x,y);painter.drawLine(x,y,x+squareWidth()-1,y);painter.setPen(color.dark());painter.drawLine(x+1,y+squareHeight()-1,x+squareWidth()-1,y+squareHeight()-1);painter.drawLine(x+squareWidth()-1,y+squareHeight()-1,x+squareWidth()-1,y+1);}5.3.3tetrixpiece.cpp在picec.cpp文件中,對色塊的存儲和色塊的旋轉(zhuǎn)進行了定義。色塊存儲在一個三維數(shù)組中,第一維表示類型,第二維表示X坐標(biāo),第三維表示Y坐標(biāo)。色塊的旋轉(zhuǎn)也在此文件中進行了詳細的定義。#include<QtCore>#include<stdlib.h>#include"tetrixpiece.h"/*在這7中形式的圖像中隨機的生成一種*/voidTetrixPiece::setRandomShape(){setShape(TetrixShape(qrand()%7+1));}/*設(shè)置樣式為參數(shù)所示樣式*/voidTetrixPiece::setShape(TetrixShapeshape){/*該三維數(shù)組中,第一維表示類型,第二維表示x坐標(biāo),最后一維表示y坐標(biāo)*/staticconstintcoordsTable[8][4][2]={{{0,0},{0,0},{0,0},{0,0}},{{0,-1},{0,0},{-1,0},{-1,1}},{{0,-1},{0,0},{1,0},{1,1}},{{0,-1},{0,0},{0,1},{0,2}},{{-1,0},{0,0},{1,0},{0,1}},{{0,0},{1,0},{0,1},{1,1}},{{-1,-1},{0,-1},{0,0},{0,1}},{{1,-1},{0,-1},{0,0},{0,1}}};for(inti=0;i<4;i++){for(intj=0;j<2;++j)/*coords數(shù)組比保存圖形信息,和平面點坐標(biāo)對應(yīng)*/coords[i][j]=coordsTable[shape][i][j];}pieceShape=shape;}intTetrixPiece::minX()const{intmin=coords[0][0];for(inti=1;i<4;++i)/*qt定義的方法,返回兩個數(shù)中最小的*/min=qMin(min,coords[i][0]);returnmin;}intTetrixPiece::maxX()const{intmax=coords[0][0];for(inti=1;i<4;++i)/*qMax返回兩個值中最大的一個*/max=qMax(max,coords[i][0]);returnmax;}intTetrixPiece::minY()const{intmin=coords[0][1];for(inti=1;i<4;++i)min=qMin(min,coords[i][1]);returnmin;}intTetrixPiece::maxY()const{intmax=coords[0][1];for(inti=1;i<4;++i)max=qMax(max,coords[i][1]);returnmax;}/*向左旋轉(zhuǎn)*/TetrixPieceTetrixPiece::rotatedLeft()const{/*當(dāng)是正方形時,旋轉(zhuǎn)了等于本身*/if(piece

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論