基于Qt的連連看游戲的設計_第1頁
基于Qt的連連看游戲的設計_第2頁
基于Qt的連連看游戲的設計_第3頁
基于Qt的連連看游戲的設計_第4頁
基于Qt的連連看游戲的設計_第5頁
已閱讀5頁,還剩41頁未讀, 繼續(xù)免費閱讀

下載本文檔

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

文檔簡介

摘要在現今電子信息高速開展的時代,電子游戲已然成為群眾最受歡送的娛樂消遣方式,經典的連連看是個老少皆宜的小游戲,它實現由各式各樣的成對圖片組成,然后存儲在一個二維的數組中,計算機隨機產生各種不同類型的圖片,根據計算機時鐘控制它在一定的時間內隨機產生,用戶可根據鼠標和回車鍵點擊圖片、假設兩次點擊的圖片一樣,那么消掉圖片。本文用QT來設計與實現簡單的連連看游戲的根本功能,玩家可以在游戲區(qū)域中通過鍵盤控制來選取相同的兩個物件,采用特定的消除規(guī)那么對它們進行消除的操作,當游戲區(qū)域中的所有方塊對都被消除后玩家即可勝利。文章對該游戲的算法以及游戲圖案的繪制進行詳細的介紹。實現起來較簡單,同時也比擬實用。關鍵詞:Qt;游戲設計;算法;數組;信號與槽ABSTRACTInthecurrenteraofrapiddevelopmentofelectronicinformation,electronicgamehasbecomethemostpopularentertainmentpopularpastime,classicRussiansquareisaenjoyedbyyoungandoldlittlegame,itachievedbyfoursquareofcolorpiece,andthenstoredinatwodimensionalarray,computerrandomgenerationsevendifferenttypesofsquare,accordingtothecomputerclockcontrolitincertaintimekeepproduced,theusercanaccordingtothekeyboardfourthedirectionkeycontrolblockturns,movesleft,movetotheright,movedownoperationandtheprogramaccordingtothesevensquarearestackedintoadifferentmodel.AndLaurasquareisbasedonsquareinRussia,givetheRussiansquarenewchallengepattern,itsinspirationfromthenetworkanotherkindofpopularvideogames-tombraider.Playerstotheidentityoftheadventurersintothegame,playersneedonlytoacertainscore,canchallengehigherdifficultylevelsofthegame,ofcourse,ifyouaregood,youwillhavethechancetoopenthemysterioushideorgans,themorefullofimaginationandstimulationofplaywillwaitforyoutakeyourchallenge.Keywords:Qt;Gamedesign;Algorithm;Array;Signalsandslots.目錄TOC\o"1-2"\h\z\u摘要IABSTRACTII第一章緒論21.1游戲背景21.2游戲概述2第二章方案論證42.1選擇開發(fā)語言4第三章需求分析113.1軟硬件需求113.2游戲功能需求11第四章游戲總體設計134.1總體設計134.2游戲開始模塊設計144.3游戲設置模塊設計144.4游戲核心模塊的設計15第五章具體實現165.1模型層設計165.2視圖層設計175.3其它相關技術的實現18第六章游戲測試196.1按鍵事件的功能測試206.2圖片消失測試206.3聲音和顯示測試206.4測試結果分析20總結21致謝22參考文獻23附錄源代碼24第一章緒論1.1游戲背景說到連連看,就不得不從經典小游戲說起,連連看是一款古老的風行全球的經典游戲,它最早出現在PC機上,我國的用戶都是通過紅白機了解、喜歡上它的,相信有很多人到現在還是對它念念不忘的。無可爭議,《連連看》是有史以來最偉大的游戲之一。在曾經發(fā)布過的所有游戲中,《連連看》還被認為是僅有的一個能夠真正吸引廣泛人群的作品,曾今造成的轟動與經濟價值可以說是游戲史上的一件大事,它看似簡單卻變化無窮,令人著迷,相信大多數玩家都還記得為它癡迷得茶飯不思的那個連連看時代。但是隨著網絡信息的高速開展,連連看也要跟隨時代的開展,以滿足群眾的需要。到如今,網絡上已經出現了各種不同版本的連連看,它賦予玩家冒險家的角色,不斷挑戰(zhàn)你的想象,其全新的設計,創(chuàng)新的玩法,為經典的連連看蒙上了一層更加神秘的色彩。1.2游戲概述游戲簡介游戲“連連看〞顧名思義就是找出相關聯的東西,這個連連看在網上根本是用在小游戲中,就是找出相同的兩樣東西,在一定的規(guī)那么之內可以做為相關聯處理?!斑B連看〞的開展經歷了從桌面游戲、在線游戲、社交游戲三個過程。游戲“連連看〞是源自臺灣的桌面小游戲,自從流入大陸以來風行一時,也吸引眾多程序員開發(fā)出多種版本的“連連看〞。這其中,顧方編寫的“阿達連連看〞以其精良的制作廣受好評,這也成為顧方“阿達系列軟件〞的核心產品。并于2004年,取得了國家版權局的計算機軟件著作權登記證書。隨著Flash應用的流行,網上出現了多種在線Flash版本“連連看〞。如“水晶連連看〞,“果蔬連連看〞等,流行的“水晶連連看〞以華美界面吸引了一大批的女性玩家。2023年,隨著社交網絡的普及和開放平臺的興起,“連連看〞被引入了社交網絡。“連連看〞與個人空間相結合,被快速的傳播,成為一款熱門的社交游戲,其中以開發(fā)者Jonevey在Manyou開放平臺上推出的“寵物連連看〞最為流行。游戲功能本次設計連連看主要是在原連連看對戰(zhàn)的根底上設計挑戰(zhàn)模式,具體的功能如下所述:游戲運行界面簡單美觀,操作簡單,運行穩(wěn)定;能夠根據不同的等級模式播放不同的游戲背景音樂,包括操作方向鍵、消行時的聲音,音量由玩家操作控制;設計不同的游戲難度,當玩家到達一定的積分,可以進入相關難度的等級;玩家可直接操作界面上的相關按鈕來控制游戲的開始、暫停、設置、退出等功能。第二章方案論證2.1選擇開發(fā)語言根據自己以前所學的關于C語言、C++、Java、以及Qt的相關知識,并通過網上查找相關資料,了解到C、C++、VB、Delphi、C#、Java等均可以現勞拉方塊游戲的設計。下面簡單介紹下VB、C++、Java、Qt各自的特點:VB的特點全稱VisualBasic,它是以Basic語言作為其根本語言的一種可視化編程工具。在中國乃至全世界都能看到它的身影,它曾是在中國最為流行的編程工具,到現在還占據著非常重要的地位,對于它的好壞大家都有一定的了解,VB作為一種較早出現的開發(fā)程序以其容易學習,開發(fā)效率較高,具有完善的幫助系統等優(yōu)點曾影響了好幾代編程人員,但是由于VB不具備跨平臺這個特性,從而也決定了VB在未來的軟件開發(fā)中將會逐漸地退出其歷史舞臺;它對組件技術的支持是基于COM和ActiveX,對于組件技術不斷完善開展的今天,它也顯出了它的落后性;同時VB在進行系統底層開發(fā)的時候也是相對復雜的,調用API函數需聲明,調用不方便,不能進行DDK編程,不可能深入Ring0編程,不能嵌套匯編;而且面向對象的特性差;網絡功能和數據庫功能也沒有非常突出的表現,綜上所述,VB作為一種可視化的開發(fā)工具由于其本身的局限性,導致了它在未來軟件開發(fā)中逐步被其他工具所代替。C++的特點C/C++的哲學就不一樣了,同一份程序代碼,只要在該平臺重新Compile成該平臺的執(zhí)行檔,就能在該平臺執(zhí)行,假設文字模式下的程序,確實可以跨平臺,程序完全不需修改,但GUI盛行以后,由于各GUI的Library都不一樣且沒有標準,所以GUI程序并沒方法跨平臺Compile,因為各平臺都有專屬的Library。但是C/C++優(yōu)勢就是執(zhí)行速度快,假設能解決GUILibrary的問題,那么跨平臺即可解決。除了GUILibrary需要統一外,還得看該Library設計的好不好才行,LinuxGUI我沒寫過就不說了,假設在Windows平臺,Borland的C++Builder使用Delphi的VCLLibrary,Microsoft的VisualC++可以用MFC和.NETFramework,首先來看Borland的C++Builder,它使用標準的ANSIC++語言開發(fā),利用VCL寫出來的程序也算蠻漂亮的,執(zhí)行速度很快,比擬麻煩的是C++Builder當初為了縮短上市時間,并沒有設計自己的Library,而是藉用Delphi的Library,導致C++Builder在Compile時,是先用Delphi的Compiler將VCLcompile成objectfile后,再用C++Builder將你寫的C++程序compile成objectfile,最后再用Linker將所有的objectfilelink起來,由于這都是IDE在做,對程序設計師似乎影響不大,但VCL由于是Delphi的Library,所以假設想深入研究VCL的sourcecode時,那么必須學Delphi的Pascal才行,否那么看不懂VCLsourcecode,這也是很多人對C++Builder卻步的原因。再來看Microsoft的VisualC++,MFC用的是完整的ANSIC++語言,所以語言局部不是問題,但假設你看過用MFC寫的程序,你一定會驚訝為什么這么復雜,程序代碼非常冗長不好看,且MFC是有名的難學,假設VisualC++搭配.NETFramrwork,那么無法使用ANSIC++,得用其.NET平臺版本的C++/CLI,相信這點很多人就有意見了,不過.NETFramework由于設計的不錯,所以寫出來的程序相當精簡漂亮,感覺和C++Builder差不多,不過無論是C++Builder或VisualC++開發(fā)的GUI,所開發(fā)出來的程序都無法跨平臺,當然也無法跨平臺Compile。2.1.3JavaJava具有平安性、可移植性、多線程機制以及跨平臺的良好特性,但是由于本人對Java語言不是很熟悉,所以此方案也予以否決。2.1.4Qt的Qt擁有一個單一的Library,讓你開發(fā)各種不同平臺的程序,目前支持Windows、Linux、Mac、UNIX、EmbeddedLinux,講白話點,就是它提供了一個Library讓你開發(fā)GUI程序,寫好之后,只要在各平臺重新Compile后,就可以在各平臺執(zhí)行,而且使用完整的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成各平臺的原生程序即可,這樣即可保證其執(zhí)行速度,不用再靠VirtualMachine。但很可惜這個理想,這么多年來都沒人可以做出來,或許是我孤陋寡聞吧。Qt無疑是GUI終極解決方案,有強力的ANSIC/C++語言背書,又有單一的GUILibrary,且精簡漂亮,又能Compile成各平臺的原生執(zhí)行檔,幾乎是最完美的解決方案了。2.1.5經過以上比擬好,考慮到Qt的眾多良好特性,尤其是其跨平臺性,加上自己最近正在學習Qt,為了能夠更進一步掌握Qt編程,因此決定使用Qt開發(fā)連連看游戲。2.2Qt關鍵技術的介紹Qt特點的具體介紹1.可移植性Qt是一個跨平臺GUI工具箱,不僅適用于Unix,它同樣適用于MSWindows。如果開發(fā)平臺是MSWindows,可能選擇的GUI工具箱為MicrosoftFoundationClasses〔MFC〕,這樣就會失去眾多的Unix用戶。相反,如果開發(fā)平臺是Unix,可能選擇其它工具箱,如Motif等,同樣會失去眾多的Windows用戶。如果選擇的GUI工具箱為Qt,那么只要在不同的平臺上簡單的編譯源代碼,就可以使原程序在不同的平臺上運行,從而解決喪失用戶的問題。Qt把在處理不同窗口系統時的潛在問題隱藏了起來。為使Qt使用方便,Qt包含了一系列類,這些類使開發(fā)人員防止了在文件處理、時間處理等方面存在的依賴操作系統方面的細節(jié)。2.國際化所謂國際化,通俗的講,就是指在某國開發(fā)的軟件可以方便的被其它國家的人使用。Qt為本地化應用提供完全的支持,所有用戶界面文本都可以基于消息翻譯表被翻譯成各國語言。另外,Qt完全支持雙字節(jié)16bit國際字符標準。利用Qt開發(fā)跨平臺的國際化軟件是一個方便、增量的過程。在開發(fā)過程中,利用Qt的linguist界面工具就能方便的將開發(fā)的軟件翻譯成各國語言,從而實現軟件的國際化。3.面向對象Qt是一個C++工具箱,它由幾百個C++類構成。在程序設計中可以使用這些類,如果Qt沒有提供真正適合需求的組件,那么可以方便的修改現有的組件或者重新編寫組件。Qt具有模塊設計和注重軟件構件或元素的可重用性的特點。一個組件不需要知道它的內容,而通過Qt特有的signal和slot機制與外界通信、交流。使用Qt進行應用程序的開發(fā),可以充分利用其面向對象和模塊化的特征,從繁瑣的編程中解脫出來,專注于應用程序本身的實現。4.可用戶化的外觀Qt支持主題,所以基于Qt的應用軟件能在Motif外觀、Windows外觀,以及另一些用戶化的外觀之間互換,甚至改變運行時間。這些應用程序不管是在XWindows下還是在MicrosoftWindows下都可以獨立操作、運行。5.獨有的SignalSlot機制SignalSlot機制是Qt最重要的特征。在MSWindows中,程序通過消息機制和事件循環(huán)來實現圖形對象行為的觸發(fā)和處理;在Qt中,程序在一個類中定義多個Signal和Slot,Signal就相當于“事件〞,而Slot就相當于響應事件的“方法〞。為了實現“事件驅動〞,需要將一個類的Signal和另一個類的Slot連接起來(使用connect)。采用這種機制是一種平安可靠的方法,它允許回調。并支持對象之間在彼此不知道對方信息的情況下進行合作,這使Qt非常適合于真正的構件編程。6.開發(fā)程序的方便性Qt提供了一個可視化的開發(fā)工具QtDesigner,使用該工具就像在Windows中使用VisualC++那樣可以直接向工程中添加各種組件,而不需要一步一步地編寫代碼,這個特點是其它非可視化編程工具望塵莫及的。QtDesigner中包含全面的聯機幫助文檔,包括超文本方式的QtManual,man幫助手冊頁和補充指南。這些幫助不管是對于初學者還是專業(yè)人士,都是非常方便的。7.強大的功能Qt的強大功能主要表達在以下幾方面:擁有一套完整的組件,用戶可以直接基于這些現成的組件開發(fā)出優(yōu)秀的界面;擁有豐富的API函數,大概有250多個C++類;具有優(yōu)越的繪畫功能和2D/3D圖形潤色功能,Qt的繪畫工具類Qpainter,可以在任意一個繪畫設備上潤色圖形,對于更高級的2D/3D圖形可以結合使用OpenGL和Qt的組件,使用OpenGL就像用任意一個Qt組件一樣方便,而且效果比純粹使用OpenGL作2D/3D圖形更好;支持XML。Qt的類庫Qt類庫大致可以分為三個局部:控件,框架和工具。1.控件控件局部包括環(huán)境控件,主窗口控件,標準對話框,根本的GUI控件,擴展GUI控件,GUI組織控件,以及幫助系統控件。環(huán)境控件為應用程序提供全局效勞的類,包括系統設定、國際化等。例如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等。Qt對象通訊機制對象間通訊是面向對象程序設計的一個極其重要的內容,類似于MicrosoftMFC的消息映射和事件循環(huán),Qt的對象間通訊采用的是信號—槽(signal—slot)機制,信號就好似是事件,而槽那么是響應事件的方法。如果需要實現對象間的通訊,只需要把一個對象的信號和另外一個對象的槽使用連接(connect)起來。信號—槽機制說明:Qt下對象間的通訊用信號—槽機制來實現。信號—槽機制是Qt的一個中心特征并且也是它與其它圖形工具包的最不相同的局部。圖2-1直觀地表示了這種機制是如何工作的。圖2-1信號與槽的連接原理圖在圖形用戶界面編程中,經常希望一個窗口部件的一個變化被通知給另一個窗口部件。更一般地,希望任何一類對象可以和其它對象進行通訊。例如,如果正在解析一個XML文件,當遇到一個新的標簽時,也許要通知列表視圖正在用來表達XML文件的結構。較老的工具包是使用一種被稱作回調的通訊方式來實現同一目的?;卣{是指一個函數的指針,所以如果希望一個處理函數通知一些事件,可以把另一個函數(回調)的指針傳遞給處理函數,處理函數在適當的時候調用回調函數?;卣{有兩個主要缺點:首先他們不是類型平安的,從來都不能確定處理函數使用了正確的參數來調用回調;其次回調和處理函數是非常強有力地聯系在一起的,因為處理函數必須知道要調用哪個回調。在Qt中有一種可以替代回調的技術:使用信號和槽。當一個特定事件發(fā)生的時候,一個信號被發(fā)射。Qt的窗口部件有很多預定義的信號,但是總是可以通過繼承來參加自己定義的信號。槽就是一個可以被調用處理特定信號的函數。Qt的窗口部件有很多預定義的槽,通常也可以參加自己的槽,這樣就可以處理感興趣的信號了。信號—槽機制是類型平安的:一個信號的簽名必須與它的接收槽的簽名相匹配。實際上一個槽的簽名可以比它接收的信號的簽名少,因為它可以忽略額外的簽名。因為簽名是一致的,編譯器就可以幫助檢測類型是否匹配。信號和槽是寬松地聯系在一起的:一個發(fā)射信號的類不用知道哪個槽要接收這個信號。Qt的信號和槽的機制可以保證如果把一個信號和一個槽連接起來,槽會在正確的時間使用信號的參數而被調用。信號和槽可以使用任何數量、任何類型的參數。它們是完全類型平安的,不會再有回調核心轉儲。從QObject類或者它的一個子類(比方QWidget類)繼承的所有類都可以包含信號槽。當對象的狀態(tài)發(fā)生改變的時候,信號被發(fā)送給其它對象,從而實現了該對象與其它對象的通信。對象在發(fā)射信號時,無須知道有沒有槽接收它所發(fā)射的信號,而槽是正常的成員函數,一個槽不知道它是否被任何信號連接,這就是信息封裝,這種封裝確保了對象可以用作一個軟件組件。此外,使用對象時也無須知道這種通訊機制的實現細節(jié)。在信號—槽機制實現的過程中,可以把許多信號和單一槽相連,也可以把一個信號和許多槽相連。把一個信號和另一個信號直接相連也是可以的。(這時,只要第一個信號被發(fā)射時,第二個信號立刻就被發(fā)射)??傮w來看,信號和槽構成了一個強有力的組件編程機制。第三章需求分析3.1軟硬件需求本次的開發(fā)環(huán)境所采用的操作系統為Linux操作系統的Ubuntu10.10版本,編程環(huán)境是基于QT4.7的Qtcreator版本,由于本游戲對硬件的要求不是很嚴格,所以硬件需求不做討論。3.2游戲功能需求本次設計是在傳統的連連看上設計實現對戰(zhàn)的連連看,玩家通過到達一定的積分來獲得繼續(xù)闖關的時機,還有時機開啟神秘的應藏關,以此來增加游戲的可玩性。游戲的根本規(guī)那么:程序隨機產生任意成對的圖片,當定點擊開始游戲時,電腦根據時間參數隨機生成固定的成對圖片,游戲再次開始,玩家可通過鼠標上的左鍵,自由的點兩張圖片。如果點擊兩次時,兩張圖片相同,且滿足程序的算法那么這兩張圖片可消去。消去圖片后,游戲可給玩家加分,假設在規(guī)定的時間內,玩家沒有消掉所有的圖片那么游戲失敗。由于是闖關模式,到達一定分數的玩家可以繼續(xù)挑戰(zhàn)新的游戲,游戲的難度會相應增加,并且還增加了新玩法。具體的游戲功能如下:游戲界面需求:設計良好的游戲界面可以讓玩家充分感受到游戲帶來的娛樂性,游戲的背景取自網上中的圖片,表達了游戲的挑戰(zhàn)性。鼠標處理事件需求:通過點擊主窗體中相應的按鈕,可以實現游戲的開始、暫停、結束,通過點擊選項設置中相應的按鈕,可設置聲音的大小及方向鍵↓的功能。顯示需求:當兩次點擊的圖片相同且滿足算法可以消去,當到達一定分數的時候,游戲會進入下一關,并有障礙了。游戲闖關設計需求:隨著游戲的難度不同,玩法會發(fā)生改變,需要在游戲中設置障礙,蒙手游戲。如果玩家能到達并完成最后一關,那么玩家挑戰(zhàn)成功,游戲結束。圖3.1游戲開始界面第四章游戲總體設計4.1總體設計整體設計思想:進入游戲后,有三個按鈕可供玩家選擇:開始游戲,游戲設置,退出游戲,在進入相應子菜單后也可返回到主菜單,每個菜單的具體設計將在后面介紹,以下是總體的游戲流程圖。主菜單主菜單開始游戲暫停繼續(xù)鍵盤方向鍵控制游戲返回主菜單退出游戲設置選項第一關過關第二關過關第…關過關第六關失敗設置聲音設置網格挑戰(zhàn)成功設置加速圖4-1游戲總體流程圖設計4.2游戲開始模塊設計此模塊為本次設計的核心模塊,玩家在主菜單設置好游戲選項后點擊開始按鈕后開始游戲,并進入游戲窗口,游戲窗口大體是這樣設計的:首先最上面一欄顯示當前處于第幾關,游戲區(qū)域分為兩局部,主游戲區(qū)顯示當前游戲畫面,其寬設置為10個單位的小方塊圖片的邊長,高為20,游戲區(qū)域右邊的上面局部設置了3個功能按鈕:重新開始游戲、暫停、返回主菜單按鈕;游戲區(qū)域右邊的下面局部那么顯示主菜單界面,該界面在游戲開始后處于隱藏狀態(tài),當玩家點擊“返回主菜單〞按鈕后,主菜單會重新顯示出來,同時游戲界面處于隱藏狀態(tài)。在開始游戲后,當玩家獲得一定積分后,會進入下一關,如果失敗,那么必須重新開始。玩家在順利完成第五關后,這時,玩家就能進入神秘的隱藏關,一次來增加游戲難度〔相信那將會很有趣〕。4.3游戲設置模塊設計游戲設置模塊提供了3個設置選項:是否顯示游戲網格、音量設置以及音效設置,這些設置的靈活性可以方便不同水平用戶的自由選擇,以便一步步晉級。而音效效果那么可以增加用戶玩游戲的樂趣。設置好游戲選項后,即可返回主菜單開始游戲,在游戲的過程中也可以隨時暫停返回主菜單,再進行重新設置游戲選項,這樣更加方便用戶的使用。4.4游戲核心模塊的設計連連看所要求的是:1:兩個目標是相同的2:兩個目標之間連接線的折點不超過兩個?!策B接線由x軸和y軸的平行線組成〕那么分析一下連接的情況可以看到,一般分三種情況1:直線相連2:一個折點3:兩個折點:可以發(fā)現,如果有折點,每個折點必定有且至少有一個坐標〔x或者y〕是和其中一個目標點是相同的,也就是說,折點必定在兩個目標點所在的x方向或y方向的直線上。所以設計思路就是:假設目標點p1,p2,如果有兩個折點分別為z1,z2那么,所要進行的是1:如果驗證p1,p2直線連線,那么連接成立2:搜索以p1,p2的x,y方向四條直線〔可能某兩條直線會重合〕上的有限點,每次取兩點作為z1,z2,驗證p1到z1/z1到z2/z2到p2是否都能直線相連,是那么連接成立。連連看消去算法實現在檢驗兩張圖片能否消掉的時候,我們要讓兩張圖片同時滿足兩個條件才行,就是兩者配對并且連線成功。分3種情況:(從下面的這三種情況,我們可以知道,需要三個檢測,這三個檢測分別檢測一條直路經。這樣就會有三條路經。假設這三條路經上都是空按鈕,那么就剛好是三種直線〔兩個轉彎點〕把兩個按鈕連接起來了)1.相鄰2.假設不相鄰的先在第一個按鈕的同行找一個空按鈕。1).找到后看第二個按鈕橫向到這個空按鈕所在的列是否有按鈕。2).沒有的話再看第一個按鈕到與它同行的那個空按鈕之間是否有按鈕。3).沒有的話,再從與第一個按鈕同行的那個空按鈕豎向到與第二個按鈕的同行看是否有按鈕。沒有的話路經就通了,可以消了.3.假設2失敗后,再在第一個按鈕的同列找一個空按鈕。1).找到后看第二個按鈕豎向到這個空按鈕所在的行是否有按鈕2).沒有的話,再看第一個按鈕到與它同列的那個空按鈕之間是否有按鈕。3).沒有的話,再從與第一個按鈕同列的那個空按鈕橫向到與第二個按鈕同列看是否有按鈕。沒有的話路經就通了,可以消了。假設以上三步都失敗,說明這兩個按鈕不可以消去。第五章具體實現5.1模型層設計圖形的產生通過圖形工廠類ShapeFactory的getShape(ShapeListenerlistener)方法隨機產生方塊的某種狀態(tài),這里運用了工廠設計模式。圖形的變形圖形的變形是通過函數char*MyItem::itemChange(unsignedchar*currentItem)來實現的,該函數首先是在內存中開辟一個新的4*4數組,用來保存變化后的方塊,通過兩個for循環(huán),依次將數組中個元素的橫坐標與列坐標交換位置,即可使原來的方塊逆時針旋轉90度,到達旋轉方塊的目的。判段消掉圖片如果兩在張圖片滿足一個拐點,沒有拐點。兩個拐點那么該兩張圖片就可以消掉,同時需要用一個全局變量fullRowNum來保存此次一共消除了多少張,以便算分,沒有拐點10分,一個拐點20分,二個拐點的是30分。具體是通過函數voidGameArea::clearRow()來實現的。5.2視圖層設計圖片的顯示方塊的顯示是通過調用GameArea類中的draw_currentMap()方法實現的,首先判斷存儲方塊的數組的值,但凡值為1的成員那么給該數組控制的對應游戲區(qū)域的坐標通過調用painter.drawPixmap()繪制圖片,具體的坐標和范圍以及圖片來源都是有painter.drawPixmap()中的參數給定的。在調用painter.drawPixmap()函數之前,還可以設置圖片顏色,具體是通過painter.setPen()h和painter.setBrush()來實現的這樣就能顯示方塊,而且可以不斷的改變顏色,使游戲界面富有動感。游戲區(qū)域的顯示游戲區(qū)域的繪制包括網格和游戲區(qū)的方塊的繪制,具體通過調用GameArea類中的draw_gameArea()函數來實現,在該函數中調用到了繪制網格的draw_Grid()函數和顯示圖片的draw_currrentMap()函數,在draw_Grid()函數中調用Painter類的painter.drawLine()函數繪制網格,具體的起始點和結束點同樣由傳遞參數獲得。首先需要設置游戲區(qū)域大小,可以通過this->gameArea->setGameAreaPi〔〕實現,還需要安置新的坐標原點可以通過調用該函數。5.3其它相關技術的實現鍵盤事件響應連連看是通過鼠標左鍵來控制游戲的運行,那么是具體如何實現的呢?這就需要用到鍵盤的左擊事件,通過響應鼠標的按下事件來實現。玩家通過鼠標左鍵來控制圖片的點擊。具體代碼實現:通過重新實現虛函數QWidget::keyPressEvent來響應相應的鍵盤按鍵事件。聲音的實現聲音的實現在這里用到了一個單獨的類MyBoxAudio來封裝,聲音的實現要用到庫類中的Phonon類,首先創(chuàng)立一個媒體對象medioObject和用于輸出聲音的設備接口對象audioOutput,有了這兩個對象以后再調用Phonon::createPath()函數生成路徑,然后綁定音頻文件〔必須為.wav格式的〕,最后調用medioObject.play()函數,即可實現聲音的播放。第六章游戲測試6.1選項按鈕的功能測試〔1〕點擊“游戲開始〞:游戲正常開始,結果正常;〔2〕點擊“游戲設置〞:彈出游戲設置對話框;能夠選中向下鍵↓選項和是否繪制網格選項,聲音大小可調,點擊“返回〞按鈕能夠回到主菜單,結果正常;〔3〕點擊“退出游戲〞:游戲正常退出,結果正常;〔4〕點擊“暫停〞:游戲停止,“暫停〞變?yōu)椤叭∠麜和(?,再點擊“取消暫停〞:游戲繼續(xù),結果正常;〔5〕點擊“返回主菜單〞:游戲退回到主菜單界面,結果正常;6.2按鍵事件的功能測試〔1〕兩次點擊相同圖片,假設滿足算法,圖片消失,那么結果正常;〔2〕圖片點擊測試:游戲過程中,點擊鼠標左鍵:圖片在沒有其他圖片阻擋的情況下可變灰色,結果正常;6.3圖片消失測試〔1〕當點擊兩張相同圖片:兩站圖片同時消失,結果正常;〔2〕當圖片消失,且滿足一條直線時分數增加10分,滿足一個拐點分數增加20分,滿足兩個拐點,分數增加30分;6.4聲音和顯示測試〔1〕進入游戲時:背景音樂正常播放,圖片消失時,有背景音樂播放;〔2〕在游戲過程中,游戲區(qū)域背景顏色不斷改變;在開始最后一關時:游戲區(qū)域越來越大,結果正常;6.5測試結果分析經過測試,本游戲實現了根本的連連看的功能,運行比擬穩(wěn)定,不過有些細節(jié)方面可能需要改良,游戲在很多方面還需要進一步完善??傮w的游戲界面效果如下列圖所示:圖6.1游戲界面效果總結游戲設計與實踐是一項復雜而龐大的工作,在選題之后,我才意識到過程的艱難,因為以前從來都沒有接觸過游戲設計,剛開始有點迷茫和彷徨。后來通過翻閱書籍和在網上查閱資料,逐漸找到了一些感覺,在老師的指導下,自己也手動編寫了幾個簡單的游戲,打地鼠游戲和網絡N子棋雙人對戰(zhàn)游戲,本文以連連看游戲為例予以說明。本次設計讓我初步懂得了電子游戲涉及到的有關技術、方法,包括電子游戲選題、構思、設計步驟等。并實現一些可演示的游戲軟件,其中有很多應用了學習的相關技術,并且做到了界面、聲音都能實際演示。此次設計過程中印象最深的收獲有:1、學到了很多新知識,并且對老知識進行了回憶。經過長時間的學習,更進一步熟悉了Qt編程、通過不斷上機實驗,調試程序,總結經驗,從對課題的不理解到能夠開始動手去做,提出新問題并自己想方法去解決問題,自己多實踐,所以增強了動手能力。2、提高了中、英文資料的檢索能力。這次畢業(yè)設計過程中我查閱了多資料,包括一些期刊、雜志,還有網絡中的電子文檔、電子書籍、網頁及下載的視頻教學課程;不但有中文資料還有英文資料。這些資料,使我的眼界更開闊,對課題的認識更加深刻,編寫程序的時候思路更加清楚,少走了很多彎路?;貞洿舜卧O計過程,我學到了許多書本上沒有學到的知識。通過這次自己制作的軟件,豐富了自己的實踐技能,擴張了本專業(yè)的知識面,使我受益匪淺,同時也體驗到了搞軟件開發(fā)的難度。在這次設計的同時,由于我對這樣的軟件開發(fā)還只是一個開始,了解的不多,這其中或許還有很多的缺乏,有些模塊做得不是很好,有些功能還不能夠完全的實現,如播放背景音樂時,只能播放一遍,因為游戲Qt類庫中封裝的東西太多,有些函數它底層的具體實現可能還沒有真正的理解,所以,這也許就是本次游戲設計的缺乏之處。致謝今天,畢業(yè)設計也告一段落了,也就意味著我的大學時代即將結束。回想畢業(yè)設計這幾個月,回想大學這四年的時光,感慨萬千。值得留戀,值得追憶的,實在太多。還有很多老師,同學,朋友要感謝。首先,要感謝我的指導老師黃同成老師,他認真負責、踏實努力的工作精神,一絲不茍、嚴謹治學的專業(yè)作風,給我留下了深刻的印象。黃老師教給我的不僅是科學知識,他還教給了我做人的道理,所有這些都為我今后的人生道路奠定了堅實的根底,使我受益終生。同時,也要感謝成老師,黃磊老師,感謝信息工程系所有老師四年來的悉心教誨。我們所在的實驗室是一個溫暖的大集體,也要感謝我們實驗室各位老師給我的幫助。也要感謝與我同寢室的同學四年來,在工作和學習中給與我的鼓勵和幫助。最后,我還要向我的父母表示最真誠的感謝和祝福,是他們的辛勤和汗水養(yǎng)育了我,是他們的精神鼓舞了我,使我能夠不懈努力和拼搏。致謝人:陳嚴2012參考文獻[1]MarkSummerfield著.白建平等譯.Qt高級編程[M].電子工業(yè)出版社2023.8.[2]StanleyB.Lippman等著.李師賢等譯.C++Primer中文版[M].人民郵電出版社2023.7.[3]W.RichardStevens、StephenA.Rago著.尤晉元等譯.UNIX環(huán)境高級編程[M].人民郵電出版社2023.10.[4]Stanleyb.Lippman著.侯捷譯.深度探索C++對象模型[M].華中科技大學出版社2001.5.[5]譚浩強著.C程序設計第三版[M].清華大學出版社2005.7.[6]嚴蔚敏、吳偉民著.數據結構[M].清華大學出版社2023.9.[7]宋勁杉編著.LinuxC編程一站式學習[M].電子工業(yè)出版社2023.12.[8]KennethA.Reek著.徐波譯.C和指針[M].人民郵電出版社2003.9.[9]JasmineBlanchette、MarkSummerfield著.閆鋒欣等譯.C++GUIQt4編程[M].電子工業(yè)出版社2023.8.[10]丁林松、黃麗琴編著.Qt4圖形設計與嵌入式開發(fā)[M].人民郵電出版社.2023.4.附錄源代碼Mainwindow.cpp#include<resolv.h>#include<stdlib.h>#include<netinet/in.h>#include<arpa/inet.h>#include<unistd.h>#include<QScrollBar>#include"mainwindow.h"#include"ui_mainwindow.h"#include"udp.h"#include<QImage>#include<QTime>#include"llk.h"#include<iostream>usingnamespacestd;MainWindow::MainWindow(QWidget*parent):QMainWindow(parent),ui(newUi::MainWindow){ui->setupUi(this);connect(this,SIGNAL(recvMessage(QString,QString)),this,SLOT(onRecvMessage(QString,QString)));//this->setCentralWidget(link);//link->setMaximumSize(300,300);ui->editChatRec->setReadOnly(true);//link=newllk();size=6;isLinkE=false;sendMessage("55",8838,"o17",true);}MainWindow::~MainWindow(){deleteui;}voidMainWindow::changeEvent(QEvent*e){QMainWindow::changeEvent(e);switch(e->type()){caseQEvent::LanguageChange:ui->retranslateUi(this);break;default:break;}}voidMainWindow::on_btnSend_clicked(){QStringstring=ui->lineEdit->text();if(ui->radiosingle->isChecked()==true){sendMessage(string,8838,'c'+ui->editChat->text(),true);}else{string="55";sendMessage("55",8838,'c'+ui->editChat->text(),true);}QStringstr=trUtf8("自己對")+string+trUtf8("發(fā)送:")+"\n"+ui->editChat->text();ui->editChatRec->setPlainText(ui->editChatRec->toPlainText()+"\n"+str);ui->editChat->clear();QScrollBar*bar=ui->editChatRec->verticalScrollBar();bar->setSliderPosition(bar->maximum());}Ui::MainWindow*MainWindow::getUi(){returnui;}voidMainWindow::onRecvMessage(QStringmsg,QStringipAdd){//QStringtime=QTime::currentTime().toString();QStringstring=time+"\n"+QString(trUtf8("收到來自"))+ipAdd+trUtf8(":的消息:")+"\n"+msg.right(msg.length()-1);switch(msg.at(0).toAscii()){case'o'://如果接受的是上線消息ui->listWidget->addItem(msg.right(msg.length()-1));break;default://如果接受的是普通消息ui->editChatRec->setPlainText(ui->editChatRec->toPlainText()+"\n"+string);break;}QScrollBar*bar=ui->editChatRec->verticalScrollBar();bar->setSliderPosition(bar->maximum());}voidMainWindow::on_action_begin_triggered(){/*link=newllk();link->setsize(6);link->arrayInit(6);link->Create(6);link->show();isLinkE=true;*///size=4;if(isLinkE){//link=newllk();//link->setsize(8);//link->arrayInit(8);//link->Create(8);link->close();isLinkE=false;}else{link=newllk();link->setsize(size);link->arrayInit(size);link->Create(size);link->show();isLinkE=true;}if(isLinkE==false){link=newllk();link->setsize(size);link->arrayInit(size);link->Create(size);link->show();isLinkE=true;}}voidMainWindow::on_action_close_triggered(){this->close();link->close();}voidMainWindow::on_action_pause_triggered(){if(isLinkE)link->setEnabled(false);}voidMainWindow::on_action_return_triggered(){link->setEnabled(true);}voidMainWindow::on_action_easy_triggered(){size=6;if(isLinkE){//link=newllk();//link->setsize(8);//link->arrayInit(8);//link->Create(8);link->close();isLinkE=false;}else{link=newllk();link->setsize(6);link->arrayInit(6);link->Create(6);link->show();isLinkE=true;}if(isLinkE==false){link=newllk();link->setsize(6);link->arrayInit(6);link->Create(6);link->show();isLinkE=true;}}voidMainWindow::on_action_soso_triggered(){size=8;/*llk*lin;lin=newllk();//this->setCentralWidget(lin);//lin->setGeometry(30,30,500,500);lin->setsize(8);lin->arrayInit(8);lin->Create(8);lin->setVisible(true);lin->close();*/if(isLinkE){//link=newllk();//link->setsize(8);//link->arrayInit(8);//link->Create(8);link->close();isLinkE=false;}else{link=newllk();link->setsize(8);link->arrayInit(8);link->Create(8);link->show();isLinkE=true;}if(isLinkE==false){link=newllk();link->setsize(8);link->arrayInit(8);link->Create(8);link->show();isLinkE=true;}}voidMainWindow::on_action_diffcult_triggered(){size=10;/*llk*lin;lin=newllk();//this->setCentralWidget(lin);//lin->setGeometry(30,30,500,500);lin->setsize(8);lin->arrayInit(8);lin->Create(8);lin->setVisible(true);lin->close();*/if(isLinkE){//link=newllk();//link->setsize(8);//link->arrayInit(8);//link->Create(8);link->close();isLinkE=false;}else{link=newllk();link->setsize(10);link->arrayInit(10);link->Create(10);link->show();isLinkE=true;}if(isLinkE==false){link=newllk();link->setsize(10);link->arrayInit(10);link->Cremybutton.cpp#include"mybutton.h"MyButton::MyButton(intvalue,QWidget*parent){this->value=value;this->setParent(parent);QObject::connect(this,SIGNAL(clicked()),this,SLOT(mySlot()));}voidMyButton::mySlot(){emitmyClicked(this->value);}

Main.cpp#include<QtGui/QApplication>#include"mainwindow.h"#include<QtGui/QApplication>#include<errno.h>#include<sys/socket.h>#include<resolv.h>#include<stdlib.h>#include<netinet/in.h>#include<arpa/inet.h>#include<unistd.h>#include<iostream>#include<string>usingnamespacestd;constunsignedintMAXBUF=1024;void*thd_handler(void*window){MainWindow*w=(MainWindow*)window;intsockfd;structsockaddr_inmy_addr;socklen_taddrlen;charbuffer[MAXBUF];unsignedintmyport=8838;printf("serverstarted!\n");//createasocketforudpif((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0) //attention{perror("socketcreationfailure");exit(errno);}//initializesockaddr_inbzero(&my_addr,sizeof(my_addr));my_addr.sin_family=AF_INET;my_addr.sin_port=htons(myport);my_addr.sin_addr.s_addr=INADDR_ANY;//bindif(bind(sockfd,(structsockaddr*)&my_addr,sizeof(structsockaddr))==-1){perror("bindfailure");exit(errno);}printf("bindsuccess\n");addrlen=sizeof(structsockaddr);while(true){bzero(buffer,MAXBUF);intlen=recvfrom(sockfd,buffer,MAXBUF,0,(sockaddr*)&my_addr,&addrlen);if(len<0){perror("recvfrom");exit(errno);}emitw->recvMessage(QObject::trUtf8(buffer),inet_ntoa(my_addr.sin_addr));}//closeconnectionclose(sockfd);}intmain(intargc,char*argv[]){pthread_tntid;QApplicationa(argc,argv);MainWindoww;pthread_create(&ntid,NULL,thd_handler,&w);w.show();returna.exec();}udp.cpp#include"udp.h"#include<QString>#include<errno.h>#include<sys/socket.h>#include<resolv.h>#include<stdlib.h>#include<netinet/in.h>#include<arpa/inet.h>#include<unistd.h>voidsendMessage(QStringipAddress,unsignedintport,QStringmsg,boolisBroad){ //constunsignedintMAXBUF=1024;intsockfd;intaddr_len;intlen;structsockaddr_indest;//charbuffer[MAXBUF];charaddr[16];strcpy(addr,ipAddress.toAscii());//createasocketforudpif((sockfd=socket(AF_INET,SOCK_DGRAM,0))<0) //attention{perror("socketcreationfailure");exit(errno);}if(isBroad){intbroad=1;setsockopt(sockfd,SOL_SOCKET,SO_BROADCAST,&broad,sizeof(broad));strcpy(addr,"55");}//initializesockaddr_inbzero(&dest,sizeof(dest));dest.sin_family=AF_INET;dest.sin_port=htons(port);if(inet_aton(addr,(structin_addr*)&dest.sin_addr)==0){perror("ipaddressformatiserror");exit(errno);}//sendmsgtoserveraddr_len=sizeof(dest);//bzero(buffer,MAXBUF);len=sendto(sockfd,msg.toLocal8Bit(),msg.toLocal8Bit().length(),0,(sockaddr*)&dest,addr_len);if(len<0){printf("\n\rsenderror.\n\r");exit(errno);}//closeconnection::close(sockfd);}llk.cpp#include"llk.h"#include<iostream>#include"judge.h"llk::llk(){isFirstClick=true;llk::createBtnRerank();size=6;llk::createCurrentProgressBar(size);timer=newQTimer();currentTime=0;QObject::connect(timer,SIGNAL(timeout()),this,SLOT(timeProcess()));}voidllk::xxx(intx){clear(x);//std::cout<<x<<std::endl;//mybutton[x]->setVisible(false);//Widget::arrayInit(6);//progressBar[1]->setValue(20);}voidllk::addPic(QStringpath,inti){labelPic[i]=newQLabel(this);labelPic[i]->setGeometry(i*100+5,30,100,120);QPixmappixmap(path);labelPic[i]->setPixmap(path);labelPic[i]->setVisible(false);progressBar[i]=newQProgressBar();progressBar[i]->setGeometry(i*100+10,120,100,20);progressBar[i]->setParent(this);progressBar[i]->setValue(10);}voidllk::Create(intsize){createTimeProcessBar(size*size);timer->start(1000);charss[26][20]={"begin","./icon/icon1.png","./icon/icon2.png","./icon/icon3.png","./icon/icon4.png","./icon/icon5.png","./icon/icon6.png","./icon/icon7.png","./icon/icon8.png","./icon/icon9.png","./icon/icon10.png","./icon/icon11.gif","./icon/icon12.gif","./icon/icon13.gif","./icon/icon14.gif","./icon/icon15.gif","./icon/icon16.gif","./icon/icon17.gif","./icon/icon18.gif","./icon/icon19.gif","./icon/icon20.gif","./icon/icon21.gif","./icon/icon22.gif","./icon/icon23.gif","./icon/icon24.gif","./icon/icon25.gif"};createCurrentProgressBar(size);currentIndex=size*size;progressBarCurrent->setValue(0);for(unsignedinti=0;i<size*size;i++){mybutton[i]=newMyButton(i,this);mybutton[i]->setGeometry(20+i%size*60,150+i/size*60,60,60);intx,y;x=i/size+1;if((i+1)%size){y=(i+1)%size;}elsey=size;intm=array[x][y];//std::cout<<x<<","<<y<<std::endl;mybutton[i]->setIcon(QIcon(ss[m]));mybutton[i]->setIconSize(QSize(50,50));QObject::connect(mybutton[i],SIGNAL(myClicked(int)),this,SLOT(xxx(int)));//mybutton[i]->setIcon(QIcon(s));}}voidllk::arrayInit(intsize){array[size+1][0]=0;array[size+1][size+1]=0;array[0][size+1]=0;array[0][0]=0;for(inti=1;i<=size;i++){array[0][i]=0;array[size+1][i]=0;array[i][0]=0;array[i][size+1]=0;for(intj=1;j<=size;j++){array[i][j]=((i-1)*size+j-1)/4+1;}}for(inti=1;i<=size;i++){for(intj=1;j<=size;j++){intx1,x2,y1,y2,tmp1;//srand(unsigned(time(NULL)));x1=rand()%size+1;x2=rand()%size+1;y1=rand()%size+1;y2=rand()%size+1;tmp1=array[x1][y1];array[x1][y1]=array[x2][y2];array[x2][y2]=tmp1;}}for(inti=0;i<=size+1;i++){for(intj=0;j<=size+1;j++){std::cout<<array[i][j]<<"";}std::cout<<std::endl;}}voidllk::clear(intindex){if(isFirstClick){firstIndex=index;isFirstClick=false;std::cout<<firstIndex<<",";}else{std::cout<<index<<std::endl;intx1,y1,x2,y2;x1=firstIndex/size+1;x2=index/size+1;if((firstIndex+1)%size){y1=(firstIndex+1)%size;}elsey1=size;if((index+1)%size){y2=(index+1)%size;}elsey2=size;std::cout<<x1<<","<<y1<<std::endl;std::cout<<x2<<","<<y2<<std::endl;std::cout<<"**************"<<std::endl;

溫馨提示

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

評論

0/150

提交評論