




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
目錄第1章 引言 31.1 課題背景及意義 31.2 關(guān)于本課題 3第2章 開發(fā)環(huán)境及相關(guān)技術(shù)的介紹 42.1 開發(fā)環(huán)境 42.2 C#的由來 42.3 C#的特點 4 簡潔易用的語法 4 自動的資源回收機制 5 與WEB的緊密結(jié)合 5 完整的平安性與錯誤處理 5 支持跨平臺 5 與XML的融合 62.4 .NET開發(fā)平臺 6第3章 需求分析 63.1 可行性分析 6 目的 6 經(jīng)濟可行性 7 技術(shù)可行性 73.2 界面分析 7 主界面分析 7 界面美化分析 83.3 運行過程分析 8第4章 概要設(shè)計 84.1 功能性設(shè)計 84.2 流程設(shè)計 10第5章 詳細設(shè)計 125.1 主窗體的構(gòu)建 12 掃雷游戲工程的構(gòu)建 12 自動適應(yīng)屏幕的界面 12 自動適應(yīng)窗體的控件 135.2 雷區(qū)的設(shè)置 14 雷區(qū)的生成 14 第一次點擊雷塊的處理 15 提示數(shù)字顏色設(shè)定 165.3 游戲難度設(shè)置 165.4 文件的讀取 18 開局時的文件讀取 18 對數(shù)據(jù)的處理 195.5 事件的處理 20 鼠標左鍵按下相應(yīng) 20 鼠標右鍵按下相應(yīng) 21 鼠標中鍵或左右鍵同時按下相應(yīng) 225.6 遞歸算法 23 遞歸算法簡介 23 游戲中的遞歸算法 235.7 文件的加密及解密 25 文件的解密 25 文件的加密 275.8 自定義控件的創(chuàng)立及使用 27 自定義控件的定義及使用 27 自定義外觀的菜單 28 第三方控件的使用 29第6章 測試與運行 316.1 游戲的測試 316.2 游戲的運行 326.3 游戲的部署及安裝 32第7章 設(shè)計與總結(jié) 33第8章 致謝 33第9章 參考文獻 34
引言課題背景及意義當前隨著計算機的深入普及,越來越多的人有了個人電腦,人們運用計算機完成許多重要的工作,計算機在人們的日常生活中扮演著越來越重要的角色。隨著計算機的廣泛應(yīng)用和深入開展,當前的計算機應(yīng)用早已不單局限于工作,計算機的娛樂性越來越得到人們的關(guān)注,近年來游戲產(chǎn)業(yè)規(guī)模飛速成長。權(quán)威市場調(diào)研機構(gòu)國際數(shù)據(jù)集團(DFCIntelligence)日前發(fā)表報告顯示,在2012年全球游戲市場的產(chǎn)值到達了600.4億美元,并預(yù)測2013年將到達649億美元,更會在2015年突破700億美元大關(guān)。這遠遠超越好萊塢電影產(chǎn)業(yè)以及音樂等娛樂事業(yè),而成為目前娛樂事業(yè)的最大主流。目前整個游戲產(chǎn)業(yè)的運作模式已經(jīng)跟好萊塢電影產(chǎn)業(yè)的運作模式非常相近,電影產(chǎn)業(yè)有制片、發(fā)行、宣傳等明細分工,游戲產(chǎn)業(yè)亦同,由專業(yè)的游戲研發(fā)小組負責(zé)研發(fā)游戲,也有如微軟、Steam這類國際級經(jīng)銷商負責(zé)游戲發(fā)行,甚至連“游戲制作人”也被培養(yǎng)成明星一樣成為一種招牌,如任天堂有王牌制作人宮本茂、SEGA有鈴木裕、KONAMI有小島秀夫、CAPCOM有三上真司,明確的游戲產(chǎn)業(yè)分工確實有助于游戲產(chǎn)業(yè)的規(guī)模開展與進化,但也無形中讓游戲開發(fā)本錢大增。為了降低游戲開發(fā)本錢,開發(fā)娛樂性強本錢低的游戲就成為當前的主要課題,在這種趨勢下各種小型的低本錢的游戲軟件應(yīng)運而生。在這其中,系統(tǒng)自帶的小游戲也占據(jù)了相當重要的地位,與那些網(wǎng)絡(luò)游戲和3D游戲相比,它有編寫簡單、容易上手等特點,可以滿足人們在完成日常工作之余適當娛樂的需求。這些小游戲大都是以益智和娛樂為目的,不僅給緊張工作的人們以放松,還可以讓人們的大腦得到開發(fā)。微軟公司的Windows系列操作系統(tǒng)中內(nèi)置了很多非常經(jīng)典的小游戲,包括掃雷,彈球,紙牌等等。關(guān)于本課題本次課題研究的是微軟公司的操作系統(tǒng)Windows中的掃雷游戲。掃雷游戲是Windows操作系統(tǒng)下的一款經(jīng)典游戲,在過去的數(shù)年里,windows操作系統(tǒng)歷經(jīng)數(shù)次換代更新,變的越來越龐大、復(fù)雜,功能也越來越強大,但是這款小游戲依然存活了下來,可見這款小游戲的經(jīng)典。掃雷游戲的規(guī)那么簡單,目標是在最短的時間內(nèi)根據(jù)點擊格子出現(xiàn)的數(shù)字找出所有非雷格子,同時防止踩雷。掃雷游戲具有上手容易、耐玩性高、玩家廣泛等特點,基于這些原因,我決定將掃雷游戲作為我的研究課題。開發(fā)環(huán)境及相關(guān)技術(shù)的介紹開發(fā)環(huán)境操作系統(tǒng):MicrosoftWindows7程序語言:C#.NET框架版本:.NETFramework4.0集成開發(fā)環(huán)境:MicrosoftVisualStudio2010C#的由來在過去的一段時間中C和C++一直是商業(yè)軟件的開發(fā)領(lǐng)域中最具生命力的語言。雖然他們?yōu)槌绦騿T提供了豐富的功能,高度的靈活性和強大的底層控制力,但是利用C、C++語言開發(fā)的Windows應(yīng)用程序顯然復(fù)雜了很多,同時也犧牲了一定的效率。與VB相比同等級的C、C++完成一個程序往往需要更多的時間來完成開發(fā),因此各層人士都試圖尋找一種新的語言,希望能在功能和功率之間找到一種更為理想的平衡點。針對這一問題微軟公司于2000年6月26日正式發(fā)布C#。C#是一種最新的、面向?qū)ο蟮木幊陶Z言。C#使得程序員可以在Miscrsoft開發(fā)的.NET平臺上快速的編寫應(yīng)用程序。C#是一種簡單、現(xiàn)代、面向?qū)ο笄翌愋推桨驳木幊陶Z言。C#語言從C和C++語言演化而來,同時C#具備了應(yīng)用程序快速開發(fā)RapidApplicationDevelopment〔RAD〕語言的高效率和C++固有的強大能力并吸收了Java和Delphi等語言的特點和精華,是.NET開發(fā)的首選語言。C#的特點簡潔易用的語法C#主要從C和C++繼承而來,同時吸收Java和Delphi的優(yōu)點。C#摒棄了C和C++中一些比擬復(fù)雜而且不常用的語法元素。C和C++中的指針雖然功能強大但極不平安稍不小心就會導(dǎo)致程序出錯甚至導(dǎo)致系統(tǒng)奔潰。C#取消了指針,不允許直接對內(nèi)存進行操作,讓代碼運行在平安的環(huán)境中。此外C#語法的很多變化無不表達了C#的簡潔之美。自動的資源回收機制C#與.NET的完美集成使得C#完全擁有.NET的自動回收機制。在windows中提供應(yīng)程序使用的一切軟、硬件統(tǒng)稱為資源。比方程序中需要在窗口上畫圖的筆就是一種資源在早期的windows版本中程序使用完資源后應(yīng)該及時解放否那么會導(dǎo)致系統(tǒng)資源缺乏而運行變慢。在.NET框架中由于資源使用完后由系統(tǒng)自動清理所以編寫C#程序不必小心翼翼地保證及時釋放資源從而可以把更多的精力放在程序編寫的邏輯上。與WEB的緊密結(jié)合網(wǎng)上辦公和電子商務(wù)在各行各業(yè)中的到越來越廣泛的的應(yīng)用,B/S模式程序的市場需求越來越多。在微軟的.NET開發(fā)套件中C#與ASP.NET是相互融合的。ASP.NET的應(yīng)用程序可以使用VB.NET語法也可以使用C#語法。使用C#語法編寫的ASP.NET結(jié)構(gòu)更嚴謹,運行更高效。由于有了WEB效勞框架的幫助對程序員來說網(wǎng)絡(luò)效勞看起來就像是C#的本地對象。程序員們能夠利用他們掌握的面向?qū)ο蟮闹R和技巧開發(fā)WEB效勞。僅需要使用簡單的C#語言結(jié)構(gòu)以及C#組件就能夠方便的開發(fā)WEB效勞,并允許它們通過Internet被運行在任何操作系統(tǒng)上的任何語言所調(diào)用。完整的平安性與錯誤處理語言的平安性與錯誤處理能力是衡量一種語言是否優(yōu)秀的重要依據(jù)。任何人都會犯錯即使是最熟練的程序員也不例外,如忘記變量的初始化,對不屬于自己管理范圍內(nèi)存的空間進行修改等。這些錯誤常常產(chǎn)生難以預(yù)計的后果。一旦這樣的軟件被投入使用,尋找與改正這些簡單錯誤的代價是讓人無法估計的。C#的先進設(shè)計思想可以消除軟件開發(fā)中的許多常見錯誤,并且提供了包括類型平安在內(nèi)的完整的平安性能支持。為減少開發(fā)中的錯誤,C#幫助開發(fā)者通過更少的代碼來完成相同的功能,這大大減輕了編程人員的工作量,同時更有效的防止了錯誤的產(chǎn)生。支持跨平臺隨著互聯(lián)網(wǎng)應(yīng)用程序的應(yīng)用范圍越來越廣,人們逐漸意識到,當前的網(wǎng)絡(luò)系統(tǒng)錯綜復(fù)雜,用戶使用的硬件設(shè)備和軟件系統(tǒng)各不相同。開發(fā)人員所設(shè)計的應(yīng)用程序必須具有強大的跨平臺性。C#編寫的應(yīng)用程序就具備這種能力,這種跨平臺性也包括了C#程序的客戶端可以運行在不同類型的客戶端上比方等非PC裝置上。與XML的融合由于XML技術(shù)真正融入到了.NET和C#之中,C#的編程變成了真正意義的網(wǎng)絡(luò)編程。甚至可以說.NET和C#是專為XML而設(shè)計。使用C#的程序員可以輕松用C#內(nèi)含的類來使用XML技術(shù)。就這方面而言目前C#提供應(yīng)了程序員更多的自由和更好的性能來使用XML。.NET開發(fā)平臺.NET是一個用于建立應(yīng)用程序的平臺,它在內(nèi)部封裝了大量的功能強大的應(yīng)用程序接口函數(shù)〔API〕,利用這些函數(shù)可以開發(fā)各類Windows應(yīng)用軟件。.NET還是一個開發(fā)平臺,它向廣闊的程序員提供了功能強大的集成開發(fā)環(huán)境〔IDE〕——VisualStudio。在未來.NET還是一個運行、發(fā)布應(yīng)用程序的平臺,它可以將應(yīng)用程序作為一種效勞通過Internet提供應(yīng)分布在世界各個角落的網(wǎng)絡(luò)用戶。.NET平臺對早期的開發(fā)平臺作了重大改良。其提供了一種全新的軟件開發(fā)模型,它允許用不同程序設(shè)計語言創(chuàng)立的應(yīng)用程序之間相互通信。這個平臺也允許開發(fā)者創(chuàng)立基于Web的應(yīng)用程序,這些應(yīng)用程序能夠發(fā)布到多種不同的設(shè)備甚至是無線和臺式機上。Microsoft的.NET方案為利用Internet和Web進行軟件的開發(fā)、設(shè)計和使用開辟了廣闊的新前景。.NET策略的一個主要方面是它與具體的語言或平臺無關(guān)。它并不要求程序員使用惟一的一種程序設(shè)計語言。程序員可以將多種與.NET兼容的語言結(jié)合起來開發(fā).NET應(yīng)用程序。多個程序員可以共同參與同一個軟件工程得開發(fā),每個人可以使用自己最精通的.NET語言如VisualC#.NET、C++.NET、VisualBasic.NET以及其他許多語言來完成工程的開發(fā)。需求分析可行性分析目的可行性研究的目的是用最小的代價在盡可能短的時間內(nèi)確定問題是否能夠解決。也就是說可行性研究的目的不是解決問題,而是確定問題是否值得去解決,可行性分析研究的是在當前的具體條件下,是否具備必要的資源和其它條件。本課題中,從經(jīng)濟可行性、技術(shù)可行性方面進行研究。經(jīng)濟可行性當前游戲市場,各種類型的游戲軟件層出不窮。由于游戲的開發(fā)本錢巨大,游戲的開發(fā)往往具有一定的風(fēng)險性,但是一些小游戲的開發(fā)具有本錢小,編寫簡單的優(yōu)勢,所以這些小游戲在游戲開發(fā)中也占有一席之地。在這類小游戲中包括益智類游戲,它以畫面精美、游戲方法簡單等特點得到大家的認可,成為人們在工作之余不可或缺的好伙伴。我的研究課題是掃雷游戲,這款小游戲具有投入本錢小,開發(fā)風(fēng)險性小等特點。從經(jīng)濟可行性角度考慮是可行的。技術(shù)可行性這款游戲使用C#語言進行編寫,C#是一種高效的編程語言,可以快速開發(fā)出用戶需求的產(chǎn)品。其.NETFramework平臺為開發(fā)者提供了龐大的類庫,開發(fā)人員只需要通過相應(yīng)的接口調(diào)用需求的方法就可以實現(xiàn)應(yīng)用程序的快速開發(fā)。這款游戲的定位是單機模式,使用WinForm技術(shù)進行開發(fā)即可。游戲中的主要功能均可由C#中提供的方法來實現(xiàn)。經(jīng)上所述,技術(shù)可行性可以實現(xiàn)。界面分析主界面分析該游戲的主窗體根據(jù)用戶顯示器分辨率的大小進行動態(tài)的調(diào)整,確保游戲的界面大小不由顯示器分辨率大小的改變而改變。游戲窗體居中設(shè)置,以占屏幕80%為宜。主窗體中以游戲界面居中,時間計時器以及剩余地雷個數(shù)計時器顯示在主窗體底部,而各種游戲設(shè)定選項設(shè)置在菜單中即可。游戲可以進行難度的設(shè)置,分為初、中、高,共三個難度等級,每個等級都對應(yīng)著不同的排行榜,玩家的優(yōu)異游戲戰(zhàn)績將記錄在排行榜內(nèi)。游戲也應(yīng)該提供游戲界面更換的控制,如更改游戲背景色以及其它顏色等。界面美化分析游戲應(yīng)該充分考慮到美觀性,可以通過游戲窗體界面的改變以及適宜的游戲素材的添加來實現(xiàn)。對于窗體界面的改變,這里可以嘗試對C#中自帶的控件進行重定義,在繼承了原控件的根底屬性之上進行更為美觀的修改,如對按鈕控件進行重定義,設(shè)置為長寬相等的正方形,并且允許定義地雷方塊的顏色等。也可以對游戲的菜單進行重繪,采用自繪制圖形覆蓋Windows系統(tǒng)自帶的菜單,到達美化界面的效果。游戲中需要用到很多圖片素材以及聲音素材,圖片素材如地雷、計時用的時鐘、各種窗體圖標等,聲音素材如開始聲音、地雷爆炸聲音、點擊雷塊聲音等,這些素材可以考慮從素材網(wǎng)站進行下載。運行過程分析游戲開始時,程序?qū)诶讌^(qū)中布上相應(yīng)難度的雷數(shù),雷數(shù)將在右下角的剩余地雷個數(shù)框中顯示。布雷完畢后,玩家可以開始進行游戲,在點擊按鈕時,雷區(qū)的按鈕上可能會出現(xiàn)數(shù)字,也有可能出現(xiàn)空白區(qū),其中數(shù)字代表以該按鈕為中心,周圍八個按鈕的雷數(shù),空白區(qū)代表其周圍八個按鈕中沒有地雷。玩家可以根據(jù)周圍的信息,來判斷哪個按鈕可能是雷,并在其上面打上標識。當玩家將所有的地雷都找出來的時候,而且非雷的按鈕都翻開了,此時游戲獲勝。玩家在點擊按鈕的時候,其不同的鼠標點擊對應(yīng)相應(yīng)的功能,有鼠標左鍵點擊事件,鼠標右鍵點擊事件以及鼠標滾輪鍵點擊事件,其中鼠標滾輪鍵點擊事件也可用左右鍵同時按下來執(zhí)行。概要設(shè)計功能性設(shè)計游戲應(yīng)該提供的功能大致有:難度選擇功能、計時功能、記錄游戲信息功能、排行榜功能、更換界面功能等。此游戲仿照微軟公司W(wǎng)indows操作系統(tǒng)中的掃雷游戲,提供三種標準游戲難度,其中:初級:81個方塊、10個地雷。中級:256個方塊、40個地雷。高級:480個方塊、99個地雷。布雷方式為隨機布雷,但出于游戲的友好性考慮,要保證玩家點擊的第一個方塊不能是地雷。當玩家點擊到有地雷的方塊后,游戲結(jié)束,并且顯示當前游戲中的地雷位置。假設(shè)開始進行下局游戲,那么需要對地雷進行重新布置。假設(shè)玩家探測到了所有地雷,那么游戲勝利,彈出游戲勝利對話框。游戲勝利后,玩家的當局游戲信息將被記錄,玩家可以查看自己的游戲信息,如游戲場數(shù),勝率,最正確戰(zhàn)績等。當然,玩家不單可以查看自己的戰(zhàn)績,更可以查看該游戲的戰(zhàn)績總排行,這將在另一個窗口中進行顯示。游戲信息的記錄以及各種數(shù)據(jù)的統(tǒng)計,會大大增加游戲的耐玩性。由于本游戲采用的數(shù)據(jù)讀寫處理采用文件讀取方式,有必要對游戲數(shù)據(jù)進行充分的加密處理,在程序翻開時,將讀取被加密的數(shù)據(jù)文件并對該文件進行解密操作,將解密的數(shù)據(jù)按照固定的算法讀入內(nèi)存,當游戲結(jié)束后,要將內(nèi)存中的數(shù)據(jù)進行加密然后保存到文件中。本設(shè)計的功能模塊如下:掃雷游戲掃雷游戲窗體類模塊鼠標中鍵鼠標右鍵鼠標左鍵聲音數(shù)據(jù)窗體加載鼠標雙擊函數(shù)遞歸函數(shù)重新開始函數(shù)畫圖函數(shù)音樂函數(shù)本設(shè)計的用例圖如下所示:流程設(shè)計本設(shè)計的主要流程是:游戲開始后用戶可以通過點擊鼠標的左鍵、右鍵、中鍵或者左右鍵同時按下進行游戲,當所有的地雷被探索,那么游戲勝利;假設(shè)用戶點擊了雷塊,那么游戲結(jié)束;假設(shè)用戶退出游戲,那么游戲結(jié)束。游戲的主流程圖如下:是是是開始初始化窗體等待按鍵左鍵鍵右鍵顯示方塊布置地圖啟動計時器游戲結(jié)束結(jié)束進行遞歸掃雷否否是是否是否第一次按下按下方塊是否為地雷是否再玩是否詳細設(shè)計主窗體的構(gòu)建掃雷游戲工程的構(gòu)建本課題采用微軟公司為.NET平臺開發(fā)量身定造的集成開發(fā)環(huán)境:VisualStudio2010進行游戲的開發(fā)。開發(fā)游戲的第一部和開發(fā)其他WinForm應(yīng)用一樣,要建立一個Windows窗體應(yīng)用程序,作為游戲的主窗體程序。創(chuàng)立過程如下列圖所示,工程名稱為“掃雷”,并為該工程創(chuàng)立新的解決方案以及新的目錄。自動適應(yīng)屏幕的界面創(chuàng)立游戲窗體之后,需要對窗體的大小進行設(shè)定,本游戲設(shè)定為,使游戲窗體自適應(yīng)用戶顯示器分辨率,即根據(jù)用戶顯示器分辨率的大小動態(tài)的進行窗體大小的設(shè)置。設(shè)置代碼如下所示。/**以下函數(shù)用于調(diào)整窗體,控件等的位置以及大小*/privatevoidsetGameFrameSize()//此函數(shù)用于設(shè)置游戲窗體適應(yīng)屏幕的大小{//獲取當前屏幕的像素點大小,并取其相應(yīng)的百分比進行游戲主窗體大小設(shè)定intsetHeight=*9/10;intsetWidth=*9/10;intsetStartX=/2-setWidth/2;intsetStartY=/2-setHeight/2;this.SetBounds(setStartX,setStartY,setWidth,setHeight);}自動適應(yīng)窗體的控件創(chuàng)立游戲窗體大小設(shè)定好之后,需要對窗體的各個控件的位置進行設(shè)定,如計時器控件、剩余地雷數(shù)量等控件的位置等。設(shè)置代碼如下所示。privatevoidsetControlAreaSize()//設(shè)置控制窗口的各個控件的位置{//獲取主窗體各個控件的大小并按照百分比進行窗體設(shè)定intwidth=;inticonWidth=;inttextWidth=;intcaculateLength=(width-2*iconWidth-2*textWidth)/3;//設(shè)置時鐘圖片的位置及大小clockPicture.SetBounds(caculateLength,0,clockPicture.Width,clockPicture.Height);//設(shè)置計時器空間的位置及大小timerCount.SetBounds(caculateLength+clockPicture.Width,0,timerCount.Width,timerCount.Height);//設(shè)置剩余雷塊數(shù)圖片的位置及大小bombPicture.SetBounds(2*caculateLength+clockPicture.Width+timerCount.Width,0,bombPicture.Width,bombPicture.Height);//設(shè)置記錄雷塊剩余個數(shù)的控件的位置及大小bombLast.SetBounds(width-caculateLength-bombLast.Width,0,bombLast.Width,bombLast.Height);}privateintcaculateBolckSize(introw,intcol)//將地雷塊調(diào)整為適宜的大小{ //獲取主窗體各個控件的大小并按照百分比進行窗體設(shè)定 intgameAreaHeight=gameArea.Height;intblockSize=gameAreaHeight*9/10/row;intgameAreaWidth=gameArea.Width;intblockSize2=gameAreaWidth*9/10/col; if(blockSize>blockSize2) {blockSize=blockSize2;}if(blockSize>40){blockSize=40;}returnblockSize;}在進行完窗體的設(shè)定之后,對游戲的窗體顏色進行一定的修改,即可有一個較為不錯的效果。下列圖是VisualStudio2010集成開發(fā)環(huán)境下的掃雷主窗體。雷區(qū)的設(shè)置雷區(qū)的生成當游戲界面初始化完成后,開始進行地雷的布置,當玩家點擊開始游戲按鈕后,在地雷區(qū)中隨機的布置當前游戲難度下應(yīng)該產(chǎn)生的地雷總數(shù)。雷塊實際是一個自定義的Button控件,該控件繼承了Button類,并且添加了雷塊所在位置等屬性信息,更改了自身形狀的大小等。如下代碼為生成掃雷游戲頁面,并為所有的雷塊添加各種事件處理函數(shù)。其中MouseMove事件與MouseLeave事件的添加作用是:在鼠標移動到某未點擊的雷塊時,該雷塊高亮顯示。當鼠標離開該雷塊時,高亮顯示效果消失。這種設(shè)計會得到更好的游戲體驗效果。相關(guān)代碼如下所示:privatevoidnewBlockCava(introw,intcol)//生成掃雷的游戲頁面{//將剩余雷數(shù)框的值初始化bombLast.Text=();//根據(jù)雷塊的大小以及屏幕的大小開始自定義位置布雷inttempBlockSize=caculateBolckSize(row,col);intstartPointX=gameArea.Width/2-tempBlockSize*col/2;intstartPointY=gameArea.Height/2-tempBlockSize*row/2;for(inti=0;i<row;i++)for(intj=0;j<col;j++){block[i,j]=newBlock();block[i,j].X=i;block[i,j].Y=j;block[i,j].IsBoomb=false;(block[i,j]);block[i,j].SetBounds(startPointX+j*tempBlockSize,startPointY+i*tempBlockSize,tempBlockSize,tempBlockSize);//為雷塊設(shè)置背景色block[i,j].BackColor=Color.Pink;//為雷塊添加各種響應(yīng)事件block[i,j].MouseUp+=newMouseEventHandler(bt_MouseUp);block[i,j].MouseDown+=newMouseEventHandler(bt_MouseDown);block[i,j].MouseMove+=newMouseEventHandler(bt_MouseMove);block[i,j].MouseLeave+=newEventHandler(bt_MouseLeave);}}第一次點擊雷塊的處理當游戲第一次點擊雷塊后,程序?qū)τ螒騾^(qū)域進行設(shè)置。即保證用戶點擊的雷塊以及其周圍的八個雷塊都沒有地雷,這樣用戶的第一次點擊一定不會遇到地雷,并且至少會翻開9個方塊。這樣降低了開局的難度,并且表達了游戲的友好性,增加了游戲的耐玩性。相關(guān)代碼如下所示:privatevoidsetBoomb(intx,inty)//設(shè)置地雷并且保證點到的第一個方塊和周圍的八個方塊不是地雷{timer1.Start();Randomrand=newRandom();intBoombNumber=Program.theMountOfBoomb;intcountBoombNumber=0;while(countBoombNumber!=BoombNumber){intpointX=rand.Next(Program.row);intpointY=rand.Next(Program.col);if(((block[pointX,pointY].IsBoomb==true)||(pointX==x&&pointY==y)||(pointX==x-1&&pointY==y-1)||(pointX==x-1&&pointY==y)||(pointX==x-1&&pointY==y+1)||(pointX==x&&pointY==y-1)||(pointX==x&&pointY==y+1)||(pointX==x+1&&pointY==y-1)||(pointX==x+1&&pointY==y)||(pointX==x+1&&pointY==y+1))==false){block[pointX,pointY].IsBoomb=true;countBoombNumber++;}}}第一次點擊雷塊效果如下所示:提示數(shù)字顏色設(shè)定難度設(shè)置通過用戶對難度控制對話框的設(shè)置來實現(xiàn),當用戶應(yīng)用了不同于當前游戲的難度之后,程序?qū)⒏鶕?jù)用戶選擇的難度設(shè)置指定個數(shù)的雷塊對游戲界面進行雷塊個數(shù)的改變以及地雷個數(shù)的重置。此處涉及到了不同窗體之間的傳值問題,本處的解決方案是:采用賦值給類內(nèi)靜態(tài)變量的形式實現(xiàn)。代碼中的變量theMountOfBoomb,row,cow等都是靜態(tài)變量。游戲難度設(shè)置難度設(shè)置通過用戶對難度控制對話框的設(shè)置來實現(xiàn),當用戶應(yīng)用了不同于當前游戲的難度之后,程序?qū)⒏鶕?jù)用戶選擇的難度設(shè)置指定個數(shù)的雷塊對游戲界面進行雷塊個數(shù)的改變以及地雷個數(shù)的重置。此處涉及到了不同窗體之間的傳值問題,本處的解決方案是:采用賦值給類內(nèi)靜態(tài)變量的形式實現(xiàn)。代碼中的變量theMountOfBoomb,row,cow等都是靜態(tài)變量。相關(guān)代碼如下所示:privatevoid更改難度ToolStripMenuItem_Click(objectsender,EventArgse)//更改難度對話框的實現(xiàn),根據(jù)更改后的難度值和原難度值的數(shù)值是否相等來判斷{intpreLevel=Program.curLevel;ChangeLevelcl=newChangeLevel();cl.ShowDialog();if(cl.DialogResult==DialogResult.OK){timer1.Stop();timerCount.Text="0";flag=1;}inttempLevel=Program.curLevel;if(preLevel!=tempLevel){if(tempLevel==1){();Program.row=9;Program.col=9;Program.theMountOfBoomb=10;Program.isGameOver=false;}elseif(tempLevel==2){();Program.row=16;Program.col=16;Program.theMountOfBoomb=40;Program.isGameOver=false;}elseif(tempLevel==3){();Program.row=16;Program.col=30;Program.theMountOfBoomb=99;Program.isGameOver=false;}newBlockCava(Program.row,Program.col);gameArea.Refresh();}}文件的讀取開局時的文件讀取游戲開局時,將從myScoreFile.dat文件中讀取數(shù)據(jù),該文件中存放的是被加密后的數(shù)據(jù),為了轉(zhuǎn)化為程序識別的數(shù)據(jù),需要對數(shù)據(jù)進行解密處理,encryption類是自定義的用于控制數(shù)據(jù)的加密以及解密的類,此類中提供了加密以及解密的方法。文件讀取代碼如下所示:privatevoidloadData(){/**在文件讀取前以及讀取后要求對文件進行加密以及解密*/for(inti=0;i<3;i++)for(intj=0;j<5;j++)/對數(shù)據(jù)進行初始化{Program.theInfo[i,j]=newtheScoreInfo();}if(File.Exists("myScoreFile.dat")){encryptionen=newencryption();en.JieMiWenJian("myScoreFile.dat");//設(shè)置新的文件流,用于讀取文件FileStreamfsMyfile=newFileStream("myScoreFile.dat",FileMode.OpenOrCreate,FileAccess.ReadWrite);timer1.Stop();//將文件中的數(shù)據(jù)讀入到掃雷游戲中StreamReadersrMyfile=newStreamReader(fsMyfile);(0,SeekOrigin.Begin);for(inti=0;i<3;i++){for(intj=0;j<5;j++)//將文件中的數(shù)據(jù)讀入游戲內(nèi)存中{if((Program.theInfo[i,j].DateNow=srMyfile.ReadLine())!=null){Program.theInfo[i,j].TimeCost=Convert.ToInt32(srMyfile.ReadLine());}else{Program.theInfo[i,j].DateNow="null";}}fsMyfile.Close();srMyfile.Close();en.JiaMiWenJian("myScoreFile.dat");}}}對數(shù)據(jù)的處理從文件中讀取的數(shù)據(jù)記錄了玩家的游戲信息,這些信息被結(jié)構(gòu)化的保存在了內(nèi)存中,當玩家進行游戲取得更佳的成績后,程序?qū)⒂孟鄳?yīng)的算法對這些信息進行更新。以下是數(shù)據(jù)更新的方法:privateintrankTheScoreList(intcostTime){DateTimetime=DateTime.Now;stringcurTime=time.ToString();intreturnNumber=0;inti=3;while(i>=0&&costTime<Program.theInfo[Program.curLevel-1,i].TimeCost){i--;}returnNumber=i+1;//數(shù)字是幾,就把幾上原來的數(shù)據(jù)轉(zhuǎn)移到中轉(zhuǎn)變量中〔假設(shè)是4那么取消〕,把新值覆蓋原來值//該數(shù)字加一,數(shù)字假設(shè)到4,那么直接覆蓋inttemp=returnNumber;inttempTimeCost;stringtempDateNow;if(temp==4){//直接賦值Program.theInfo[Program.curLevel-1,temp].TimeCost=Convert.ToInt32(timerCount.Text);Program.theInfo[Program.curLevel-1,temp].DateNow=curTime;}else{//將原數(shù)組的該值傳遞到臨時變量tempTimeCost=Program.theInfo[Program.curLevel-1,temp].TimeCost;tempDateNow=Program.theInfo[Program.curLevel-1,temp].DateNow;Program.theInfo[Program.curLevel-1,temp].TimeCost=Convert.ToInt32(timerCount.Text);Program.theInfo[Program.curLevel-1,temp].DateNow=curTime;inttempj=4;for(inttempi=0;tempi<3-temp;tempi++){Program.theInfo[Program.curLevel-1,tempj].TimeCost=Program.theInfo[Program.curLevel-1,tempj-1].TimeCost;Program.theInfo[Program.curLevel-1,tempj].DateNow=Program.theInfo[Program.curLevel-1,tempj-1].DateNow;tempj--;}Program.theInfo[Program.curLevel-1,temp+1].TimeCost=tempTimeCost;Program.theInfo[Program.curLevel-1,temp+1].DateNow=tempDateNow;}returnreturnNumber;}事件的處理鼠標左鍵按下相應(yīng)游戲的操作方面主要以鼠標為主,鼠標左鍵按下事件的主要作用是為了點擊用戶認為不是地雷的方塊,當鼠標左鍵點下后,點下的方塊將從為探測狀態(tài)轉(zhuǎn)化為已探測狀態(tài),并可能會連帶翻開周圍的方塊。具體代碼如下所示:privatevoidtheLeftButtonDown(intx,inty)//鼠標左鍵按下后產(chǎn)生的算法{if(Convert.ToInt16(block[x,y].Tag)==0&&Program.isGameOver==false)//如果該雷塊沒有翻開{//如果點擊的是第一個雷塊,那么應(yīng)保證其周圍8個不是雷,并且開始隨機布雷if(isFirstClick()==true){Program.tagForDialog=0;setBoomb(x,y);}if(block[x,y].IsBoomb==false){block[x,y].BackColor=Color.Wheat;block[x,y].Tag=1;intcount=countBoombAmountAround(x,y);if(count==0){block[x,y].Text="";}else{block[x,y].Text=countBoombAmountAround(x,y).ToString();//需要在此處添加設(shè)置數(shù)字顏色函數(shù)tagNumberOnTheBlock(x,y);}searchBomb(x,y);//不用包含游戲勝利方法,因為SearchBomb方法里面已經(jīng)包含}else{//顯示所有地雷,加載爆炸聲音等gameLose(x,y);}}}鼠標右鍵按下相應(yīng)鼠標右鍵按下事件主要有兩個作用,當用戶對為探測方塊第一次按下該時,該方塊上將出現(xiàn)一個五角星,如下圖,代表確認該方塊是地雷,假設(shè)對此方塊再次進行右鍵單擊,那么圖標變?yōu)橐粋€咖啡杯,如下圖,表示此處是否有地雷還有待商榷,對于一些比擬難解決的雷區(qū),使用該圖標有助于玩家更好的進行推理判斷。具體代碼如下所示:privatevoidtheRightButtonDown(intx,inty)//鼠標右鍵按下時產(chǎn)生的算法{if((int)block[x,y].Tag==0){if(block[x,y].FlagOnUnclickButton==0){block[x,y].FlagOnUnclickButton=1;inta=Convert.ToInt16(bombLast.Text);a--;bombLast.Text=a.ToString();if(a>=0){block[x,y].Image=Image.FromFile(select);}}elseif(block[x,y].FlagOnUnclickButton==1){block[x,y].FlagOnUnclickButton=2;inta=Convert.ToInt16(bombLast.Text);a++;bombLast.Text=a.ToString();block[x,y].Image=Image.FromFile(thinking);}elseif(block[x,y].FlagOnUnclickButton==2){block[x,y].FlagOnUnclickButton=0;block[x,y].Image=null;}}}鼠標中鍵或左右鍵同時按下相應(yīng)鼠標中鍵按下事件用于確定某已確定無雷的方塊周圍的未探測雷塊個數(shù),假設(shè)用戶點擊的某個方塊的方塊上的數(shù)字與其周圍已探測地雷的個數(shù)相同,那么該方塊周圍的未標記地雷的方塊都將自動翻開。鼠標中鍵按下不易操作,故在真實的游戲中玩家多用左右鍵同時按下來替換這一操作,熟練的掌握這一操作會對游戲速度產(chǎn)生質(zhì)的提升。privatevoidtheBothButtonDown(intx,inty,boolisDown)//兩個鍵都按下產(chǎn)生的事件{//首先確定一個矩形區(qū)域,然后通過循環(huán)來確定有幾個雷。intstartRow=(x==0)?0:x-1;intendRow=(x==Program.row-1)?Program.row-1:x+1;intstartCol=(y==0)?0:y-1;intendCol=(y==Program.col-1)?Program.col-1:y+1;for(inti=startRow;i<=endRow;i++){ for(intj=startCol;j<=endCol;j++) { if((int)block[i,j].Tag==0&&isDown==true&&block[i,j].FlagOnUnclickButton==0){ block[i,j].BackColor=Color.Wheat; } if((int)block[i,j].Tag==0&&isDown==false) { block[i,j].BackColor=Color.Pink;}}}}由于鼠標的左右鍵同時按下事件在C#中是不存在的,需要自己來完成對鼠標左右鍵同時按下事件的定義。鼠標左右鍵同時按下是不可能的,左右鍵的按下一定會存在時間的間隔,因此設(shè)置一個容差值即可,即認為當左右鍵在相應(yīng)的容差值范圍內(nèi)按下,那么認為左右鍵已經(jīng)同時按下。代碼如下所示://以下幾個變量用于控制左右鍵同時按下privatelongTicks;privatelongTicksDelay=500000L;privateMouseButtonsButton;if(Program.isGameOver==false){switch(e.Button){//此處的左右鍵同時按下算法采用最小時差計算方法,可以用于此處//但是此方法目前有一個Bug,導(dǎo)致點到可用方塊時無法先判斷是否雙擊,一律調(diào)用單擊方法//至于左右鍵同時點下問題:可以試試給else語句添加條件caseMouseButtons.Left:if(-Ticks<TicksDelay&&Button==MouseButtons.Right){if(block[x,y].BackColor==Color.Wheat){theMidButtonDown(x,y);}}//之所以flagOnClick值設(shè)為不等于1,是因為兩個鍵不可能同時松開,只能松開一個,而這已經(jīng)足夠判斷elseif(flagOnClick!=1){theLeftButtonDown(x,y);}break;caseMouseButtons.Right:if(-Ticks<TicksDelay&&Button==MouseButtons.Left){if(block[x,y].BackColor==Color.Wheat){theMidButtonDown(x,y);}}elseif(flagOnClick!=1){theRightButtonDown(x,y);}break;caseMouseButtons.Middle:theMidButtonDown(x,y);break;}Button=e.Button;Ticks=;}遞歸算法遞歸算法簡介這里先引入一個“遞歸”的概念,“遞歸”(Recursion)簡單的說,就是一個程序能被自己所定義的語句調(diào)用。遞歸在程序設(shè)計上是一種重要的數(shù)據(jù)結(jié)構(gòu)形態(tài),通過遞歸程序的編寫,在程序代碼上會變得相當簡潔,不過如果設(shè)計不當,會造成無窮循環(huán)或堆迭溢滿的情形,所以遞歸的程序中心必須含有if…then或SelectCase等設(shè)計,以終止遞歸執(zhí)行。游戲中的遞歸算法在游戲過程中,當游戲者按下非地雷方塊時,方塊會沿四周八個方向向外翻開非地雷的方塊。程序的執(zhí)行方面必須判斷:以按下方塊為中心,檢查周圍八個方塊是否為非地雷方塊,假設(shè)其中有一個方塊是非地雷方塊時,那么又以其為中心,向外檢查周圍八個方塊是否為非地雷方塊,如此反復(fù)的執(zhí)行即構(gòu)成遞歸的使用條件。前面已經(jīng)提到,遞歸必須設(shè)計終止的條件判斷,在本游戲的遞歸架構(gòu)中,當判斷方塊的內(nèi)容為數(shù)字時〔即在非地雷方塊周圍〕,即立即停止遞歸程序。代碼如下所示:privatevoidsearchBomb(intx,inty)//開始遞歸掃雷{//和判斷周圍地雷數(shù)量方法相同,也需要進行有效方塊矩形設(shè)定intstartRow=(x==0)?0:x-1;intendRow=(x==Program.row-1)?Program.row-1:x+1;intstartCol=(y==0)?0:y-1;intendCol=(y==Program.col-1)?Program.col-1:y+1;//如果掃到的方塊上面沒有地雷,那么以此塊開始進行遞歸查找intcountBomb=countBoombAmountAround(x,y);if(countBomb==0&&block[x,y].FlagOnUnclickButton!=1){//block[x,y].Enabled=false;block[x,y].BackColor=Color.Wheat;for(inti=startRow;i<=endRow;i++){if(Program.tagForDialog==1){break;}for(intj=startCol;j<=endCol;j++){if((!(i==x&&j==y))&&block[i,j].BackColor==Color.Pink&&Convert.ToInt16(block[i,j].Tag)==0&&Program.isGameOver==false){searchBomb(i,j);if(Program.tagForDialog==1){break;}}if(Convert.ToInt16(block[i,j].Tag)==0&&block[i,j].FlagOnUnclickButton!=1){//block[i,j].Enabled=false;block[i,j].BackColor=Color.Wheat;block[i,j].Tag=1;}if((tagNumberOnTheBlock(i,j))==true)//如果游戲勝利,那么跳出循環(huán),但是此循環(huán)是雙重for循環(huán),并非遞歸循環(huán)//此處調(diào)用是為了在遞歸過程中判斷游戲是否勝利,屬于機器操作{j=endCol+1;i=startRow+1;}}}}}文件的加密及解密文件的解密由于本游戲采用的數(shù)據(jù)讀寫處理采用文件讀取方式,有必要對游戲數(shù)據(jù)進行充分的加密處理,在程序翻開時,將讀取被加密的數(shù)據(jù)文件并對該文件進行解密操作,將解密的數(shù)據(jù)按照固定的算法讀入內(nèi)存,當游戲結(jié)束后,要將內(nèi)存中的數(shù)據(jù)進行加密然后保存到文件中。本加密算法采用DES對稱加密算法進行加密以及解密。具體代碼如下:publicvoidJieMiWenJian(stringname)//解密文件{byte[]key={24,55,102,24,98,26,67,29,84,19,37,118,104,85,121,27,93,86,24,55,102,24,98,26,67,29,9,2,49,69,73,92};byte[]IV={22,56,82,77,84,31,74,24,55,102,24,98,26,67,29,99};RijndaelManagedmyRijndael=newRijndaelManaged();FileStreamfsOut=File.Open(name,FileMode.Open,FileAccess.Read);CryptoStreamcsDecrypt=newCryptoStream(fsOut,myRijndael.CreateDecryptor(key,IV),CryptoStreamMode.Read);StreamReadersr=newStreamReader(csDecrypt);//把文件讀出來StreamWritersw=newStreamWriter("temp.dll");//解密后文件寫入一個新的文件sw.Write(sr.ReadToEnd());sw.Flush();sw.Close();sr.Close();fsOut.Close();File.Delete(name);copyFile("temp.dat",name);File.Delete("temp.dat");}下列圖顯示了對myScoreFile文件的解密比照。加密后的數(shù)據(jù)加密前的數(shù)據(jù)文件的加密publicvoidJiaMiWenJian(stringname)//加密文件{byte[]key={24,55,102,24,98,26,67,29,84,19,37,118,104,85,121,27,93,86,24,55,102,24,98,26,67,29,9,2,49,69,73,92};byte[]IV={22,56,82,77,84,31,74,24,55,102,24,98,26,67,29,99};RijndaelManagedmyRijndael=newRijndaelManaged();FileStreamfsOut=File.Open("temp.dll",FileMode.Create,FileAccess.Write);FileStreamfsIn=File.Open(name,FileMode.Open,FileAccess.Read);//寫入加密文本文件CryptoStreamcsDecrypt=newCryptoStream(fsOut,myRijndael.CreateEncryptor(key,IV),CryptoStreamMode.Write);//讀加密文本BinaryReaderbr=newBinaryReader(fsIn);csDecrypt.Write(br.ReadBytes((int)fsIn.Length),0,(int)fsIn.Length);csDecrypt.FlushFinalBlock();csDecrypt.Close();fsIn.Close();fsOut.Close();File.Delete(name);copyFile("temp.dat",name);File.Delete("temp.dat");}自定義控件的創(chuàng)立及使用自定義控件的定義及使用定義:自定義控件是已編譯的效勞器端控件,它將用戶界面和其他功能都封裝起來到可復(fù)用的包中。自定義控件和標準的控件相比,除了它們一個不同的標記前綴,并且必須進行顯式注冊和部署以外并沒有什么不同。此外,自定義控件擁有自己的對象模型,能夠觸發(fā)事件,并支持MicrosoftVisualStudio的所有設(shè)計是特性,諸如屬性窗口、可視化設(shè)計器、屬性生成器和工具箱。使用:首先要在VistualStudio的各個版本環(huán)境下,點擊右邊的工具箱,在工具箱上空白處點擊右鍵--選擇項--在.NETFramework組件選項卡下點擊“瀏覽”--找到你要添加的自定義控件(.dll文件)--翻開--確定。這樣你就可以在工具箱中將那個自定義控件拖出來使用了。自定義外觀的菜單本程序?qū)Σ藛慰丶M行了重繪制,采用繼承MenuStrip的方式實現(xiàn),對于菜單項的繪制,使用重寫OnRenderMenuItemBackground方法實現(xiàn),由于重繪菜單代碼過多,這里列出重繪菜單項的關(guān)鍵代碼。protectedoverridevoidOnRenderMenuItemBackground(ToolStripEventArgse){Graphicsg=e.Graphics;ToolStripItemitem=e.Item;ToolStriptsType=e.ToolStrip;g.SmoothingMode=SmoothingMode.HighQuality;//渲染頂級項if(tsTypeisMenuStrip){if(){PenLinesPen=newPen(Color.FromArgb(205,226,252));Point[]LinePoint={newPoint(0,2),newPoint(-1,2),newPoint(-1,-3),newPoint(0,-3),newPoint(0,2)};g.DrawLines(LinesPen,LinePoint);SolidBrushbrush=newSolidBrush(Color.FromArgb(197,228,253));Rectanglerect=newRectangle(0,2,-1,-5);g.FillRectangle(brush,rect);}if(item.Pressed){PenLinesPen=newPen(Color.FromArgb(197,228,253));Point[]LinePoint={newPoint(0,2),newPoint(-1,2),newPoint(dth-1,-3),newPoint(0,-3),newPoint(0,2)};g.DrawLines(LinesPen,LinePoint);}}//渲染下拉項elseif(tsTypeisToolStripDropDown){g.SmoothingMode=SmoothingMode.HighQuality
溫馨提示
- 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)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025太陽能槽式復(fù)合拋物面聚光集熱土壤儲熱技術(shù)
- 個人勞動法權(quán)益保障合同
- 個人抵押借款擔(dān)保合同
- 分期付款購買機動車合同書
- 醫(yī)療器械藥品購銷合同
- 醫(yī)院場地租賃合同書樣本
- 五金電器銷售合同6篇
- 2025年紅河b2貨運上崗證模擬考試
- 合同范本銷售人員聘用合同7篇
- 面板自動檢測機競爭策略分析報告
- 呼吸機濕化的護理
- 2024“五史”全文課件
- 醫(yī)療器械法律法規(guī)培訓(xùn)
- 2025年九年級數(shù)學(xué)中考復(fù)習(xí)計劃
- 2024屆江西省南昌市高三一模英語試卷(解析版)
- 2023年長沙自貿(mào)投資發(fā)展集團有限公司招聘筆試真題
- 辦公樓電氣系統(tǒng)改造方案
- 水電預(yù)留預(yù)埋施工組織設(shè)計方案
- 黑龍江省水資源稅適用稅額表2024
- 骨科常用體外治療儀器
- 2024解析:第十五章電流和電路-基礎(chǔ)練(解析版)
評論
0/150
提交評論