




已閱讀5頁,還剩18頁未讀, 繼續(xù)免費(fèi)閱讀
版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
一 游戲概述 1.1游戲簡(jiǎn)介 游戲“連連看”顧名思義就是找出相關(guān)聯(lián)的東西,這個(gè)連連看在網(wǎng)上基本是用在小游戲中,就是找出相同的兩樣?xùn)|西,在一定的規(guī)則之內(nèi)可以做為相關(guān)聯(lián)處理?!斑B連看”的發(fā)展經(jīng)歷了從桌面游戲、在線游戲、社交游戲三個(gè)過程。 游戲“連連看”是源自臺(tái)灣的桌面小游戲,自從流入大陸以來風(fēng)靡一時(shí),也吸引眾多程序員開發(fā)出多種版本的“連連看”。這其中,顧方編寫的“阿達(dá)連連看”以其精良的制作廣受好評(píng),這也成為顧方“阿達(dá)系列軟件”的核心產(chǎn)品。并于2004年,取得了國(guó)家版權(quán)局的計(jì)算機(jī)軟件著作權(quán)登記證書。隨著Flash應(yīng)用的流行,網(wǎng)上出現(xiàn)了多種在線Flash版本“連連看”。如“水晶連連看”,“果蔬連連看”等,流行的“水晶連連看”以華麗界面吸引了一大批的女性玩家。2008年,隨著社交網(wǎng)絡(luò)的普及和開放平臺(tái)的興起,“連連看”被引入了社交網(wǎng)絡(luò)?!斑B連看”與個(gè)人空間相結(jié)合,被快速的傳播,成為一款熱門的社交游戲,其中以開發(fā)者Jonevey在Manyou開放平臺(tái)上推出的“寵物連連看”最為流行。 1.2游戲功能本次設(shè)計(jì)連連看主要是在原連連看對(duì)戰(zhàn)的基礎(chǔ)上設(shè)計(jì)挑戰(zhàn)模式,具體的功能如下所述:l 游戲運(yùn)行界面簡(jiǎn)單美觀,操作簡(jiǎn)單,運(yùn)行穩(wěn)定;l 能夠根據(jù)不同的等級(jí)模式播放不同的游戲背景音樂,包括操作方向鍵、消行時(shí)的聲音,音量由玩家操作控制;l 設(shè)計(jì)不同的游戲難度,當(dāng)玩家達(dá)到一定的積分,可以進(jìn)入相關(guān)難度的等級(jí);玩家可直接操作界面上的相關(guān)按鈕來控制游戲的開始、暫停、設(shè)置、退出等功能。二 需求分析2.1開發(fā)的需求 2.1.1 C+ C/C+的哲學(xué)就不一樣了,同一份程序代碼,只要在該平臺(tái)重新Compile成該平臺(tái)的執(zhí)行檔,就能在該平臺(tái)執(zhí)行,若文字模式下的程序,的確可以跨平臺(tái),程序完全不需修改,但GUI盛行以后,由于各GUI的Library都不一樣且沒有標(biāo)準(zhǔn),所以GUI程序并沒辦法跨平臺(tái)Compile,因?yàn)楦髌脚_(tái)都有專屬的 Library。但是C/C+優(yōu)勢(shì)就是執(zhí)行速度快,若能解決GUI Library的問題,則跨平臺(tái)即可解決。除了GUI Library需要統(tǒng)一外,還得看該Library設(shè)計(jì)的好不好才行,Linux GUI我沒寫過就不說了,若在Windows平臺(tái),Borland的C+ Builder使用Delphi的VCL Library,Microsoft的Visual C+可以用MFC和.NET Framework,首先來看Borland的C+ Builder,它使用標(biāo)準(zhǔn)的ANSI C+語言開發(fā),利用VCL寫出來的程序也算蠻漂亮的,執(zhí)行速度很快,比較麻煩的是C+ Builder當(dāng)初為了縮短上市時(shí)間,并沒有設(shè)計(jì)自己的Library,而是藉用Delphi的Library,導(dǎo)致C+ Builder在Compile時(shí),是先用Delphi的Compiler將VCL compile成object file后,再用C+ Builder將你寫的C+程序compile成object file,最后再用Linker將所有的object file link起來,由于這都是IDE在做,對(duì)程序設(shè)計(jì)師似乎影響不大,但VCL由于是Delphi的Library,所以若想深入研究VCL的source code時(shí),則必須學(xué)Delphi的Pascal才行,否則看不懂VCL source code,這也是很多人對(duì)C+ Builder卻步的原因。再來看Microsoft的Visual C+,MFC用的是完整的ANSI C+語言,所以語言部分不是問題,但若你看過用MFC寫的程序,你一定會(huì)驚訝為什么這么復(fù)雜,程序代碼非常冗長(zhǎng)不好看,且MFC是有名的難學(xué),若 Visual C+搭配.NET Framrwork,則無法使用ANSI C+,得用其.NET平臺(tái)版本的C+/CLI,相信這點(diǎn)很多人就有意見了,不過.NET Framework由于設(shè)計(jì)的不錯(cuò),所以寫出來的程序相當(dāng)精簡(jiǎn)漂亮,感覺和C+ Builder差不多,不過無論是C+ Builder或Visual C+開發(fā)的GUI,所開發(fā)出來的程序都無法跨平臺(tái),當(dāng)然也無法跨平臺(tái)Compile。 2.1.2 QT(1)QT的介紹 Qt 是一個(gè)多平臺(tái)的C+圖形用戶界面應(yīng)用程序框架。它提供給應(yīng)用程序開發(fā)者建立藝術(shù)級(jí)的圖形用戶界面所需的所用功能。Qt 是完全面向?qū)ο蟮暮苋菀讛U(kuò)展,并且允許真正地組件編程。自從 1996 年早些時(shí)候,Qt 進(jìn)入商業(yè)領(lǐng)域,它已經(jīng)成為全世界范圍內(nèi)數(shù)千種成功的應(yīng)用程序的基礎(chǔ)。Qt 也是流行的Linux 桌面環(huán)境KDE 的基礎(chǔ),KDE 是所有主要的Linux 發(fā)行版的一個(gè)標(biāo)準(zhǔn)組件。Qt 的特點(diǎn)有:可移植性、易用性、執(zhí)行速度快等特點(diǎn)。(2)QT的優(yōu)勢(shì)l XML 支持。l 大量的開發(fā)文檔l 支持 2D/3D 圖形渲染,支持 OpenGLl 優(yōu)良的跨平臺(tái)特性,Qt支持下列操作系統(tǒng): Microsoft Windows 95/98, Microsoft Windows NT, Linux, Solaris, SunOS, HP-UX, Digital UNIX (OSF/1, Tru64), Irix, FreeBSD, BSD/OS, SCO, AIX, OS390,QNX 等等。l 面向?qū)ο?,Qt 的良好封裝機(jī)制使得 Qt 的模塊化程度非常高,可重用性較好,對(duì)于用戶開發(fā)來說是非常 方便的。 Qt 提供了一種稱為 signals/slots 的安全類型來替代 callback,這使得各個(gè)元件 之間的協(xié)同工作變得十分簡(jiǎn)單。l 豐富的 API,Qt包括多達(dá)250個(gè)以上的 C+ 類,還提供基于模板的 collections,serialization,file, I/O device,directory management, date/time 類。甚至還包括正則表達(dá)式的處理 功能。2.2 游戲功能需求 本次設(shè)計(jì)是在傳統(tǒng)的連連看上設(shè)計(jì)實(shí)現(xiàn)對(duì)戰(zhàn)的連連看,玩家通過達(dá)到一定的積分來獲得繼續(xù)闖關(guān)的機(jī)會(huì),還有機(jī)會(huì)開啟神秘的應(yīng)藏關(guān),以此來增加游戲的可玩性。游戲的基本規(guī)則:程序隨機(jī)產(chǎn)生任意成對(duì)的圖片,當(dāng)定點(diǎn)擊開始游戲時(shí),電腦根據(jù)時(shí)間參數(shù)隨機(jī)生成固定的成對(duì)圖片,游戲再次開始,玩家可通過鼠標(biāo)上的左鍵,自由的點(diǎn)兩張圖片。如果點(diǎn)擊兩次時(shí),兩張圖片相同,且滿足程序的算法則這兩張圖片可消去。消去圖片后,游戲可給玩家加分,若在規(guī)定的時(shí)間內(nèi),玩家沒有消掉所有的圖片則游戲失敗。由于是闖關(guān)模式,達(dá)到一定分?jǐn)?shù)的玩家可以繼續(xù)挑戰(zhàn)新的游戲,游戲的難度會(huì)相應(yīng)增加,并且還增加了新玩法。具體的游戲功能如下:游戲界面需求:設(shè)計(jì)良好的游戲界面可以讓玩家充分感受到游戲帶來的娛樂性,游戲的背景取自網(wǎng)上中的圖片,體現(xiàn)了游戲的挑戰(zhàn)性。 鼠標(biāo)處理事件需求:通過點(diǎn)擊主窗體中相應(yīng)的按鈕,可以實(shí)現(xiàn)游戲的開始、暫停、結(jié)束,通過點(diǎn)擊選項(xiàng)設(shè)置中相應(yīng)的按鈕,可設(shè)置聲音的大小及方向鍵的功能。顯示需求:當(dāng)兩次點(diǎn)擊的圖片相同且滿足算法可以消去,當(dāng)達(dá)到一定分?jǐn)?shù)的時(shí)候,游戲會(huì)進(jìn)入下一關(guān),并有障礙了。游戲闖關(guān)設(shè)計(jì)需求:隨著游戲的難度不同,玩法會(huì)發(fā)生改變,需要在游戲中設(shè)置障礙,蒙手游戲。如果玩家能到達(dá)并完成最后一關(guān),則玩家挑戰(zhàn)成功,游戲結(jié)束。最后游戲效果如下:三 游戲總體設(shè)計(jì) 3.1 總體設(shè)計(jì)整體設(shè)計(jì)思想:進(jìn)入游戲后,有三個(gè)按鈕可供玩家選擇:開始游戲,游戲設(shè)置,退出游戲,在進(jìn)入相應(yīng)子菜單后也可返回到主菜單,每個(gè)菜單的具體設(shè)計(jì)將在后面介紹,以下是總體的游戲流程圖。 3.2游戲核心模塊的設(shè)計(jì) 3.2.1連連看所要求的是:1兩個(gè)目標(biāo)是相同的;2兩個(gè)目標(biāo)之間連接線的折點(diǎn)不超過兩個(gè)。(連接線由x軸和y軸的平行線組成) 那么分析一下連接的情況可以看到,一般分三種情況:(1)直線相連;(2)一個(gè)折點(diǎn);(3)兩個(gè)折點(diǎn)??梢园l(fā)現(xiàn),如果有折點(diǎn),每個(gè)折點(diǎn)必定有且至少有一個(gè)坐標(biāo)(x或者y)是和其中一個(gè)目標(biāo)點(diǎn)是相同的,也就是說,折點(diǎn)必定在兩個(gè)目標(biāo)點(diǎn)所在的x方向或y方向的直線上。所以設(shè)計(jì)思路就是:假設(shè)目標(biāo)點(diǎn) p1 , p2 ,如果有兩個(gè)折點(diǎn)分別為z1 , z2 那么,所要進(jìn)行的是 : 如果驗(yàn)證p1 , p2 直線連線,則連接成立 搜索以p1,p2的x,y方向四條直線(可能某兩條直線會(huì)重合)上的有限點(diǎn),每次取兩點(diǎn)作為z1,z2 ,驗(yàn)證p1到z1/z1到z2/z2到p2 是否都能直線相連 ,是則連接成立。3.2.2 連連看消去算法實(shí)現(xiàn)在檢驗(yàn)兩張圖片能否消掉的時(shí)候,我們要讓兩張圖片同時(shí)滿足兩個(gè)條件才行,就是兩者配對(duì)并且連線成功。分3種情況:(從下面的這三種情況,我們可以知道,需要三個(gè)檢測(cè),這三個(gè)檢測(cè)分別檢測(cè)一條直路經(jīng)。這樣就會(huì)有三條路經(jīng)。若這三條路經(jīng)上都是空按鈕,那么就剛好是三種直線(兩個(gè)轉(zhuǎn)彎點(diǎn))把兩個(gè)按鈕連接起來了)(1)相鄰 (2) 若不相鄰的先在第一個(gè)按鈕的同行找一個(gè)空按鈕。1).找到后看第二個(gè)按鈕橫向到這個(gè)空按鈕所在的列是否有按鈕。2).沒有的話再看第一個(gè)按鈕到與它同行的那個(gè)空按鈕之間是否有按鈕。3).沒有的話,再從與第一個(gè)按鈕同行的那個(gè)空按鈕豎向到與第二個(gè)按鈕的同行看是否有按鈕。沒有的話路經(jīng)就通了,可以消了. (3)若2失敗后,再在第一個(gè)按鈕的同列找一個(gè)空按鈕。1).找到后看第二個(gè)按鈕豎向到這個(gè)空按鈕所在的行是否有按鈕 2).沒有的話,再看第一個(gè)按鈕到與它同列的那個(gè)空按鈕之間是否有按鈕。3).沒有的話,再從與第一個(gè)按鈕同列的那個(gè)空按鈕橫向到與第二個(gè)按鈕同列看是否有按鈕。沒有的話路經(jīng)就通了,可以消了。 若以上三步都失敗,說明這兩個(gè)按鈕不可以消去。四 具體方案4.1視圖層設(shè)計(jì)4.1.1圖形的產(chǎn)生加載圖塊圖片資源,調(diào)用圖片庫用函數(shù)DrawArea:loadPixmap()來實(shí)現(xiàn)。函數(shù)如下設(shè)計(jì):void DrawArea:loadPixmap() background.load(:/background/background.png); background=background.scaled(size(); QPixmap pix(:/pattern/pattern.png); int num=pix.height()/PIX_SIZE; for(int i=1;inum;+i) qreal y=PIX_SIZE*i; QPixmap p=pix.copy(0,y,PIX_SIZE,PIX_SIZE); pixmap.push_back(p); 4.1.2 判段消掉圖片如果兩個(gè)圖片一樣,我們進(jìn)行消塊,并進(jìn)行加分操作。消塊操作如下:if(hitTimer) killTimer(hitTimer); hitTimer =startTimer(INTERVAL_HIT_TIMER); +multiHit; emit hit(multiHit); lineTimer=startTimer(INTERVAL_LINE_TIMER);4.2 邏輯層設(shè)計(jì) 僵局考慮 判斷是否已經(jīng)進(jìn)入死局,死局條件:在回合尚未結(jié)束的情況下遍歷面板,無法找到一對(duì)可銷圖塊則判定為死局。若找到一對(duì)可銷圖塊,則將其記錄為hintA和hintB,以供hint()函數(shù)利用。設(shè)計(jì)代碼如下:bool DrawArea:isDead() int i,j,x,y; if(!pairLeft) return true; for(i=0;ixMax;+i) for(j=0;jyMax;+j) if(boardij) for(x=i;xxMax;+x) if(x=i) y=j+1; else y=0; for(;yyMax;+y) if(boardxy=boardij) if(isPosLinkable(i,j,x,y)/如果消塊成功,那么這里就變成了0 hintA.x=i; hintA.y=j; hintB.x=x; hintB.y=y; return false; return true;4.3 其它相關(guān)技術(shù)的實(shí)現(xiàn) 鍵盤事件響應(yīng)連連看是通過鼠標(biāo)左鍵來控制游戲的運(yùn)行,那么是具體如何實(shí)現(xiàn)的呢?這就需要用到鍵盤的左擊事件,通過響應(yīng)鼠標(biāo)的按下事件來實(shí)現(xiàn)。玩家通過鼠標(biāo)左鍵來控制圖片的點(diǎn)擊。具體代碼實(shí)現(xiàn):通過重新實(shí)現(xiàn)虛函數(shù)GameWindow:keyPressEvent(QKeyEvent *event)來響應(yīng)相應(yīng)的鍵盤按鍵事件。五 游戲的測(cè)試5.1 選項(xiàng)按鈕的功能測(cè)試 (1)點(diǎn)擊“游戲開始”:游戲正常開始,結(jié)果正常; (2)點(diǎn)擊“退出游戲”:游戲正常退出,結(jié)果正常; (3)點(diǎn)擊“暫?!保河螒蛲V?,“暫?!弊?yōu)椤叭∠麜和!?,再點(diǎn)擊“取消暫?!保河螒蚶^續(xù),結(jié)果正常; (4)點(diǎn)擊“返回主菜單”:游戲退回到主菜單界面,結(jié)果正常;5.2 按鍵事件的功能測(cè)試 (1)兩次點(diǎn)擊相同圖片,若滿足算法,圖片消失,則結(jié)果正常; (2)圖片點(diǎn)擊測(cè)試:游戲過程中,點(diǎn)擊鼠標(biāo)左鍵:圖片在沒有其他圖片阻擋的情況下可變色,結(jié)果正常;5.3 圖片消失測(cè)試 (1)當(dāng)點(diǎn)擊兩張相同圖片:兩站圖片同時(shí)消失,結(jié)果正常; (2)當(dāng)圖片消失,且滿足一條直線時(shí)分?jǐn)?shù)增加10分。5.4 聲音和顯示測(cè)試 (1)進(jìn)入游戲時(shí):背景音樂正常播放,圖片消失時(shí),有背景音樂播放;(2)在游戲過程中,游戲區(qū)域背景顏色不斷改變;在開始最后一關(guān)時(shí):游戲區(qū)域越來越大,結(jié)果正常;5.5 測(cè)試結(jié)果分析 經(jīng)過測(cè)試,本游戲?qū)崿F(xiàn)了基本的連連看的功能,運(yùn)行比較穩(wěn)定,不過有些細(xì)節(jié)方面可能需要改進(jìn),游戲在很多方面還需要進(jìn)一步完善。六 小結(jié)游戲設(shè)計(jì)與實(shí)踐是一項(xiàng)復(fù)雜而龐大的工作,在選題之后,我才意識(shí)到過程的艱難,因?yàn)橐郧皬膩矶紱]有接觸過游戲設(shè)計(jì),剛開始有點(diǎn)迷茫和彷徨。后來通過翻閱書籍和在網(wǎng)上查閱資料,逐漸找到了一些感覺。本次設(shè)計(jì)讓我初步懂得了電子游戲涉及到的有關(guān)技術(shù)、方法,包括電子游戲選題、構(gòu)思、設(shè)計(jì)步驟等。并實(shí)現(xiàn)一些可演示的游戲軟件,其中有很多應(yīng)用了學(xué)習(xí)的相關(guān)技術(shù),并且做到了界面、聲音都能實(shí)際演示。此次設(shè)計(jì)過程中印象最深的收獲有:1、學(xué)到了很多新知識(shí),并且對(duì)老知識(shí)進(jìn)行了回顧。經(jīng)過長(zhǎng)時(shí)間的學(xué)習(xí),更進(jìn)一步熟悉了Qt編程、通過不斷上機(jī)實(shí)驗(yàn),調(diào)試程序,總結(jié)經(jīng)驗(yàn),從對(duì)課題的不理解到能夠開始動(dòng)手去做,提出新問題并自己想辦法去解決問題,自己多實(shí)踐,所以增強(qiáng)了動(dòng)手能力。2、提高了中、英文資料的檢索能力。這次專業(yè)設(shè)計(jì)過程中我查閱了多資料,包括一些期刊、雜志,還有網(wǎng)絡(luò)中的電子文檔、電子書籍、網(wǎng)頁及下載的視頻教學(xué)課程;不但有中文資料還有英文資料。這些資料,使我的眼界更開闊,對(duì)課題的認(rèn)識(shí)更加深刻,編寫程序的時(shí)候思路更加清楚,少走了很多彎路。回顧此次設(shè)計(jì)過程,我學(xué)到了許多書本上沒有學(xué)到的知識(shí)。通過這次自己制作的軟件,豐富了自己的實(shí)踐技能,擴(kuò)張了本專業(yè)的知識(shí)面,使我受益匪淺,同時(shí)也體驗(yàn)到了搞軟件開發(fā)的難度。在這次設(shè)計(jì)的同時(shí),由于我對(duì)這樣的軟件開發(fā)還只是一個(gè)開始,了解的不多,這其中或許還有很多的不足,有些模塊做得不是很好,有些功能還不能夠完全的實(shí)現(xiàn),如播放背景音樂時(shí),只能播放一遍,因?yàn)橛螒騋t類庫中封裝的東西太多,有些函數(shù)它底層的具體實(shí)現(xiàn)可能還沒有真正的理解,所以,這也許就是本次游戲設(shè)計(jì)的不足之處。七 源碼(部分代碼):/*drawarea.cpp*/#include drawarea.h#include #include #include #include #include #include #include #include #include const int INTERVAL_LINE_TIMER=200;const int INTERVAL_HIT_TIMER =2000;const int PIX_SIZE = 46;const int AREA_WIDTH = Y_MAX*PIX_SIZE;const int AREA_HEIGHT = X_MAX*PIX_SIZE;DrawArea:DrawArea(QWidget *parent) : QWidget(parent) loadPixmap(); drawArea = new QLabel(this); drawArea-setGeometry(0,0,AREA_WIDTH,AREA_HEIGHT); drawArea-setPixmap(background); isHintUsed=false;QSize DrawArea:size() const return QSize(AREA_WIDTH,AREA_HEIGHT);QSize DrawArea:sizeHint() const return size();/* 初始化關(guān)卡 */void DrawArea:initLevel(const Map &mapData) lastX=mapData.xMax; lastY=mapData.yMax; lineTimer=0; hitTimer =0; multiHit =0; pairLeft =0; xMax=mapData.xMax; yMax=mapData.yMax; for(int i=0;ixMax;+i) for(int j=0;jyMax;+j) boardij=mapData.mapij; if(boardij) +pairLeft; if(pairLeft%2!=0) emit errorNotify(tr(地圖數(shù)據(jù)錯(cuò)誤,地圖存在不成對(duì)的塊數(shù)); return; if(pairLeft=0) emit errorNotify(tr(地圖數(shù)據(jù)為空); return; pairLeft =pairLeft/2; disorder(mapData.disorderCount); /剛開局就判斷死局,一個(gè)是初始化上帝之手, /再一個(gè)最主要原因是為hint圖塊對(duì)賦值 /上帝之手的初始化必須在地圖數(shù)據(jù)加載之后進(jìn)行 if(isDead() godTouch=true; emit godTouchOn(); else godTouch=false; isLevelOver = false; drawBoard();/Test從文件加載地圖及相關(guān)配置信息。void DrawArea:loadMapFromFile(string fileName) int nDisorder; FILE *mapFile; mapFile=fopen(fileName.c_str(),r); if(!mapFile) exit(-1); if(fscanf(mapFile,%d %d,&nDisorder,&pairLeft)=EOF) emit errorNotify(tr(Test:地圖數(shù)據(jù)加載失敗); return; for(int i=0;ixMax;+i) for(int j=0;jyMax;+j) if(fscanf(mapFile,%d,&boardij)=EOF) emit errorNotify(tr(Test:地圖數(shù)據(jù)無法成功加載); return; fclose(mapFile); disorder(nDisorder);/根據(jù)指定的打亂次數(shù) nDisorder對(duì)面板內(nèi)的非零數(shù)據(jù)進(jìn)行交換void DrawArea:disorder(int nDisorder) srand(clock(); /基本實(shí)現(xiàn):將非零數(shù)據(jù)加入到一個(gè)足夠長(zhǎng)的數(shù)組中,隨機(jī)產(chǎn)生兩個(gè) /坐標(biāo)進(jìn)行交換 int posxMax*yMax2; int nBlock=0; for(int i=0;ixMax;+i) for(int j=0;jyMax;+j) if(boardij) posnBlock0=i; posnBlock1=j; +nBlock; for(int i=nDisorder;i;-i) int pos1=rand()%nBlock; generatePos2: int pos2=rand()%nBlock; if(pos1=pos2) goto generatePos2; int x1=pospos10; int y1=pospos11; int x2=pospos20; int y2=pospos21; std:swap(boardx1y1,boardx2y2); drawBoard();/* 加載圖塊圖片資源 */void DrawArea:loadPixmap() background.load(:/background/background.png); background=background.scaled(size(); QPixmap pix(:/pattern/pattern.png); int num=pix.height()/PIX_SIZE; for(int i=1;itimerId()=lineTimer) killTimer(lineTimer); lineTimer =0; drawBoard(); if(event-timerId()=hitTimer) multiHit=0; killTimer(hitTimer); hitTimer =0; drawBoard(); /* 接受鼠標(biāo)按下的消息并將其發(fā)生的相對(duì)屏幕坐標(biāo)轉(zhuǎn)換成數(shù)組坐標(biāo) * 傳入clickPos進(jìn)行判斷,同時(shí)將其畫上選中標(biāo)志。 */void DrawArea:mousePressEvent(QMouseEvent *event) int y=(event-x()-drawArea-x()/PIX_SIZE; int x=(event-y()-drawArea-y()/PIX_SIZE; if(!isBlank(x,y) emit select(); isHintUsed = false; drawEmbrace(x,y); clickPos(x,y); /* 繪制面板,當(dāng)回合未結(jié)束時(shí),繪制面板上所有圖塊的內(nèi)容。 * 如果連擊數(shù)不少于兩次,則在屏幕正中心顯示 xN Hit的字樣 */voidDrawArea:drawBoard() store=background; QPainter painter(&store); if(!isLevelOver) painter.setCompositionMode(QPainter:CompositionMode_SourceOver); for(int i=0;ixMax;+i) for(int j=0;jyMax;+j) painter.save(); painter.translate(j*PIX_SIZE,i*PIX_SIZE); if(!isBlank(i,j) & boardij1) QFont font; QPen pen(Qt:SolidLine); pen.setColor(QColor(255,255,255,220); font.setFamily(Comic Sans MS); font.setPixelSize(30); font.setBold(true); painter.setPen(pen); painter.setFont(font); painter.drawText(QPointF(0,AREA_HEIGHT-15),tr(x%1 連擊!).arg(multiHit); painter.end(); drawArea-setPixmap(store); if(isHintUsed) drawEmbrace(hintA.x,hintA.y); drawEmbrace(hintB.x,hintB.y); else drawEmbrace(lastX,lastY);/* 為選中的圖塊畫上標(biāo)志 */void DrawArea:drawEmbrace(const int &x,const int &y) if(isValid(x,y) & boardxy) QPainter painter(&store); painter.setCompositionMode(QPainter:RasterOp_SourceAndDestination); QPen pen; pen.setWidth(5); pen.setColor(Qt:blue); painter.setPen(pen); painter.translate(y*PIX_SIZE,x*PIX_SIZE); painter.drawRect(0,0,PIX_SIZE,PIX_SIZE); painter.end(); drawArea-setPixmap(store); /* 在指定的圖塊上畫一個(gè)紅色的叉號(hào) */void DrawArea:drawRedMark(const int &x, const int &y) QPainter painter(&store); QPen pen(Qt:white); pen.setWidth(5); painter.setPen(pen); painter.translate(y*PIX_SIZE,x*PIX_SIZE); painter.drawLine(0,0,PIX_SIZE,PIX_SIZE); painter.drawLine(0,PIX_SIZE,PIX_SIZE,0); painter.end(); drawArea-setPixmap(store);/* 在兩個(gè)給定點(diǎn)之間畫一條較粗的直線 */void DrawArea:drawLine(const int &aX, const int &aY, const int &bX, const int &bY) QPainter painter(&store); int x1=aY*PIX_SIZE+ PIX_SIZE/2; int y1=aX*PIX_SIZE+PIX_SIZE/2; int x2=bY*PIX_SIZE+PIX_SIZE/2; int y2=bX*PIX_SIZE+PIX_SIZE/2; QPen pen(Qt:blue); pen.setStyle(Qt:SolidLine); pen.setWidth(5); painter.setPen(pen); painter.drawLine(x1,y1,x2,y2); painter.end(); drawArea-setPixmap(store);void DrawArea:autoDestroy() lastX=hintA.x; lastY=hintA.y; clickPos(hintB.x,hintB.y);/* *連連看邏輯實(shí)現(xiàn)相關(guān)函數(shù) */* 判斷是否已經(jīng)進(jìn)入死局,死局條件: * 在回合尚未結(jié)束的情況下遍歷面板,無法找到一對(duì)可銷圖塊 * 則判定為死局。若找到一對(duì)可銷圖塊,則將其記錄為hintA * 和hintB,以供hint()函數(shù)利用。 */bool DrawArea:isDead() int i,j,x,y; if(!pairLeft) return true; for(i=0;ixMax;+i) for(j=0;jyMax;+j) if(boardij) for(x=i;xxMax;+x) if(x=i) y=j+1; else y=0; for(;yyMax;+y) if(boardxy=boardij) if(isPosLinkable(i,j,x,y)/如果消塊成功,那么這里就變成了0 hintA.x=i; hintA.y=j; hintB.x=x; hintB.y=y; return false; return true;/* 在 (x,y)位置發(fā)生了點(diǎn)擊,如果上次點(diǎn)擊的點(diǎn)花色與之相同且位置不同, * 對(duì)于上帝模式,直接銷塊。 * 否則,嘗試判斷是否可連接,如果可連接則進(jìn)行連線, * 并隨后進(jìn)行死局判斷,如進(jìn)入死局則開啟上帝模式 * 否則將這個(gè)點(diǎn)記為上次點(diǎn)擊的點(diǎn)。 * 每次成功銷塊之后,立即增加連擊計(jì)數(shù)并啟動(dòng)一個(gè)連擊定時(shí)器,如果連擊 * 定時(shí)器過期,則連擊計(jì)數(shù)清零。 */void DrawArea:clickPos(int x,int y) assert( isValid(x,y) ); assert( !isBlank(x,y) ); vector posVec; int nPos=0; Pos pos1,pos2; if(lastX=x &lastY=y) return; if(!isValid(lastX,lastY)| !isSame(x,y,lastX,lastY)|/isSame must be placed after isValid isBlank(lastX,lastY) lastX=x; lastY=y; drawBoard(); return; if(godTouch) drawRedMark(x,y); drawRedMark(lastX,lastY); goto Destroy_Blocks; if(isPosLinkable(x,y,lastX,lastY,&nPos,&pos1,&pos2) Pos a(x,y); Pos b(lastX,lastY); posVec.push_back(a); if(nPos=1) posVec.push_back(pos1); if(nPos=2) posVec.push_back(pos2); posVec.push_back(b); for(unsigned int i=0;
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 書法教師培訓(xùn)提升計(jì)劃
- 醫(yī)院感染監(jiān)測(cè)與培訓(xùn)計(jì)劃
- 幼兒園保育員崗位輪換工作計(jì)劃
- 部編版九年級(jí)語文上冊(cè)教師成長(zhǎng)計(jì)劃
- 學(xué)生不服從管理違紀(jì)檢討書范文
- 鋼結(jié)構(gòu)大型體育場(chǎng)館成本控制措施
- 高三物理目標(biāo)分?jǐn)?shù)達(dá)成計(jì)劃
- 制造業(yè)工資審核發(fā)放流程規(guī)范
- 幼兒園2025年秋季后勤保障工作計(jì)劃
- 以形助思:高中物理教學(xué)中圖像法的深度應(yīng)用與策略探究
- 國(guó)際咨詢工程師聯(lián)合會(huì)fidic合同中英文對(duì)照版
- 天然氣開采業(yè)的技術(shù)裝備與設(shè)施建設(shè)
- 高素質(zhì)農(nóng)民培育培訓(xùn)
- 《厭氧菌感染的治療》課件
- 葫蘆灸培訓(xùn)課件
- 社區(qū)中醫(yī)健康知識(shí)講座總結(jié)
- 耵耳護(hù)理查房
- 貴州省黔東南州2024屆化學(xué)高一第二學(xué)期期末統(tǒng)考試題含解析
- 避孕套市場(chǎng)需求分析報(bào)告
- 2023年切削刀具行業(yè)市場(chǎng)分析報(bào)告及未來發(fā)展趨勢(shì)
- 標(biāo)準(zhǔn)教程HSK1第5課
評(píng)論
0/150
提交評(píng)論