勞拉方塊游戲設計與實現畢業論文設計_第1頁
勞拉方塊游戲設計與實現畢業論文設計_第2頁
勞拉方塊游戲設計與實現畢業論文設計_第3頁
勞拉方塊游戲設計與實現畢業論文設計_第4頁
勞拉方塊游戲設計與實現畢業論文設計_第5頁
已閱讀5頁,還剩61頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

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

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

4.游戲的詳細設計4.1勞拉方塊游戲功能圖在項目設計中,項目的詳細設計環節必不可少。一些可能存在的問題在詳細設計的過程中將會得到糾正。4.1.1游戲運行流程圖游戲開始后,方塊下落,期間我們可以通過方向鍵來調整方塊的下落姿態,當落下的方塊占滿窗口后,游戲將會結束。圖4-1詳細地描述了此過程。勞拉方塊游戲開始勞拉方塊游戲開始通過方向鍵來調整方塊下落姿態通過方向鍵來調整方塊下落姿態調整過后的勞拉方塊落下調整過后的勞拉方塊落下方塊占滿窗口方塊占滿窗口是否游戲結束是否游戲結束YESNOYESNO退出游戲退出游戲圖4-1游戲運行流程圖

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

5.游戲主要功能選項的實現與檢驗5.1主要功能的驗證(1)計分功能(SCORE)該部分是用來統計游戲玩家的得分:自由下落增加1分score+=dropHeight+1;每消去n行,多增加10nscore+=10*numFullLines;(2)暫停功能(PAUSE)通過PAUSE鍵來控制游戲的暫停。quitButton->setFocusPolicy(Qt::NoFocus);pauseButton=newQPushButton(tr("&Pause"));//暫停按鈕(3)消行數功能(LINESREMOVED)當方塊落下的時候,剛好將一行或n行填滿,則消去n行if(numFullLines>0){numLinesRemoved+=numFullLines;/*LCD數字顯示[11]消除行數等于滿行數*/(4)游戲等級功能(LEVEL)該類功能是用于統計游戲者所能達到的等級數/*聲明信號*/signals:voidscoreChanged(intscore);//得分該表觸發該信號voidlevelChanged(intlevel);//級別改變觸發該信號if(numPiecesDropped%5==0){++level;//每當分數達到了5的某個倍數時,level增加1(5)游戲退出功能(QUIT)當按下QUIT鍵時,游戲可視化窗口[12]關閉,退出勞拉方塊游戲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調試程序打開QT,如圖5-1:圖5-1QT主界面點擊“openproject”選項,在“打開文件”窗口中選擇想要打開的文件,如圖5-2:圖5-2打開已存在的項目打開文件后,點擊“Debug”按鈕,對項目進行編譯,如圖5-3:圖5-3游戲編譯成功5.4加載成功,觀察效果游戲編譯成功,點擊綠色箭頭按鈕,程序將被編譯運行,運行結果如圖5-4和5-5所示:圖5-4游戲開始界面圖5-5游戲運行界面點擊面板上的“Pause”后,游戲將進入暫停狀態,如圖5-6所示:圖5-6游戲暫停界面游戲運行一段時間后,游戲的等級和分數均獲得了提升,能夠正常運行,如圖5-7:圖5-7游戲運行一段時間后的截圖5.5代碼詳解5.5.1main.cpp該部分為程序的主入口,即main函數,從代碼中可以看出,程序的運行流程為先定義圖形用戶界面類,調用庫函數和創建頭文件,自定TetrixWindow類的對象并以時間為隨機參數變量改變方塊下落形狀,讓窗口在后臺循環運行,達到顯示窗口的目的#include<QtGui>//定義圖形用戶界面類#include<stdlib.h>//調用庫函數#include"tetrixwindow.h"http://調用創建的頭文件intmain(intargc,char*argv[])//c++程序入口,(argc是命令行參數的數目,*argv[]是指向參數的各個指針所構成的數組){QApplicationapp(argc,argv);//,Qt程序入口TetrixWindowwindow;//自定TetrixWindow類的對象,其實就是QWidget類的子類window.show();//顯示qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));//以時間為隨機參數變量改變方塊下落形狀returnapp.exec();//讓窗口在后臺循環運行,達到顯示窗口的目的} 5.5.2tetrixboard.cpp該部分為代碼的“黑盒”部分,所有關乎程序的邏輯處理部分全部集合在其中,如游戲的行消除、計分、等級等功能,都是在這個文件中進行定義的。值得一說的是,該部分還用到了QT中的一些自帶的框架風格及其相應的設置功能,這些功能使得游戲實現的過程變得容易。#include<QtGui>//定義圖形用戶界面類#include"tetrixboard.h"TetrixBoard::TetrixBoard(QWidget*parent):QFrame(parent){/*設置框架風格為Panel|Sunken,API有圖可參照*/setFrameStyle(QFrame::Panel|QFrame::Sunken);setFocusPolicy(Qt::StrongFocus);/*設置框架焦點策略*/isStarted=false;/*初始化開始和暫停均為false*/isPaused=false;clearBoard();/*清空界面*/nextPiece.setRandomShape();/*指名下一個圖形隨機生成*/}/*設置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關鍵字表示發送信號*/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://按錯其他鍵,不執行錯誤操作QFrame::keyPressEvent(event);}}以上的部分,完整地定義了游戲中的鍵盤事件處理機制以及游戲隨機生成方塊的產生原理,通過以上代碼的處理及相應,才能對鍵盤發出的信號做出相應的反應。接下來的部分是色塊的生成部分,以時間作為隨機變量,隨機產生方塊,每當分數達到了5的某個倍數時,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)//游戲級數、分數{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;//每當分數達到了5的某個倍數時,level增加1timer.start(timeoutTime(),this);emitlevelChanged(level);}score+=dropHeight+1;emitscoreChanged(score);removeFullLines();if(!isWaitingAfterLine)newPiece();}下面的部分是關于游戲界面中LEVEL的設定。得分的機制也做了設定。LCD數字顯示消除行數等于滿行數,消除一行增加10分。voidTetrixBoard::removeFullLines(){intnumFullLines=0;for(inti=BoardHeight-1;i>=0;--i){boollineIsFull=true;/*假設剛開始就滿行*//*每行都沒有障礙物*/for(intj=0;j<BoardWidth;++j){if(shapeAt(j,i)==NoShape){/*則設置滿行標志false*/lineIsFull=false;break;}}if(lineIsFull){/*LCD數字自加*/++numFullLines;/*j:橫坐標k:縱坐標*/for(intk=i;k<BoardHeight-1;++k){for(intj=0;j<BoardWidth;++j)/*用上一行的圖形填充滿行的位置*/shapeAt(j,k)=shapeAt(j,k+1); }/*將頂行設置為空白行*/for(intj=0;j<BoardWidth;++j)shapeAt(j,BoardHeight-1)=NoShape;}}if(numFullLines>0){/*LCD數字顯示消除行數等于滿行數*/numLinesRemoved+=numFullLines;/*消除一行增加十分*/score+=10*numFullLines;/*發分數和消行信號*/emitlinesRemovedChanged(numLinesRemoved);emitscoreChanged(score);/*每500ms框架會接收到一個定時器事件*/timer.start(500,this);isWaitingAfterLine=true;/*設置當當前的方塊為空白*/curPiece.setShape(NoShape);/*更新控件顯示*/update();}}/*生成新方塊*/voidTetrixBoard::newPiece(){/*將當前顯示的方塊設置為即將顯示的方塊*/curPiece=nextPiece;/*設置下一個方塊隨機產生*/nextPiece.setRandomShape();/*顯示方塊*/showNextPiece();/*設置當前的橫坐標為框架的中心*/curX=BoardWidth/2+1;/*設置curY為框架頂點+方塊最小高度*/curY=BoardHeight-1+curPiece.minY();if(!tryMove(curPiece,curX,curY)){curPiece.setShape(NoShape);timer.stop();isStarted=false;}}下面的部分是上色部分,色塊的顏色就是由這些決定的。在一個數組中定義了若干顏色,通過設置畫筆,然后使用定制顏色來畫圖。voidTetrixBoard::showNextPiece(){if(!nextPieceLabel)return;intdx=nextPiece.maxX()-nextPiece.minX()+1;intdy=nextPiece.maxY()-nextPiece.minY()+1;/*squareWidth:一個正方塊的寬squareHeight:正方塊的高*構建一個圖像映射*QPixmap為QPaiterDevice的子類*/QPixmappixmap(dx*squareWidth(),dy*squareHeight());/*構建繪畫這個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());}/*設置標簽的圖片映像*/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);/*設置邊界*/if(x<0||x>=BoardWidth||y<0||y>=BoardHeight)returnfalse;/*沒有方塊則返回false*/if(shapeAt(x,y)!=NoShape)returnfalse;//循環}curPiece=newPiece;curX=newX;//賦值新坐標curY=newY;/*更新控件*/update();returntrue;//循環}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);/*設置畫筆*/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文件中,對色塊的存儲和色塊的旋轉進行了定義。色塊存儲在一個三維數組中,第一維表示類型,第二維表示X坐標,第三維表示Y坐標。色塊的旋轉也在此文件中進行了詳細的定義。#include<QtCore>#include<stdlib.h>#include"tetrixpiece.h"/*在這7中形式的圖像中隨機的生成一種*/voidTetrixPiece::setRandomShape(){setShape(TetrixShape(qrand()%7+1));}/*設置樣式為參數所示樣式*/voidTetrixPiece::setShape(TetrixShapeshape){/*該三維數組中,第一維表示類型,第二維表示x坐標,最后一維表示y坐標*/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數組比保存圖形信息,和平面點坐標對應*/coords[i][j]=coordsTable[shape][i][j];}pieceShape=shape;}intTetrixPiece::minX()const{intmin=coords[0][0];for(inti=1;i<4;++i)/*qt定義的方法,返回兩個數中最小的*/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;}/*向左旋轉*/TetrixPieceTetrixPiece::rotatedLeft()const{/*當是正方形時,旋轉了等于本身*/i

溫馨提示

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

評論

0/150

提交評論