利用C#編寫掃雷游戲(附源碼)
前言
翻看了下以前大學(xué)學(xué)習(xí)的一些小項(xiàng)目,突然發(fā)現(xiàn)有個(gè)項(xiàng)目比較有意思,覺得有必要把它分享出來(lái)。當(dāng)然現(xiàn)在看來(lái),里面有很多的不足之處,但因博主現(xiàn)在已經(jīng)工作,沒有時(shí)間再去優(yōu)化。這個(gè)項(xiàng)目就是利用C#編寫一個(gè)Windows系統(tǒng)下的掃雷小游戲。
首先講下掃雷小游戲的玩法:
(1)掃雷就是要把所有非地雷的格子揭開即勝利;踩到地雷格子就算失敗。
(2)當(dāng)點(diǎn)開的格子不是地雷區(qū)域的時(shí)候,該格子會(huì)顯示一個(gè)數(shù)字,該數(shù)字表示的含義就是該格子周邊有多少個(gè)地雷。
(3)同時(shí)點(diǎn)開的如果非地雷的格子,周邊連貫的非地雷區(qū)域都會(huì)自動(dòng)被掃描打開,直到遇到旁邊有雷區(qū)的時(shí)候停止。
(4)當(dāng)你判斷出格子是地雷的時(shí)候,你可以使用鼠標(biāo)右鍵將該塊方格標(biāo)記為雷區(qū)。當(dāng)不確定的時(shí)候,你可標(biāo)記個(gè)問號(hào)以待確定。
下面來(lái)說下我大學(xué)時(shí)候?qū)崿F(xiàn)這個(gè)掃雷小游戲的思路:
(1)因?yàn)槔讌^(qū)是一個(gè)個(gè)格子聯(lián)合組成的,那我們可以使用winform程序自帶的系統(tǒng)按鈕控件Button來(lái)實(shí)現(xiàn)雷區(qū)方格。
(2)代表雷區(qū)方格的Button按鈕需要實(shí)現(xiàn)下面幾個(gè)事件:鼠標(biāo)左鍵點(diǎn)擊掃雷事件,鼠標(biāo)右鍵點(diǎn)擊標(biāo)記雷區(qū)事件,鼠標(biāo)右鍵點(diǎn)擊標(biāo)記問號(hào)區(qū)域事件。
(3)為了更好的實(shí)現(xiàn)游戲的可玩性,增加一個(gè)自由設(shè)置地雷數(shù)量的小功能,可自行設(shè)置雷區(qū)包含的地雷數(shù)量,設(shè)置完成后,自動(dòng)刷新界面,重新部署地雷。
(4)我們將雷區(qū)的方格存儲(chǔ)在一個(gè)全局的二維數(shù)組中,F(xiàn)orm窗體在初始化的時(shí)候,自動(dòng)生成面板區(qū)域的Button按鈕列表。
(5)為了實(shí)現(xiàn)每次玩游戲的時(shí)候,地雷分布不一致,我們?cè)贐utton列表生成后。隨機(jī)抽取出某些Button按鈕作為地雷分布點(diǎn),并記錄該Button的雷區(qū)屬性為含有地雷。
(6)算法中的關(guān)鍵:遞歸算法計(jì)算雷區(qū)。當(dāng)點(diǎn)擊某個(gè)方格的時(shí)候,如果該方格是雷區(qū),則直接Game Over,如果不是的話,則我們需要一個(gè)算法去計(jì)算旁邊區(qū)域的地雷數(shù)量,以及旁邊區(qū)域沒有地雷的區(qū)域,當(dāng)沒有地雷的區(qū)域連成一片的時(shí)候,我們需要使用遞歸算法,去查找二維數(shù)組,找到對(duì)應(yīng)的連片非雷區(qū),將之打開。
(7)如何設(shè)置方格的狀態(tài):當(dāng)鼠標(biāo)左鍵點(diǎn)擊的方塊區(qū)域非雷區(qū)的時(shí)候,我們將Button按鈕的屬性設(shè)置為Disabled即可呈現(xiàn)打開的狀態(tài)。當(dāng)鼠標(biāo)左鍵打開的方格是雷區(qū)時(shí)候,此時(shí)我們可以將所有地雷區(qū)域塊的Button的背景圖設(shè)置為地雷圖片,并 相應(yīng)的爆炸音效,彈出游戲終止界面即可。當(dāng)鼠標(biāo)右鍵標(biāo)記雷區(qū)或者待確定區(qū)域的時(shí)候,只需要更改Button的背景圖即可。當(dāng)然上述所有點(diǎn)擊操作,都得判斷Button方格區(qū)域當(dāng)前的狀態(tài)值:初始化狀態(tài)、已標(biāo)記為待確定狀態(tài)、已標(biāo)記為雷區(qū)。
游戲的最終效果圖如下:
我們下面來(lái)剖析下幾個(gè)關(guān)鍵點(diǎn),因?yàn)榇a量比較多,我就不全部詳細(xì)剖析了。
首先我們定義一個(gè)LeiButton類,這個(gè)類繼承于系統(tǒng)控件Button,增加x,y,youlei三個(gè)字段,x表示二維數(shù)組的第一個(gè)索引,y表示二維數(shù)組的第二個(gè)索引值,youlei用于標(biāo)記Button方塊區(qū)域按鈕的狀態(tài)(0表示無(wú)雷,1表示有雷)。同時(shí)我們使用Button按鈕類自帶的一個(gè)Tag屬性標(biāo)記該方塊區(qū)域是否被翻開。
具體定義如下:
然后我們?cè)诖绑w對(duì)象Form類中定義一些常用的變量之類,如下圖,都有相應(yīng)注釋
下面我們來(lái)看下生成Button的二維數(shù)組,即生成雷區(qū)的Button列表。我們需要在Form中添加GroupBox組件,然后將動(dòng)態(tài)生成的Button列表添加到這個(gè)groupbox組件中。生成Button的二維數(shù)組方法體如下:
生成完Button列表后,我們就開始部署地雷了,地雷隨機(jī)部署到Button列表中,部署地雷的方法如下:
到了這一步,我們就應(yīng)該將雷區(qū)的界面渲染出來(lái)了,這時(shí)候我們可以將上面兩個(gè)方法放入窗體的Form_Load事件中即可渲染出游戲界面。如下所示
我們繼續(xù),下面寫掃雷的算法,當(dāng)鼠標(biāo)左鍵點(diǎn)開某個(gè)方格的時(shí)候,如果該方格不是雷區(qū),那我們需要計(jì)算該方格周邊的地雷數(shù)量,計(jì)算方法如下:
下面是個(gè)遞歸計(jì)算的核心算法,非常關(guān)鍵。當(dāng)我們點(diǎn)開的方格非雷區(qū)的時(shí)候,周邊連片的非雷區(qū)的方格塊會(huì)被打開。這一塊的核心算法參考下列代碼,row表示行,col表示列
下面我們來(lái)添加鼠標(biāo)的點(diǎn)擊事件,我這邊采用的是bt_MouseUp事件來(lái)處理。點(diǎn)擊后,我們首先判斷游戲是否結(jié)束,如果沒結(jié)束,則進(jìn)行下列操作,獲取到被點(diǎn)擊的按鈕的x,y值以及點(diǎn)擊事件按下的鍵值(判斷按下的是鼠標(biāo)左鍵還是右鍵)。x,y值獲取到了,我們就可以到Button二維數(shù)組中找到對(duì)應(yīng)元素。
假如點(diǎn)擊的是鼠標(biāo)左鍵,則我們進(jìn)行掃雷操作,具體的代碼如下:
如果按下的是鼠標(biāo)右鍵,則是標(biāo)記方塊是雷區(qū)或者待確定區(qū)域,具體代碼如下:
最后再給出一個(gè)判斷是否掃雷完畢的方法。
掃雷游戲的設(shè)計(jì)大概到此結(jié)束,中間還有很多可以優(yōu)化的地方,比如將掃雷的邏輯代碼抽離Form類獨(dú)立出來(lái)等,這些都靠讀者自行去優(yōu)化了。
附上博主源碼下載的百度云鏈接,需要代碼學(xué)習(xí)的可自行下載研究:本地下載
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對(duì)我們的支持。
您可能感興趣的文章
- 01-10C#利用反射技術(shù)實(shí)現(xiàn)去掉按鈕選中時(shí)的邊框效果
- 01-10C#圖片處理3種高級(jí)應(yīng)用
- 01-10輕松學(xué)習(xí)C#的正則表達(dá)式
- 01-10分享一個(gè)C#編寫簡(jiǎn)單的聊天程序(詳細(xì)介紹)
- 01-10C#異步下載文件
- 01-10C# Console利用mspaint打開圖像并保存的方法
- 01-10C#利用delegate實(shí)現(xiàn)Javascript的each方法
- 01-10使用C#編寫簡(jiǎn)單的圖形化的可發(fā)送附件的郵件客戶端程序
- 01-10Windows中使用C#為文件夾和文件編寫密碼鎖的示例分享
- 01-10C#使用Process類調(diào)用外部exe程序


閱讀排行
- 1C語(yǔ)言 while語(yǔ)句的用法詳解
- 2java 實(shí)現(xiàn)簡(jiǎn)單圣誕樹的示例代碼(圣誕
- 3利用C語(yǔ)言實(shí)現(xiàn)“百馬百擔(dān)”問題方法
- 4C語(yǔ)言中計(jì)算正弦的相關(guān)函數(shù)總結(jié)
- 5c語(yǔ)言計(jì)算三角形面積代碼
- 6什么是 WSH(腳本宿主)的詳細(xì)解釋
- 7C++ 中隨機(jī)函數(shù)random函數(shù)的使用方法
- 8正則表達(dá)式匹配各種特殊字符
- 9C語(yǔ)言十進(jìn)制轉(zhuǎn)二進(jìn)制代碼實(shí)例
- 10C語(yǔ)言查找數(shù)組里數(shù)字重復(fù)次數(shù)的方法
本欄相關(guān)
- 01-10C#通過反射獲取當(dāng)前工程中所有窗體并
- 01-10關(guān)于ASP網(wǎng)頁(yè)無(wú)法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實(shí)現(xiàn)txt定位指定行完整實(shí)例
- 01-10WinForm實(shí)現(xiàn)仿視頻 器左下角滾動(dòng)新
- 01-10C#停止線程的方法
- 01-10C#實(shí)現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實(shí)現(xiàn)讀取注冊(cè)表監(jiān)控當(dāng)前操作系統(tǒng)已
隨機(jī)閱讀
- 08-05dedecms(織夢(mèng))副欄目數(shù)量限制代碼修改
- 01-11ajax實(shí)現(xiàn)頁(yè)面的局部加載
- 01-10delphi制作wav文件的方法
- 01-10C#中split用法實(shí)例總結(jié)
- 04-02jquery與jsp,用jquery
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10SublimeText編譯C開發(fā)環(huán)境設(shè)置
- 08-05DEDE織夢(mèng)data目錄下的sessions文件夾有什
- 08-05織夢(mèng)dedecms什么時(shí)候用欄目交叉功能?
- 01-10使用C語(yǔ)言求解撲克牌的順子及n個(gè)骰子