C++小游戲-掃雷


前言

提示:本文是基於easyX圖形庫實現的,還有部分功能可以添加,僅適合新手參考。


提示:以下是本篇文章正文內容,下面案例可供參考

一、掃雷游戲模式

在確定大小的矩形雷區中隨機布置一定數量的地雷,玩家需要盡快找出雷區中的所有不是地雷的方塊,而不許踩到地雷。
游戲的基本操作包括左鍵單擊和右鍵單擊。其中左鍵用於打開安全的格子,推進游戲進度;右鍵用於標記地雷,以輔助判斷。
左鍵單擊:在判斷出不是雷的方塊上按下左鍵,可以打開該方塊。如果方塊上出現數字,則該數字表示其周圍3×3區域中的地雷數(一般為8個格子,對於邊塊為5個格子,對於角塊為3個格子。所以掃雷中最大的數字為8);如果方塊上為空(相當於0),則可以遞歸地打開與空相鄰的方塊;如果不幸觸雷,則游戲結束。
右鍵單擊:在判斷為地雷的方塊上按下右鍵,可以標記地雷(顯示為小紅旗)。重復一次或兩次操作可取消標記。

二、代碼實現

1.繪制地圖場景

根據每一塊地區的數據進行圖形輸出。

代碼如下(示例):

 1 void drawmap(int map[][12],IMAGE *img)
 2 {
 3     int i, j;
 4     for (i = 1; i <= 10; i++)
 5     {
 6         for (j = 0; j <= 10; j++)
 7         {
 8             int x = 50 * (i - 1);//得到位置
 9             int y = 50 * (j - 1);
10             if (map[i][j]>25)
11             {
12                 putimage(x, y, &img[9]);//標記flag
13             }
14             else
15             {
16                 switch (map[i][j])
17                 {
18                 case 9:
19                     putimage(x, y, &img[11]);//輸出圖片雷
20                     break;
21                 case 10:
22                     putimage(x, y, &img[0]);//0
23                     break;
24                 case 11:
25                     putimage(x, y, &img[1]);//1
26                     break;
27                 case 12:
28                     putimage(x, y, &img[2]);//2
29                     break;
30                 case 13:
31                     putimage(x, y, &img[3]);//3
32                     break;
33                 case 14:
34                     putimage(x, y, &img[4]);//4
35                     break;
36                 case 15:
37                     putimage(x, y, &img[5]);//5
38                     break;
39                 case 16:
40                     putimage(x, y, &img[6]);//6
41                     break;
42                 case 17:
43                     putimage(x, y, &img[7]);//7
44                     break;
45                 case 18:
46                     putimage(x, y, &img[8]);//8
47                     break;
48                 default:
49                     putimage(x, y, &img[10]);//地圖
50                     break;
51                 }
52             }
53         }
54     }
55 }

2.鼠標點擊

鼠標左鍵點擊翻開格子,右鍵點擊標記flag,再次點擊可以進行取消。
sum記錄翻開格子的數量,點擊后對每個位置的數據進行加減操作。

代碼如下(示例):

 1 int mousedown(int map[][12])
 2 {
 3     MOUSEMSG m;    //定義鼠標消息變量
 4     while (1)
 5     {
 6         //獲取鼠標消息
 7         m = GetMouseMsg();
 8         int mi = m.x / 50 + 1;
 9         int mj = m.y / 50 + 1;
10 
11         //判斷鼠標消息
12         switch (m.uMsg)
13         {
14         case WM_LBUTTONDOWN:
15             if (map[mi][mj] > 9)    //已翻開的情況
16             {
17                 continue;
18             }
19             if (map[mi][mj] == 0)   //如果點擊為0,則翻開一片。
20             {
21                 //使用遞歸函數
22                 swap(map, mi, mj);
23             }
24             else
25             {
26                 map[mi][mj] += 10;
27                 sum += 1;
28             }
29             return  map[mi][mj];
30             break;
31         case WM_RBUTTONDOWN:
32             if (map[mi][mj] > 9&& map[mi][mj] < 25)    //已翻開的情況
33             {
34                 continue;
35             }
36             if (map[mi][mj] > 25)       //再次點擊取消flag
37             {
38                 map[mi][mj] -= 30;
39             }
40             else
41             {
42                 map[mi][mj] += 30;
43             }
44             return  map[mi][mj];
45             break;
46         }
47     }
48 }

3.遞歸

當我們點到為0的地區時,將會打開周圍的部分地區,外圍為非0數或到達邊界,內部為0.
如圖:

在這里插入圖片描述

代碼如下(示例):

 1 void swap(int map[][12],int mi,int mj)
 2 {
 3     map[mi][mj] = 10;
 4     sum += 1;
 5     for (int i = mi - 1; i <= mi + 1; i++)
 6     {
 7         for (int j = mj - 1; j <= mj + 1; j++)
 8         {
 9             //數組下標不能越界
10             if (i >= 1 && i <= 10 && j >= 1 && j <= 10)
11             {
12                 //翻開的只能是數字
13                 if (map[i][j] < 9)
14                 {
15                     //如果為0,則進行遞歸。
16                     if (map[i][j] == 0)
17                     {
18                         swap(map, i, j);
19                     }
20                     else
21                     {
22                         map[i][j] += 10;
23                         sum += 1;
24                     }
25                 }
26             }
27         }
28     }
29 }

4.初始化游戲

代碼如下(示例):

 1 void startgame()
 2 {
 3     initgraph(500, 500);    //初始化地圖500x500
 4     int map[12][12] = { 0 };
 5     int i,j,m,n;
 6     //隨機函數種子
 7     srand((unsigned int)time(NULL));
 8     //隨機生成10個雷
 9     for (n = 0; n < 10;)
10     {
11         i = rand() % 10 + 1;    //[1,10]
12         j = rand() % 10 + 1;
13         if (map[i][j] == 0)     //排除本來就有雷的情況
14         {
15             map[i][j] = -1;     //-1表示有雷
16             n++;
17         }
18     }
19     //產生數字
20     for (i = 1; i <= 10; i++)
21     {
22         for (j = 1; j <= 10; j++)
23         {
24             //排除是雷的情況
25             if (map[i][j] != -1)
26             {
27                 for (m = i - 1; m <= i + 1; m++)    //判斷周圍是否有雷
28                 {
29                     for (n = j - 1; n <= j + 1; n++)
30                     {
31                         if (map[m][n] == -1)
32                         {
33                             map[i][j]++;
34                         }
35                     }
36                 }
37             }
38         }
39     }
40     IMAGE img[12];              //定義圖片變量
41     loadimage(&img[0], "E:\\C++ project\\minesweeping\\0.jpg", 50, 50);
42     loadimage(&img[1], "E:\\C++ project\\minesweeping\\1.gif", 50, 50);//加載圖片
43     loadimage(&img[2], "E:\\C++ project\\minesweeping\\2.gif", 50, 50);
44     loadimage(&img[3], "E:\\C++ project\\minesweeping\\3.gif", 50, 50);
45     loadimage(&img[4], "E:\\C++ project\\minesweeping\\4.gif", 50, 50);
46     loadimage(&img[5], "E:\\C++ project\\minesweeping\\5.gif", 50, 50);
47     loadimage(&img[6], "E:\\C++ project\\minesweeping\\6.gif", 50, 50);
48     loadimage(&img[7], "E:\\C++ project\\minesweeping\\7.gif", 50, 50);
49     loadimage(&img[8], "E:\\C++ project\\minesweeping\\8.gif", 50, 50);
50     loadimage(&img[9], "E:\\C++ project\\minesweeping\\flag.gif", 50, 50);
51     loadimage(&img[10], "E:\\C++ project\\minesweeping\\地圖.gif", 50, 50);
52     loadimage(&img[11], "E:\\C++ project\\minesweeping\\雷.gif", 50, 50);
53     while (1)
54     {
55         drawmap(map, img);
56         //點到地雷
57         if (mousedown(map)==9)
58         {
59             sum = 0;    //重置判斷變量
60             drawmap(map, img);
61             MessageBox(hwnd,"你踩到雷了!","Game Over",MB_OK);
62             return;
63         }
64         //成功完成游戲
65         if (sum == 90)
66         {
67             sum = 0;    //重置判斷變量
68             drawmap(map, img);
69             MessageBox(hwnd, "你成功完成了游戲!", "Game Over", MB_OK);
70             return;
71         }
72     }
73 }

5.main

代碼如下(示例):

 1 #include<iostream>
 2 #include<time.h>
 3 #include<graphics.h>        //圖形庫頭文件 easyx
 4 #include <conio.h>          //調用_getch函數
 5 using namespace std;
 6 HWND hwnd;
 7 int sum = 0;//用於表示目前已經點開的格子數
 8 //聲明函數
 9 void drawmap(int map[][12], IMAGE* img);
10 int mousedown(int map[][12]);
11 void swap(int map[][12], int mi, int mj);
12 //初始化游戲
13 
14 //繪制地圖
15 
16 //鼠標點擊
17 
18 //遞歸函數
19 
20 int main()
21 {
22     while (1)
23     {
24         startgame();
25         if (MessageBox(hwnd, "再來一次", "結束游戲", MB_YESNO)==IDNO)
26             break;
27     }
28     //_getch();                //防止閃屏
29     closegraph();
30     return 0;
31 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM