一、新建項目
二、新建源文件
main.cpp和mining,cpp
三、新建頭文件
mining.h
四、圖片資源添加
添加完成后會在頭文件里面生成一個.h頭文件,用來調用資源
打開之后可以看到,對每一個資源文件進行了定義
這里面的順序和你添加文件時的順序是一樣的,是根據你添加資源的先后順序進行排列定義的
在資源文件夾下回顯示添加的資源
五、VS安裝圖形庫
安裝完成后重啟VS之后就可以在項目中調用圖形庫的頭文件-----> #include<graphics.h> //圖形庫的頭文件
接下來是相關代碼:
頭文件部分:
mining.h文件
1 #include<time.h> //該種方式引用的頭文件是c自帶的頭文件
2 #include<stdlib.h>
3 #include<graphics.h> //圖形庫的頭文件
4
5 #define MAP_WIDTH 500 //定義地圖寬度 宏定義方式 即MAP_WIDTH就等於550
6
7 #define MAP_HEIGHT 550 //定義地圖的高度
8
9 #define EACH_SIZE 50 //每一個格子的大小
10
11 #define MAX_X (MAP_WIDTH/EACH_SIZE) //計算每一行有多少個
12
13 #define MAX_Y (MAP_HEIGHT/EACH_SIZE) //計算每一列有多少個
14
15 #define MINE_COUNT 20 //雷的個數
16
17 //1.初始化地圖
18 void InitMap(); //定義一個函數 是一個模塊 只做屬於自己的事情 19
20 //2.實現雷的周圍加一
21 void ChangeState(int x,int y); 22
23 //3.判斷是否越界
24 int IsPosOk(int x, int y); 25
26 //4.貼圖
27 void DrawMap(); 28
29 //5.顯示信息
30 void ShowInfo(); 31
32 //6.實現鼠標點擊 ** 還未實現
33 int IsOpenMine(); 34
35 //7.進行遞歸翻開格子 ** 還未實現
36 void OpenZeroRecursively(int x,int y); 37
38 //8.翻開所有格子
39 void OpenAll(); 40
41 //9.判斷輸贏 點擊到地雷就輸了 ** 還未實現
42 void RenGame();
源文件部分:
main.cpp
1 #include"mining.h"
2 #include<stdio.h>
3
4 int main() 5 { 6 initgraph(MAP_WIDTH, MAP_HEIGHT);//畫出地圖窗口
7
8 InitMap();//初始換函數
9
10 DrawMap();//貼圖函數
11 getchar(); 12
13 OpenAll();//翻開所有格子
14 DrawMap();//貼圖
15
16 getchar(); 17 return 0; 18 getchar();//防止結果閃退
19 }
mining.cpp
1 #include"mining.h" //這種方式引用的頭文件是我們自己定義的
2 #include"resource.h"
3
4 int Map[MAX_X][MAX_Y]; //定義一個二維數組 制作地圖
5
6 int nCountOpen; //打開格子的個數
7
8 int nCountFlag; //標記的個數
9
10 void InitMap() //第一個函數 初始化函數
11 { 12 //1.初始化數組
13 for (int i = 0; i < MAX_X; i++) 14 { 15 for (int j = 0; j < MAX_Y; j++) 16 { 17 Map[i][j] = 0; 18 } 19 } 20
21 nCountOpen = 0; //初始化
22
23 nCountFlag = 0; //初始化 24
25 //2.埋地雷---> 地雷是隨機的
26
27 srand((unsigned int)time(0)); // 種下隨機數種子
28
29 int x, y; 30
31 int nCount=0; //統計埋雷的個數 32
33 //開始埋雷
34 while (nCount<MINE_COUNT) //當前埋雷的個數 小於埋雷的最大個數 就一直循環
35 { 36 x = rand() % MAX_X; // ? %10==0~9 rand 獲取隨機數
37
38 y = rand() % (MAX_Y - 1) + 1; //
39
40 if (-1 == Map[x][y]) //-1 表示地雷
41 {//隨機下標是一個地雷
42 continue; //跳過本次循環 不是結束循環(break)
43 } 44 Map[x][y] = -1; // 埋雷
45
46 nCount++; //埋雷的個數加一
47 } 48
49 //實現地雷九宮格周圍加一
50 for (int i = 0; i < MAX_X; i++) 51 { 52 for (int j = 1; j < MAX_Y; j++) //因為第一行沒有雷 我們是用來顯示信息的 所以不能從0開始
53 { 54 if (-1 == Map[i][j]) //判斷是不是一顆地雷 -1寫在左邊的原因-->左值 Map[i][j]=-1這種形式是錯誤的
55 { 56 ChangeState(i, j); //下標
57 } 58 } 59 } 60 } 61
62 void ChangeState(int x, int y) //第二個函數 實現雷的周圍加一 九宮格范圍
63 { 64 for (int i = x - 1; i <= x + 1; i++) 65 { 66 for (int j = y - 1; j <= y + 1; j++) 67 { 68 if (-1 == Map[i][j]||IsPosOk(i,j)==0 ) //這個位置是一顆地雷並且判斷是否越界
69 { 70 continue; //跳出本次循環
71 } 72 Map[i][j]+=1; //和Map[i][j]++;是一樣的
73 } 74 } 75 } 76
77 int IsPosOk(int x, int y) //第三個函數 判斷當前的下標是不是越界了
78 { 79 //邏輯表達式的值 0和1
80 return (x >= 0 && x <= MAX_X&&y <= 1 && y < MAX_Y); //越界返回0 沒越界返回1
81 } 82
83 void DrawMap() //第四個函數 對地圖貼圖貼圖
84 { 85 IMAGE img; 86
87 for (int i = 0; i < MAX_X; i++) 88 { 89 for (int j = 1; j < MAX_Y; j++) 90 { 91 if (Map[i][j] < 9) //雷的周圍1最大是8個不會超過九 小於9 說明格子沒有被翻開
92 { 93 loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG13), EACH_SIZE, EACH_SIZE); //L寬字節 jpg13是沒有翻開的情況的圖片
94 } 95 else //已經被翻開
96 { //翻開一個格子 讓這個格子+10 表示已經被翻開
97 if (Map[i][j] >= 11 && Map[i][j] <= 18) //11~18表示1~8
98 { 99 loadimage(&img, L"JPG", MAKEINTRESOURCE(IDR_JPG1 + Map[i][j] - 11, EACH_SIZE, EACH_SIZE)); //通過這個算法 判斷貼哪一張圖片
100 } 101 else if (Map[i][j] == 9) //9-10==-1 -1是地雷
102 { 103 loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG10), EACH_SIZE, EACH_SIZE); //貼地雷圖片
104 } 105 else if (Map[i][j] == 10) //10-10==0 0表示空白
106 { 107 loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG11), EACH_SIZE, EACH_SIZE); //貼空地圖片
108 } 109 else
110 { 111 loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG9), EACH_SIZE, EACH_SIZE); //貼標記圖片
112 } 113 } 114 putimage(i*EACH_SIZE, j*EACH_SIZE, &img); 115 } 116 } 117 ShowInfo(); 118 } 119
120 void ShowInfo() //第五個函數 顯示信息
121 { 122 //埋雷的個數 打開的個數 標記的個數 123 //設置字體的樣式
124 settextstyle(20, 20, L"wingding.ttf"); //字體樣式標號 125
126 //背景顏色
127 setbkmode(TRANSPARENT); 128
129 //字體顏色
130 settextcolor(YELLOW); 131
132 //設置字體的位置
133 WCHAR szOpen[32]; 134 WCHAR szFlag[32]; 135 WCHAR szAllMine[32]; 136
137 //字符串格式化 138 //與printf scanf類似
139 wsprintf(szAllMine, L"埋雷:%d", MINE_COUNT);//埋雷:20 把“埋雷”這個字符串放到szAllMine里面 格式化成字符串類型
140 wsprintf(szOpen, L"打開:%d", nCountOpen); 141 wsprintf(szFlag, L"標記:%d", nCountFlag); 142
143 //調整坐標
144 outtextxy(20, 20, szAllMine); 145 outtextxy(190, 20, szOpen); 146 outtextxy(350, 20, szFlag); 147
148 } 149
150
151
152
153
154
155 void OpenZeroRecursively(int x, int y) //第七個函數 進行遞歸翻開格子
156 { 157
158 } 159
160 void OpenAll() //第八個函數 翻開所有格子
161 { 162 for (int i = 0; i < MAX_X; i++) 163 { 164 for (int j=1;j<MAX_Y;j++) 165 { 166 if (Map[i][j] < 9) 167 { 168 Map[i][j] += 10; 169 } 170 } 171 } 172 } 173
174 void RenGame() //第九個函數 判斷輸贏
175 { 176
177 }
注:
設置字體樣式:
目前實現的結果如下:
之后的以后有機會寫好之后再補充
2019-03-20 13:09:47
之前寫的代碼並不完整,而且還有一些錯誤,在經過一番學習添加修改后,
最終添加修改完善后的代碼如下所示:
1 mining.h文件 2 #include<time.h> //該種方式引用的頭文件是c自帶的頭文件 3 #include<stdlib.h> 4 #include<graphics.h> //圖形庫的頭文件 5 6 #define MAP_WIDTH 500 //定義地圖寬度 宏定義方式 即MAP_WIDTH就等於550 7 8 #define MAP_HEIGHT 550 //定義地圖的高度 9 10 #define EACH_SIZE 50 //每一個格子的大小 11 12 #define MAX_X (MAP_WIDTH/EACH_SIZE) //計算每一行有多少個 13 14 #define MAX_Y (MAP_HEIGHT/EACH_SIZE) //計算每一列有多少個 15 16 #define MINE_COUNT 5//雷的個數 17 18 //1.初始化地圖 19 void InitMap(); //定義一個函數 是一個模塊 只做屬於自己的事情 20 21 //2.實現雷的周圍加一 22 void ChangeState(int x,int y); 23 24 //3.判斷是否越界 25 int IsPosOk(int x, int y); 26 27 //4.貼圖 28 void DrawMap(); 29 30 //5.顯示信息 31 void ShowInfo(); 32 33 //6.實現鼠標點擊 34 int IsOpenMine(); 35 36 //7.進行遞歸翻開格子 37 void OpenZeroRecursively(int x,int y); 38 39 //8.翻開所有格子 40 void OpenAll(); 41 42 //9.判斷輸贏 點擊到地雷就輸了 43 void RenGame(); 44 45 //以上是對使用函數的一個聲明 46 47 48 mining.cpp文件 49 #include"mining.h" //這種方式引用的頭文件是我們自己定義的 50 #include"resource.h" 51 52 int Map[MAX_X][MAX_Y]; //定義一個二維數組 制作地圖 53 54 int nCountOpen; //打開格子的個數 55 56 int nCountFlag; //標記的個數 57 58 void InitMap() //第一個函數 初始化函數 59 { 60 //1.初始化數組 61 for (int i = 0; i < MAX_X; i++) 62 { 63 for (int j = 0; j < MAX_Y; j++) 64 { 65 Map[i][j] = 0; 66 } 67 } 68 69 nCountOpen = 0; //初始化 70 71 nCountFlag = 0; //初始化 72 73 //2.埋地雷---> 地雷是隨機的 74 75 srand((unsigned int)time(0)); // 種下隨機數種子 76 77 int x, y; 78 79 int nCount=0; //統計埋雷的個數 80 81 //開始埋雷 82 while (nCount<MINE_COUNT) //當前埋雷的個數 小於埋雷的最大個數 就一直循環 83 { 84 x = rand() % MAX_X; // ? %10==0~9 rand 獲取隨機數 85 86 y = rand() % (MAX_Y - 1) + 1; // 87 88 if (-1 == Map[x][y]) //-1 表示地雷 89 {//隨機下標是一個地雷 90 continue; //跳過本次循環 不是結束循環(break) 91 } 92 Map[x][y] = -1; // 埋雷 93 94 nCount++; //埋雷的個數加一 95 } 96 97 //實現地雷九宮格周圍加一 98 for (int i = 0; i < MAX_X; i++) 99 { 100 for (int j = 1; j < MAX_Y; j++) //因為第一行沒有雷 我們是用來顯示信息的 所以不能從0開始 101 { 102 if (-1 == Map[i][j]) //判斷是不是一顆地雷 -1寫在左邊的原因-->左值 Map[i][j]=-1這種形式是錯誤的 103 { 104 ChangeState(i, j); //下標 105 } 106 } 107 } 108 } 109 110 void ChangeState(int x, int y) //第二個函數 實現雷的周圍加一 九宮格范圍 111 { 112 for (int i = x - 1; i <= x + 1; i++) 113 { 114 for (int j = y - 1; j <= y + 1; j++) 115 { 116 if (-1 == Map[i][j]||IsPosOk(i,j)==0 ) //這個位置是一顆地雷並且判斷是否越界 117 { 118 continue; //跳出本次循環 119 } 120 Map[i][j]+=1; //和Map[i][j]++;是一樣的 121 } 122 } 123 } 124 125 int IsPosOk(int x, int y) //第三個函數 判斷當前的下標是不是越界了 126 { 127 //邏輯表達式的值 0和1 128 return (x >= 0 && x < MAX_X &&y >= 1 && y < MAX_Y); //越界返回0 沒越界返回1 129 } 130 131 void DrawMap() //第四個函數 對地圖貼圖貼圖 132 { 133 IMAGE img; 134 BeginBatchDraw(); //批量繪圖 解決閃屏問題 135 136 cleardevice(); 137 138 139 for (int i = 0; i < MAX_X; i++) 140 { 141 for (int j = 1; j < MAX_Y; j++) 142 { 143 if (Map[i][j] < 9) //雷的周圍1最大是8個不會超過九 小於9 說明格子沒有被翻開 144 { 145 loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG13), EACH_SIZE, EACH_SIZE); //L寬字節 jpg13是沒有翻開的情況的圖片 146 } 147 else //已經被翻開 148 { //翻開一個格子 讓這個格子+10 表示已經被翻開 149 if (Map[i][j] >= 11 && Map[i][j] <= 18) //11~18表示1~8 150 { 151 loadimage(&img, L"JPG", MAKEINTRESOURCE(IDR_JPG1 + Map[i][j] - 11), EACH_SIZE, EACH_SIZE); //通過這個算法 判斷貼哪一張圖片 152 } 153 else if (Map[i][j] == 9) //9-10==-1 -1是地雷 154 { 155 loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG10), EACH_SIZE, EACH_SIZE); //貼地雷圖片 156 } 157 else if (Map[i][j] == 10) //10-10==0 0表示空白 158 { 159 loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG12), EACH_SIZE, EACH_SIZE); //貼空地圖片 160 } 161 else 162 { 163 loadimage(&img, L"jpg", MAKEINTRESOURCE(IDR_JPG9), EACH_SIZE, EACH_SIZE); //貼標記圖片 164 } 165 } 166 putimage(i*EACH_SIZE, j*EACH_SIZE, &img); 167 } 168 } 169 ShowInfo(); 170 EndBatchDraw(); 171 } 172 173 void ShowInfo() //第五個函數 顯示信息 174 { 175 //埋雷的個數 打開的個數 標記的個數 176 //設置字體的樣式 177 settextstyle(20, 20, L"wingding.ttf"); //字體樣式標號 178 179 //背景顏色 180 setbkmode(TRANSPARENT); 181 182 //字體顏色 183 settextcolor(YELLOW); 184 185 //設置字體的位置 186 WCHAR szOpen[32]; 187 WCHAR szFlag[32]; 188 WCHAR szAllMine[32]; 189 190 //字符串格式化 191 //與printf scanf類似 192 wsprintf(szAllMine, L"埋雷:%d", MINE_COUNT);//埋雷:20 把“埋雷”這個字符串放到szAllMine里面 格式化成字符串類型 193 wsprintf(szOpen, L"打開:%d", nCountOpen); 194 wsprintf(szFlag, L"標記:%d", nCountFlag); 195 196 //調整坐標 197 outtextxy(20, 20, szAllMine); 198 outtextxy(190, 20, szOpen); 199 outtextxy(350, 20, szFlag); 200 201 } 202 203 int IsOpenMine() 204 { 205 MOUSEMSG m = { 0 };//保存鼠標消息 206 207 while (1) //死循環 208 { 209 m = GetMouseMsg();//獲取鼠標消息 210 switch (m.uMsg) 211 { 212 case WM_LBUTTONDOWN: //鼠標左鍵按下 213 if (Map[m.x / EACH_SIZE][m.y / EACH_SIZE] == -1) //點擊到了地雷 214 { 215 Map[m.x / EACH_SIZE][m.y / EACH_SIZE] += 10; //int a=5; a+=10 a=a+10 翻開格子+10 表示已經翻開 216 return 0; //返回0說明點擊的是一顆雷 217 } 218 else if (Map[m.x / EACH_SIZE][m.y / EACH_SIZE] == 0) //點擊到的是一個空地 219 { 220 OpenZeroRecursively(m.x / EACH_SIZE, m.y / EACH_SIZE); 221 return 1; 222 } 223 else if (Map[m.x / EACH_SIZE][m.y / EACH_SIZE] > 0 && Map[m.x / EACH_SIZE][m.y / EACH_SIZE] < 9) //表示 點擊的位置的值是1~8 9表示的是已經被翻開的 224 { 225 Map[m.x / EACH_SIZE][m.y / EACH_SIZE] += 10; 226 nCountOpen++; 227 return 1; 228 } 229 230 break; 231 case WM_RBUTTONDOWN: 232 if (Map[m.x / EACH_SIZE][m.y / EACH_SIZE] < 9) 233 { 234 Map[m.x / EACH_SIZE][m.y / EACH_SIZE ]+= 100; //加多少都可以 只是一個標記 235 nCountFlag++; 236 } 237 else if (Map[m.x / EACH_SIZE][m.y / EACH_SIZE]>19) 238 { 239 Map[m.x / EACH_SIZE][m.y / EACH_SIZE] -= 100; 240 nCountFlag--; 241 } 242 return 1; 243 } 244 } 245 } 246 247 void OpenZeroRecursively(int x, int y) //第七個函數 進行遞歸翻開格子 248 { 249 Map[x][y] += 10; 250 nCountOpen++; 251 for (int i = x - 1; i <= x + 1; i++) 252 { 253 for (int j = y - 1; j <= y + 1; j++) 254 { 255 if (IsPosOk(i, j)==0) 256 { 257 continue; 258 } 259 if (0==Map[i][j]) 260 { 261 OpenZeroRecursively(i, j); 262 } 263 if (Map[i][j] < 9) 264 { 265 Map[i][j] += 10; 266 nCountOpen++; 267 } 268 } 269 } 270 } 271 272 void OpenAll() //第八個函數 翻開所有格子 游戲結束 273 { 274 for (int i = 0; i < MAX_X; i++) 275 { 276 for (int j=1;j<MAX_Y;j++) 277 { 278 if (Map[i][j] < 9) 279 { 280 Map[i][j] += 10; 281 } 282 } 283 } 284 } 285 286 void RenGame() //第九個函數 判斷輸贏 287 { 288 while (nCountOpen<((MAX_X*(MAX_Y-1))-MINE_COUNT)) //100個格子 有20個地雷 10*111=110 10*10 289 { 290 if (IsOpenMine()==0) 291 { 292 OpenAll(); 293 DrawMap(); 294 MessageBox(GetHWnd(), L"你太菜了!再去修煉吧!", L"提示",MB_OK); 295 return ; //結束函數 296 } 297 DrawMap(); 298 } 299 DrawMap(); 300 MessageBox(GetHWnd(), L"恭喜你,你贏了", L"提示", MB_OK); 301 } 302 303 304 305 main.cpp文件 306 #include"mining.h" 307 #include<stdio.h> 308 309 int main() 310 { 311 initgraph(MAP_WIDTH, MAP_HEIGHT);//畫出地圖窗口 312 313 InitMap();//初始換函數 314 DrawMap();//貼圖 315 316 while (true) //循環游戲 317 { 318 RenGame(); 319 InitMap(); 320 DrawMap(); 321 } 322 getchar(); 323 return 0; 324 }
2019-03-20 23:57:46