版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、<p> 《數(shù)據(jù)結構》課程設計</p><p> 題 目 掃雷 </p><p><b> 掃雷程序設計</b></p><p><b> 目錄</b></p><p> 摘 要···
2、183;····································
3、······························3</p><p> 1、引言··
4、····································
5、3;·····························4</p><p> 1.1 課題背景及意義·
6、83;····································&
7、#183;················4</p><p> 1.2 Visual C++ 發(fā)展概況············
8、3;····································
9、183;·5</p><p> 1.3關于本課題·····························
10、3;·····························6</p><p> 2、游戲的總體分析與設計·
11、183;····································
12、··············7</p><p> 2.1 游戲功能簡介·················
13、····································
14、3;···7</p><p> 2.2設計構想····························&
15、#183;································7</p><p>
16、 2.3流程規(guī)劃···································
17、183;·························8</p><p> 3、掃雷游戲的具體實現(xiàn)過程·····
18、;····································
19、83;·······9</p><p> 3.1掃雷游戲模塊的實現(xiàn)·······················&
20、#183;···························9</p><p> 3.1.1 掃雷游戲主窗體的創(chuàng)建··&
21、#183;····································
22、;·····9</p><p> 3.1.2 主界面控制菜單的設計·························
23、;··················13</p><p> 3.2掃雷游戲核心-----布雷算法設計···········
24、······························13</p><p> 3.3 掃雷鼠標事件的處理
25、183;····································
26、·············20</p><p> 3.4掃雷其它處理··················
27、····································
28、3;·27</p><p> 3.4.1 難度設置菜單消息處理····························
29、83;··············27</p><p> 3.4.2 背景音樂菜單消息處理···············
30、183;···························28</p><p> 3.4.3其它處理···
31、183;····································
32、················29</p><p> 4、掃雷游戲程序的調試與運行··············&
33、#183;································29</p><p>
34、 5、掃雷游戲設計總結··································
35、3;····················31</p><p> 6、致謝···········
36、83;····································&
37、#183;··················31</p><p> 7、參考文獻············
38、3;····································
39、183;·············32</p><p><b> 摘要</b></p><p> 游戲業(yè)發(fā)展一日千里,該行業(yè)極大的影響和改變了人們的生活和娛樂方式,游戲為消費者提供豐富多彩的虛擬空間,使消費者可以自由自在的享受虛擬世界的
40、樂趣,實現(xiàn)自己在現(xiàn)實生活著那個可能永遠不能實現(xiàn)的夢想,滿足了消費者的心理和精神需求。</p><p> 掃雷游戲是Windows操作系統(tǒng)自帶的一個小游戲,過去的幾年里Windows操作系統(tǒng)歷經數(shù)次換代,變得越來越龐大、復雜,但這個可愛的小游戲在任何版本的Windows操作系統(tǒng)里去卻依然保持著原貌。但幾乎每個電腦使用者都接觸過它,并且深愛著這款小游戲。</p><p> 掃雷游戲是比較經
41、典的一款小游戲,實現(xiàn)它的方法很多,可以用很多不同算法和語言實現(xiàn),如C,C++,VB,JAVA等。本論文研究的是以Visual C++ 6.0為開發(fā)環(huán)境,設計并開發(fā)一款掃雷游戲,其功能類似于Windows操作系統(tǒng)自帶的掃雷游戲。論文首先介紹了制作游戲的整體思路及整個游戲設計的流程規(guī)劃,然后介紹了雷區(qū)的布置及地雷隨機產生的實現(xiàn)方法;重點介紹了在游戲過程中各事件的處理,其中又以鼠標事件和清除未靠近地雷區(qū)方塊這兩方面最為最要,鼠標事件是利用鼠標
42、所發(fā)出的信息了解使用者的意圖,進而做出相對應的動作,而清除未靠近地雷區(qū)方塊由于引進了“遞歸”這個概念而使其簡單化。</p><p> 關鍵字:掃雷;Visual C++ 6.0;事件;遞歸</p><p><b> Abstract</b></p><p><b> 1 引言</b></p><p
43、> 1.1 課題背景及意義</p><p> 當前隨著計算機的深入普及,越來越多的人有了個人電腦,人們運用計算機完成許多重要的工作,計算機在人們的生活中變的越來越來重要。隨著計算機的應用和發(fā)展計算機已經不單純是一個工作工具,人們越來越重視計算機的娛樂性了,近年來游戲產業(yè)規(guī)模持續(xù)成長,全球每年游戲業(yè)總產值已經突破200億美金,遠遠超越好萊塢電影產業(yè)以及音樂娛樂事業(yè),而成為目前娛樂事業(yè)的最大主流。不過游戲產
44、業(yè)光鮮亮麗的背后,卻也隱含著高風險、高成本的危機,顯示游戲產業(yè)慢慢步入“微利時代”?! ∧壳罢麄€游戲產業(yè)的運作模式已經跟好萊塢電影產業(yè)的運作模式相同,電影產業(yè)有制片、發(fā)行、宣傳等分工,游戲產業(yè)亦同,由專業(yè)的游戲研發(fā)小組負責研發(fā)游戲,也有如微軟、美商藝電這類國際級大廠負責游戲發(fā)行,甚至連“游戲制作人”也被培養(yǎng)成明星一樣成為一種招牌,如任天堂有王牌制作人宮本茂、SEGA有鈴木裕、KONAMI有小島秀夫、CAPCOM有三上真司、TECMO有
45、板垣伴信...等,明確的游戲產業(yè)分工的確有助于游戲產業(yè)的規(guī)模發(fā)展與進化,但也無形中讓游戲開發(fā)成本大增。為了降低游戲開發(fā)成本,開發(fā)娛樂性強成本低的游戲就成為當前的主要課題,在這種趨勢下各種小型的低成本的</p><p> 1.2 Visual C++ 發(fā)展概況</p><p> Visual C++是一個功能強大的可視化軟件開發(fā)工具。自1993年Microsoft公司推出Visual C
46、++1.0后,隨著其新版本的不斷問世,Visual C++已成為專業(yè)程序員進行軟件開發(fā)的首選工具。</p><p> 雖然微軟公司推出了Visual C++.NET(Visual C++7.0),但它的應用的很大的局限性,只適用于Windows 2000,Windows XP和Windows NT4.0。所以實際中,更多的是以Visual C++6.0為平臺。</p><p> Vis
47、ual C++6.0不僅是一個C++編譯器,而且是一個基于Windows操作系統(tǒng)的可視化集成開發(fā)環(huán)境(integrated development environment,IDE)。Visual C++6.0由許多組件組成,包括編輯器、調試器以及程序向導AppWizard、類向導Class Wizard等開發(fā)工具。 這些組件通過一個名為Developer Studio的組件集成為和諧的開發(fā)環(huán)境。</p><p>
48、 Visual C++它大概可以分成三個主要的部分:</p><p> 1. Developer Studio,這是一個集成開發(fā)環(huán)境,我們日常工作的99%都是在它上面完成的,再加上它的標題赫然寫著“Microsoft Visual C++”,所以很多人理所當然的認為,那就是Visual C++了。其實不然,雖然Developer Studio提供了一個很好的編輯器和很多Wizard,但實際上它沒有任何編譯和鏈
49、接程序的功能,真正完成這些工作的幕后英雄后面會介紹。我們也知道,Developer Studio并不是專門用于VC的,它也同樣用于VB,VJ,VID等Visual Studio家族的其他同胞兄弟。所以不要把Developer Studio當成Visual C++, 它充其量只是Visual C++的一個殼子而已。這一點請切記!</p><p> 2. MFC,從理論上來講,MFC也不是專用于Visual C++
50、,Borland C++,C++Builder和Symantec C++同樣可以處理MFC。同時,用Visual C++編寫代碼也并不意味著一定要用MFC,只要愿意,用Visual C++來編寫SDK程序,或者使用STL,ATL,一樣沒有限制。不過,Visual C++本來就是為MFC打造的,Visual C++中的許多特征和語言擴展也是為MFC而設計的,所以用Visual C++而不用MFC就等于拋棄了Visual C++中很大的一部
51、分功能。但是,Visual C++也不等于MFC。</p><p> 3. Platform SDK。這才是Visual C++和整個Visual Studio的精華和靈魂,雖然我們很少能直接接觸到它。大致說來,Platform SDK是以Microsoft C/C++編譯器為核心(不是Visual C++,看清楚了),配合MASM,輔以其他一些工具和文檔資料。上面說到Developer Studio沒有編譯程
52、序的功能,那么這項工作是由誰來完成的呢?是CL,是NMAKE,和其他許許多多命令行程序,這些我們看不到的程序才是構成Visual Studio的基石。Visual C++ 之所以具有如此廣泛的用途是因為它具有以下的特點:</p><p> (1) 真正的面向對象編程,使開發(fā)人員不用加入太多的代碼,加快了系統(tǒng)開發(fā)的速度。</p><p> (2) 可視化的編程方法以及向導的功能,使開發(fā)人
53、員不用加入太多的代碼就可以開發(fā)出標準的Windows程序。</p><p> (3) 數(shù)據(jù)訪問的特性,允許對包括Microsoft SQL Server和其他企業(yè)數(shù)據(jù)庫在內的大部分數(shù)據(jù)庫格式建立數(shù)據(jù)庫和前端應用程序,以及可調整的服務器端部件等。</p><p> (4) 通過ActiveX技術可使用其他應用程序提供的功能,例如Microsoft Word字處理器、Microsoft E
54、xcel電子數(shù)據(jù)表及其他Windows應用程序,甚至可直接使用Visual Basic創(chuàng)建的應用程序和對象。</p><p> (5) Internet功能強大,使用戶很容易在應用程序內通過Internet或企業(yè)內部網(Intranet)訪問文檔和應用程序,或者創(chuàng)建Internet服務器應用程序。</p><p> (6) 已完成的應用程序是真正的.exe文件,您可以自由發(fā)布。<
55、/p><p><b> 1.3關于本課題</b></p><p> 隨著世界經濟的長足發(fā)展和計算機技術的日益成熟,計算機被應用到人類活動的各個領域,各種應用軟件也相繼問世,這其中有相當一部分是游戲軟件。使用游戲軟件自然是為了滿足人們對娛樂性的要求,而有些軟件大都采用3D設計對系統(tǒng)配置的要求較高。</p><p> 在眾多游戲軟件中,也不乏一些
56、小游戲的身影,它們對系統(tǒng)的配置要求較低。能夠滿足人們對娛樂性的需求,是人們在完成工作娛樂時候的最好選擇?,F(xiàn)在越來越多的人投入到這種小游戲的開發(fā)當中,它已經成為一類必不可少的游戲軟件。在各種操作系統(tǒng)中都附帶了一些小的游戲,而這些游戲也成為電腦用戶軟件中不可或缺的一部分。</p><p> 作為本系統(tǒng)的開發(fā)工具,Microsoft Visual C++ 6.0成為首選。它具有可視化的編程界面、詳細的提示、以及完善的
57、幫助文檔,使得軟件開發(fā)人員感到無比的親切感。</p><p> 2 游戲的總體分析與設計</p><p> 2.1 游戲功能簡介</p><p> 當前各種游戲軟件層出不窮。因為游戲的開發(fā)成本非常大,所以游戲的開發(fā)具有一定的風險性,但是一些小游戲的開發(fā)具有成本小,編寫簡單的優(yōu)勢,所以這些小游戲在游戲開發(fā)中也占有一席之地。在這類小游戲中包括益智類游戲,它以畫面精
58、美游戲方法簡單等特點得到大家的認可。成為人們在工作之余不可或缺的好伙伴。針對真種情況我用VB編寫了掃雷這款小游戲。下面對該游戲的功能做個簡單的介紹。</p><p> 掃雷游戲的基本功能 : 點擊鼠標左鍵于未知區(qū)域,如果未知區(qū)域有雷,游戲停止,顯示所有的地雷。如果沒雷,則顯示周圍雷數(shù),如果周圍沒雷,則再查看周圍八個區(qū)域是否有雷直到有雷為止并顯示,這其實是一個遞歸過程。</p><p>
59、 點擊鼠標右鍵于未知區(qū)域,則將其置為有雷而不管是否真的有雷??蛇x擇初、中、高三級并可自定義雷數(shù)和區(qū)域大小。</p><p> 雷區(qū)上部左側顯示總雷數(shù)減被標明有雷區(qū)域的數(shù)目。</p><p> 雷區(qū)上部中間位置顯示一按鈕用于開局和顯示鼠標動作的結果。</p><p> 雷區(qū)上部右側顯示掃雷的時間。</p><p> 將雷全部掃清后,則顯
60、示一對話框將你的姓名記入排行榜。</p><p><b> 2.2設計構想</b></p><p> 相信大多數(shù)使用Windows操作系統(tǒng)的使用者,對這款游戲都不陌生。這款游戲不止操作簡單,規(guī)則也不難,再加上游戲速度的控制機制得宜,讓整個游戲在操作過程中充滿了快樂與緊張的氣氛。除了游樂當中能帶給使用者快樂之外,游戲的設計內容無形中也不斷訓練使用者的邏輯思考能力,對
61、于依靠高度腦力工作的現(xiàn)代人,都可以通過這個游戲,不時的檢驗一下自己,所以我們不難發(fā)現(xiàn),在各種可攜帶的電子產品上都有這款游戲的蹤影。</p><p> 在設計之前,我們先來了解這款游戲的規(guī)則。</p><p> 在不掀開任何藏有地雷的方塊情況下,以最快的速度找出所有的地雷。如果在掀開方塊的過程中,不小心翻開(踩到)藏有地雷的方塊,則宣告失敗(游戲結束),惟有將所有不含地雷的方塊掀開,游戲
62、才算成功。</p><p> 游戲的操作方面主要以鼠標為主,當鼠標指針對準未翻開的方塊按下左鍵時即表示翻開方塊,當鼠標指針對準未翻開的方塊按下右鍵時即表示標示或疑示地雷,反復按下右鍵則方塊會以未標示→標示→疑似三者關系不斷循環(huán)。游戲者可以通過地雷區(qū)內的數(shù)字提示了解以數(shù)字為中心的其周邊八個方格內所含的地雷數(shù),假若翻開的方塊顯示數(shù)字“3”,則表示以其為中心的周邊方塊內藏有3個地雷。</p><p
63、> 當按下的方塊不是地雷,且周邊八個方塊也都沒有地雷時,方塊會以被翻開方塊的八個方向將空白方塊翻開。</p><p><b> 2.3流程規(guī)劃</b></p><p> 流程規(guī)劃大致上可以分為三個部分,分別為:畫面初始、游戲者按下第一個方塊和為非地雷方塊時展開。</p><p> 畫面初始時,以游戲者最后一次設定的地雷區(qū)大小為范圍
64、畫出地雷區(qū),但此時并未產生地雷。當游戲者按下第一個方塊時產生地雷資料并啟動定時器,為何在游戲者按下第一個方塊才產生地雷資料呢?其主要的用意在于不要讓游戲者第一次就踩到地雷,這樣在某種程度上可以提高游戲者游玩的氣氛。接著就是如何判斷按下的方塊是非地雷時的處理,這也是整個游戲的技術核心,我們可以通過遞歸的觀念來檢查周邊的方塊是否含有地雷及是否繼續(xù)往外翻開。</p><p> 基于以上思路,繪制功能圖如下:</
65、p><p> 3.掃雷游戲的具體實現(xiàn)過程</p><p> 3.1 掃雷游戲模塊的實現(xiàn)</p><p> 掃雷游戲的開發(fā)主要包括兩大部分:一個部分是布雷,該部分主要將雷隨機布置在游戲區(qū)域內,以避免出現(xiàn)相同的雷區(qū)布置地圖。另一部分是掃雷,該部分包括判斷鼠標左鍵點擊某區(qū)域該區(qū)域是否是雷,如果是雷該如何操作,如果不是雷該如何操作,鼠標右鍵點擊某區(qū)域時如果判斷該區(qū)域是雷則
66、加以標記,如果不是雷也加以標記,以及當鼠標雙擊某區(qū)域時,判斷與該區(qū)域相鄰的其它8個區(qū)域是否是雷并做一個標記。下面首先介紹第一部分之一——掃雷主窗體創(chuàng)建。</p><p> 3.1.1 掃雷游戲主窗體的創(chuàng)建</p><p> 啟動Visual C++ 6.0后,選擇新建工程,Visual C++ 6.0提供了用戶可能需要的各種類型的應用程序模板。如果是這種情況,選擇MFC AppWiza
67、rd(exe)項目,輸入工程名稱和位置,將創(chuàng)建一個新的工程如下:</p><p> 選擇基于Dialog based:</p><p> 其它的默認,建立新的工程。</p><p> 下面介紹一下如何創(chuàng)建窗體界面:</p><p> 首先,轉換窗口到資源編程窗口,修改主對話框的Caption屬性為“周龍掃雷游戲程序設計”,添加2個St
68、atic控件,1個Caption改為“剩余雷數(shù)”,1個Caption改為空用來表示剩余的雷數(shù)。其設計如下:</p><p> 當然,這只是設計的初始的界面,我們還需要在程序中添加其它代碼以初始化和美化運行的主界面。</p><p><b> 添加如下代碼:</b></p><p> void OnPaint()</p>&l
69、t;p><b> {</b></p><p> CDC memdc;</p><p> CBitmap bk;</p><p> bk.LoadBitmap(IDB_BACK);</p><p> memdc.CreateCompatibleDC(pDC);</p><p> p
70、DC->BitBlt(0,0,600,600,&memdc,0,0,SRCCOPY);</p><p><b> }</b></p><p> 主要是美化運行界面,如下:</p><p> 接下來要繪制鼠標操作區(qū)域,即游戲區(qū)域。添加繪制棋盤函數(shù)DrawChessBoard()</p><p><
71、b> 如下:</b></p><p> void CShaoLeiDlg::DrawChessBoard()</p><p><b> {</b></p><p> CDC* pDC = GetDC();</p><p> CPen pen(PS_SOLID,1,RGB(0,0,0));<
72、;/p><p> pDC->SelectObject(&pen);</p><p> for (int i = 0; i<row+1; i++)</p><p><b> {</b></p><p> pDC->MoveTo(x+cx*(i),y);</p><p>
73、 pDC->LineTo(x+cx*(i),y+row*cy);</p><p><b> }</b></p><p> for (int j = 0; j<col+1; j++)</p><p><b> {</b></p><p> pDC->MoveTo(x,y+(
74、j)*cy);</p><p> pDC->LineTo(x+col*cx,y+(j)*cy);</p><p><b> }</b></p><p><b> }</b></p><p> 然后的運行結果如下:</p><p> 3.1.2 主界面控制菜單的
75、設計</p><p> 接下來回到資源編程界面,編寫菜單資源,用來控制掃雷的過程,以及難度選定,和背景音樂等。</p><p> (1) “設置菜單“包含:開始,初級,中級,高級,音樂開,音樂關,退出</p><p> 其中,音樂開 包含 默認的音樂和打開本地音樂兩個子菜單項。</p><p> (2)“幫助“菜單獲取該軟件的版本信息
76、。</p><p><b> 如下:</b></p><p> 將菜單添加到主界面,至此主窗體基本創(chuàng)建完畢。</p><p> 3.2掃雷游戲核心-----布雷算法設計</p><p> (1) 掃雷游戲是由很多相同大小的格子組成的,一般計算機中自帶的游戲格子規(guī)格為9*9,16*15和30*16(第一個數(shù)字代表函
77、數(shù),第二個數(shù)字代表列數(shù))。規(guī)格不同,需要埋的地雷數(shù)目就 不同,這就會涉及到隨機埋雷算法,最簡單的是一下兩種函數(shù)的結合:</p><p> void srand(unsigned int seed);//seed為隨機種子</p><p> 一般這樣使用該函數(shù):</p><p> srand((unsigned) time(NULL));//即利用系統(tǒng)時間作為隨
78、機種子,因為系統(tǒng)內置的時鐘是在時刻變化的。</p><p> 然后使用如下函數(shù)產生隨機數(shù):</p><p> int rand(void)//可嘗試(0,RAND_MAX)之間的隨機整數(shù),RAND_MAX為十六進制的0X7fff可進行一些算術運算,使之產生所需要的任意隨機數(shù)。</p><p> (2) 掃雷游戲還要求在沒有雷的地方被點擊后就會顯示一個數(shù)字表示它
79、周圍有幾個雷,這里分析實現(xiàn)這個功能的算法。把整個游戲區(qū)看成一個二維數(shù)組</p><p> minefield[i][j]:</p><p> 要知道m(xù)inefield[2][6]周圍有幾個雷,只要去檢測如下8個網格是否有雷即可。</p><p> minefield[1][5],minefield[1][6],minefield[1][[7]</p>
80、;<p> minefield[2][5],minefield[2][7]</p><p> minefield[3][5],minefield[3][6],minefield[3][7]</p><p> 將上面的8個網格的位置關系與minefield[2][6]進行比較,不難發(fā)現(xiàn)它們之間存在一定的數(shù)學關系,抽象看來就是:minefield[i][j]周圍雷的個數(shù)是由
81、如下8個位置處的雷的總合決定的。</p><p> minefield[i-1][j-1],minefield[i-1][j],minefield[i-1][[j+1]</p><p> minefield[i][j-1],minefield[i][j+1]</p><p> minefield[i+1][j-1],minefield[i+1][j],mine
82、field[i+1][j+1]</p><p> 上面幾個位置可能超出了邊界,因此需要根據(jù)實際情況給變量i與j設置范圍。</p><p> 根據(jù)以上的分析,設計布雷算法的代碼,添加BuLei()函數(shù)用于隨機布雷。</p><p> void BuLei()//隨機布雷</p><p><b> {</b><
83、/p><p> int k1,k2; </p><p> srand( (unsigned)time( NULL ) ); </p><p> for(int i=0;i<m_Num;i++)</p><p><b> { </b></p><p> k1=rand()%row;&
84、lt;/p><p> k2=rand()%col;</p><p> if(m_NodeList[k1][k2].m_Type!=ncLEI)</p><p><b> {</b></p><p> m_NodeList[k1][k2].m_Type=ncLEI;</p><p><b&
85、gt; }</b></p><p><b> else</b></p><p><b> {</b></p><p><b> i--;</b></p><p><b> continue;</b></p><p&
86、gt;<b> }</b></p><p> if(((k1-1>=0)&&(k2-1>=0))&&(m_NodeList[k1-1][k2-1].m_Type!=ncLEI))//左上方</p><p><b> {</b></p><p> m_NodeList[k1
87、-1][k2-1].m_Type=ncNUMBER;</p><p> m_NodeList[k1-1][k2-1].m_Around+=1;</p><p><b> }</b></p><p> if((k1-1>=0)&&m_NodeList[k1-1][k2].m_Type!=ncLEI)//上方</p
88、><p><b> {</b></p><p> m_NodeList[k1-1][k2].m_Type=ncNUMBER;</p><p> m_NodeList[k1-1][k2].m_Around+=1;</p><p><b> }</b></p><p> i
89、f(((k1-1>=0)&&(k2+1<col))&&m_NodeList[k1-1][k2+1].m_Type!=ncLEI)//右上方</p><p><b> {</b></p><p> m_NodeList[k1-1][k2+1].m_Type=ncNUMBER;</p><p> m
90、_NodeList[k1-1][k2+1].m_Around+=1;</p><p><b> }</b></p><p> if((k2-1>=0)&&m_NodeList[k1][k2-1].m_Type!=ncLEI)//左方</p><p><b> {</b></p>&
91、lt;p> m_NodeList[k1][k2-1].m_Type=ncNUMBER;</p><p> m_NodeList[k1][k2-1].m_Around+=1;</p><p><b> }</b></p><p> if((k2+1<col)&&m_NodeList[k1][k2+1].m_Ty
92、pe!=ncLEI)//右方</p><p><b> {</b></p><p> m_NodeList[k1][k2+1].m_Type=ncNUMBER;</p><p> m_NodeList[k1][k2+1].m_Around+=1;</p><p><b> }</b><
93、/p><p> if(((k1+1<row)&&(k2-1>=0))&&m_NodeList[k1+1][k2-1].m_Type!=ncLEI)//左下方</p><p><b> {</b></p><p> m_NodeList[k1+1][k2-1].m_Type=ncNUMBER;<
94、/p><p> m_NodeList[k1+1][k2-1].m_Around+=1;</p><p><b> }</b></p><p> if((k1+1<row)&&m_NodeList[k1+1][k2].m_Type!=ncLEI)//下方</p><p><b> {&l
95、t;/b></p><p> m_NodeList[k1+1][k2].m_Type=ncNUMBER;</p><p> m_NodeList[k1+1][k2].m_Around+=1;</p><p><b> }</b></p><p> if(((k1+1<row)&&(k2
96、+1<col))&&m_NodeList[k1+1][k2+1].m_Type!=ncLEI)//右下方</p><p><b> {</b></p><p> m_NodeList[k1+1][k2+1].m_Type=ncNUMBER;</p><p> m_NodeList[k1+1][k2+1].m_Arou
97、nd+=1;</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p> 當然,還得添加繪圖代碼用來在游戲區(qū)域顯示隨機布置的雷和周邊情況,在OnPaint函數(shù)中添加如下代碼:</p>
98、<p> void OnPaint()</p><p><b> {</b></p><p> for(int i=0;i<row;i++)</p><p> for(int j=0;j<col;j++)</p><p><b> {</b></p>&
99、lt;p> if(m_NodeList[i][j].m_Type==ncLEI)</p><p><b> {</b></p><p> memdc.SelectObject(&bmp1);</p><p> pDC->BitBlt(m_NodeList[i][j].m_Point.x-cx/2,m_NodeList
100、[i][j].m_Point.</p><p> y-cy/2,20,20,&memdc,0,0,SRCCOPY);</p><p><b> }</b></p><p><b> else</b></p><p><b> {</b></p>&
101、lt;p> if(m_NodeList[i][j].m_Around==1)</p><p><b> {</b></p><p> memdc.SelectObject(&bmp_1); pDC->BitBlt(m_NodeList[i][j].m_Point.x-cx/2,m_NodeList[i][
102、j].</p><p> m_Point.y-cy/2,20,20,&memdc,0,0,SRCCOPY);</p><p><b> }</b></p><p> else if(m_NodeList[i][j].m_Around==2)</p><p><b> {</b><
103、;/p><p> memdc.SelectObject(&bmp_2); pDC->BitBlt(m_NodeList[i][j].m_Point.x-cx/2,m_NodeList[i][j].</p><p> m_Point.y-cy/2,20,20,&memdc,0,0,SRCCOPY);</p><p>
104、;<b> }</b></p><p> else if(m_NodeList[i][j].m_Around==3)</p><p><b> {</b></p><p> memdc.SelectObject(&bmp_3); pDC->BitBlt(m_
105、NodeList[i][j].m_Point.x-cx/2,m_NodeList[i][j].</p><p> m_Point.y-cy/2,20,20,&memdc,0,0,SRCCOPY);</p><p><b> }</b></p><p> else if(m_NodeList[i][j].m_Around==4)&l
106、t;/p><p><b> {</b></p><p> memdc.SelectObject(&bmp_4); pDC->BitBlt(m_NodeList[i][j].m_Point.x-cx/2,m_NodeList[i][j].</p><p> m_Point.y-cy/2,20,
107、20,&memdc,0,0,SRCCOPY);</p><p><b> }</b></p><p> else if(m_NodeList[i][j].m_Around==5)</p><p><b> {</b></p><p> memdc.SelectObject(&
108、bmp_5); pDC->BitBlt(m_NodeList[i][j].m_Point.x-cx/2,m_NodeList[i][j].</p><p> m_Point.y-cy/2,20,20,&memdc,0,0,SRCCOPY);</p><p><b> }</b></p><p&
109、gt; else if(m_NodeList[i][j].m_Around==6)</p><p><b> {</b></p><p> memdc.SelectObject(&bmp_6); pDC->BitBlt(m_NodeList[i][j].m_Point.x-cx/2,m_NodeList[i][
110、j].</p><p> m_Point.y-cy/2,20,20,&memdc,0,0,SRCCOPY);</p><p><b> }</b></p><p> else if(m_NodeList[i][j].m_Around==7)</p><p><b> {</b><
111、;/p><p> memdc.SelectObject(&bmp_7); pDC->BitBlt(m_NodeList[i][j].m_Point.x-cx/2,m_NodeList[i][j].</p><p> m_Point.y-cy/2,20,20,&memdc,0,0,SRCCOPY);</p><p
112、><b> }</b></p><p> else if(m_NodeList[i][j].m_Around==8)</p><p><b> {</b></p><p> memdc.SelectObject(&bmp_8); pDC->BitBlt(m_
113、NodeList[i][j].m_Point.x-cx/2,m_NodeList[i][j].</p><p> m_Point.y-cy/2,20,20,&memdc,0,0,SRCCOPY);</p><p><b> }</b></p><p><b> }</b></p><p&g
114、t;<b> }</b></p><p><b> }</b></p><p> 隨機布雷效果比較如下:</p><p><b> 第一次運行:</b></p><p><b> 第二次運行:</b></p><p>
115、如上看來,隨機布雷成功。</p><p> 3.3 掃雷鼠標事件的處理</p><p> (1) 首先,設計雷區(qū)和非雷區(qū)的判斷算法。掃雷時需要判斷每個格子的狀態(tài),可事先為格子設定一些狀態(tài),使之對應不同的BOOL值或整數(shù)值。在二維、三維游戲里,有一種簡單的構造地圖的方法,即將地圖劃分為m*n的規(guī)格格子,使每一個格子對應二維數(shù)組中的一項,當鼠標單擊時,通過找出鼠標點擊區(qū)域,找到相應的格子,
116、判斷格子狀態(tài)來替換相應的位圖。 </p><p> 具體算法思想如下: </p><p> 在應用程序的客戶區(qū)劃分一塊區(qū)域,將該區(qū)域劃分為n*m相同大小的格子;</p><p> 將每一個格子的狀態(tài)對應到二維數(shù)組的相應項上;</p><p> 當鼠標點擊某一塊區(qū)域時,首先判斷是否在各種區(qū)域,然后再通過鼠標的坐標找到相應的格子;
117、</p><p> 查詢格子的狀態(tài),從而調用相應的位圖進行位圖替換;</p><p> 說明:Windows的消息響應機制對于編寫一些小游戲是非常方便的,當編寫大型2D或3D游戲時,Windows API 就顯得有些不足,此時應使用DirectX或OpenGL等大型圖形庫來進行設計及編碼。</p><p> (2) 鼠標左鍵事件的處理。分兩種情況:</p
118、><p> 當相應區(qū)域不是雷區(qū)時,挖開區(qū)域,并且若能據(jù)此判斷周圍區(qū)域也不是雷區(qū)則將周圍相應區(qū)域也挖開;</p><p> 當區(qū)域是雷區(qū)時,則界面中所有的雷區(qū)同時“炸開“:第一步先顯示一個提示框,第二部當提示框關閉時,所有非雷區(qū)顯示出來。</p><p> 鼠標在笑臉圖片上,單擊可以重新開始。</p><p> (3) 對單擊鼠標右鍵事件處
119、理</p><p> 第一次用右鍵單擊某個區(qū)域時,改區(qū)域上插上一面小紅旗,此時單擊左鍵沒有任何變化,第二次用右鍵單擊時恢復原狀。</p><p> (4) 雙擊左鍵事件處理</p><p> 在展開的區(qū)域,并且已經確定了周圍的雷數(shù),雙擊可以疊加展開非雷區(qū)域,以減少用戶的單擊操作。</p><p> 基于以上的思想,在VC++ 6.0中
120、的核心編碼如下:</p><p> OnLButtonUp(UINT nFlags, CPoint point) </p><p><b> {</b></p><p> // TODO: Add your message handler code here and/or call default</p><p>
121、<b> int num;</b></p><p> OnLei(point);</p><p> OnNumber(point);</p><p> OnBlank(point);</p><p><b> num=0;</b></p><p> for(int
122、 a=0;a<row;a++)</p><p> for(int b=0;b<col;b++)</p><p><b> {</b></p><p> if(m_NodeList[a][b].m_IsUsed==FALSE)</p><p><b> num++;</b><
123、/p><p> if(m_Shengyu==0&&num>=row*col)</p><p><b> {</b></p><p><b> m_Face=2;</b></p><p> Invalidate();</p><p> Message
124、Box("你真聰明!!!","掃雷",</p><p> MB_ICONWARNING|MB_OKCANCEL);</p><p><b> }</b></p><p><b> }</b></p><p> CDialog::OnLButtonUp(
125、nFlags, point);</p><p><b> }</b></p><p> 其中的OnLei(),OnNumber(),OnBlank()函數(shù)分別如下:</p><p> void CShaoLeiDlg::OnLei(CPoint point)</p><p><b> {</b&g
126、t;</p><p> for (int i = 0 ;i<row;i++)</p><p> for (int j = 0; j<col;j++)</p><p><b> {</b></p><p> tmp = m_NodeList[i][j].m_Point;</p><p
127、> CRect rect(tmp.x-10,tmp.y-10,tmp.x+10,tmp.y+10);</p><p> if (rect.PtInRect(point))</p><p> { if(m_NodeList[i][j].m_IsUsed==TRUE&&m_NodeList[i][j].</p><p> m_I
128、sSign==FALSE)</p><p><b> {</b></p><p> if(m_NodeList[i][j].m_Type==ncLEI)</p><p><b> {</b></p><p> for (int m = 0 ;m<row;m++)</p>
129、<p> for (int n= 0; n<col;n++)</p><p><b> {</b></p><p> if(m_NodeList[m][n].m_Type==ncLEI)</p><p><b> {</b></p><p> m_NodeList[m][n
130、].m_IsUsed=FALSE;</p><p> m_NodeList[m][n].m_IsSign=FALSE;</p><p><b> }</b></p><p><b> else</b></p><p><b> {</b></p><
131、p> if(m_NodeList[m][n].m_IsUsed==TRUE)</p><p> m_NodeList[m][n].m_IsSign=TRUE; if(m_NodeList[m][n].m_IsUsed==FALSE&&</p><p> m_NodeLis
132、t[m][n].m_IsSign==TRUE)</p><p> m_NodeList[m][n].m_IsUsed=TRUE;</p><p><b> }</b></p><p><b> }</b></p><p><b> m_Face=1;</b></p
133、><p> Invalidate();</p><p><b> BaoZha();</b></p><p> MessageBox("你還差了點,不服重來!!!","掃雷",</p><p> MB_ICONWARNING|MB_OKCANCEL);</p>&
134、lt;p> } </p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p&g
135、t; void CShaoLeiDlg::OnNumber(CPoint point)</p><p><b> {</b></p><p> CPoint tmp; </p><p> for (int i = 0 ;i<row;i++)</p><p> for (int j = 0; j<c
136、ol;j++)</p><p><b> {</b></p><p> tmp = m_NodeList[i][j].m_Point;</p><p> CRect rect(tmp.x-10,tmp.y-10,tmp.x+10,tmp.y+10);</p><p> if (rect.PtInRect(po
137、int))</p><p><b> {</b></p><p> if(m_NodeList[i][j].m_IsUsed==TRUE&&</p><p> m_NodeList[i][j].m_IsSign==FALSE)</p><p><b> {</b></p
138、><p> if(m_NodeList[i][j].m_Type==ncNUMBER)</p><p><b> {</b></p><p> m_NodeList[i][j].m_IsUsed=FALSE;</p><p> m_NodeList[i][j].m_IsSign=FALSE;</p>&
139、lt;p> Invalidate();</p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><b> }</b></p><p><
140、b> }</b></p><p> void CShaoLeiDlg::OnBlank(CPoint point)</p><p><b> {</b></p><p> CPoint tmp;</p><p> for (int i = 0 ;i<row;i++)</p>
141、<p> for (int j = 0; j<col;j++)</p><p><b> {</b></p><p> tmp = m_NodeList[i][j].m_Point;</p><p> CRect rect(tmp.x-10,tmp.y-10,tmp.x+10,tmp.y+10);</p>
142、;<p> if (rect.PtInRect(point))</p><p><b> {</b></p><p> if(m_NodeList[i][j].m_IsUsed==TRUE&&</p><p> m_NodeList[i][j].m_IsSign==FALSE)</p><
143、;p><b> {</b></p><p> if(m_NodeList[i][j].m_Type==ncBLANK)</p><p><b> {</b></p><p> m_NodeList[i][j].m_IsUsed=FALSE;</p><p> if((i-1>=
144、0)&&(j-1>=0))</p><p><b> {</b></p><p> m_NodeList[i-1][j-1].m_IsUsed=FALSE;</p><p> if(m_NodeList[i-1][j-1].m_Type==ncBLANK)</p><p><b>
145、 {</b></p><p> if((i-1-1>=0)&&(j-1-1>=0)&&</p><p> m_NodeList[i-1-1][j-1-1].m_Type!=ncLEI)</p><p> m_NodeList[i-1-1][j-1-1].m_IsUsed=FALSE;
146、 if((j-1-1>=0)&&m_NodeList[i-1][j-1-1].m_Type!=ncLEI)</p><p> m_NodeList[i-1][j-1-1].m_IsUsed=FALSE; if((i-1-1>=0)&&m_NodeList[i-1-1][j-1].m_Type!
147、=ncLEI)</p><p><b> {</b></p><p> m_NodeList[i-1-1][j-1].m_IsUsed=FALSE;</p><p><b> }</b></p><p> if((i-1-1>=0)&&m_NodeList[i-1-1]
148、[j].m_Type!=ncLEI)</p><p><b> {</b></p><p> m_NodeList[i-1-1][j].m_IsUsed=FALSE; </p><p><b> }</b></p><p><b> }</b></p>
149、<p><b> }</b></p><p> if((i-1>=0))</p><p> m_NodeList[i-1][j].m_IsUsed=FALSE;</p><p> if((i-1>=0)&&(j+1<col))</p><p><b> {
150、</b></p><p> m_NodeList[i-1][j+1].m_IsUsed=FALSE;</p><p> if(m_NodeList[i-1][j+1].m_Type==ncBLANK)</p><p><b> {</b></p><p> if((i-1-1>=
151、0)&&m_NodeList[i-1-1][j+1].m_Type!=ncLEI)</p><p> m_NodeList[i-1-1][j+1].m_IsUsed=FALSE; if((i-1-1>=0)&&(j+1+1<col)&&</p><p> m_NodeList[i-1
152、-1][j+1+1].m_Type!=ncLEI)</p><p> m_NodeList[i-1-1][j+1+1].m_IsUsed=FALSE; if((j+1+1<col)&&m_NodeList[i-1][j+1+1].m_Type!=ncLEI)</p><p><b> {</b></p>
153、<p> m_NodeList[i-1][j+1+1].m_IsUsed=FALSE;</p><p> }if((j+1+1<col)&&m_NodeList[i][j+1+1].m_Type!=ncLEI)</p><p><b> {</b></p><p> m_NodeLis
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫僅提供信息存儲空間,僅對用戶上傳內容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
評論
0/150
提交評論