文章目录
Part 1:功能实现
- 界面
- 插红旗🚩
- 展开空白
- 记录用时⏲
- 难度选择:简单/一般/困难/自定义
- more…
Part 2 :各部分详解
2.1头文件一览
#include<graphics.h> //使用easyx
#include<stdio.h>
#include<Windows.h>
#include<stdlib.h>
#include<time.h>
//#include<tchar.h>
//#include<atlstr.h> //这两个库是用来弄计时器的作者水平有限目前没有做出来
#define ROW 9//游戏区
#define COL 9
#define MINE 10 //雷的个数
#define ROWS ROW+2//数雷时候为了避免数组越界而拓宽
#define COLS COL+2
#define SIZE 50 //布置界面大小
这里使用的是Easyx_20210730的版本Easyx官网指路
2.2主函数部分
int main()
{
HWND MineSweeper = initgraph(SIZE * ROW, SIZE * COL);//搭建窗口
srand((unsigned)time(NULL));//随机数种子
SetWindowText(MineSweeper, L"扫雷"); //窗口命名
loadimage(&img[12], _T("12.bmp"), SIZE * ROW, SIZE * COL, true);//加载图片
loadimage(&img[0], _T("0.bmp"), SIZE, SIZE, true);
loadimage(&img[1], _T("1.bmp"), SIZE, SIZE, true);
loadimage(&img[2], _T("2.bmp"), SIZE, SIZE, true);
loadimage(&img[3], _T("3.bmp"), SIZE, SIZE, true);
loadimage(&img[4], _T("4.bmp"), SIZE, SIZE, true);
loadimage(&img[5], _T("5.bmp"), SIZE, SIZE, true);
loadimage(&img[6], _T("6.bmp"), SIZE, SIZE, true);
loadimage(&img[7], _T("7.bmp"), SIZE, SIZE, true);
loadimage(&img[8], _T("8.bmp"), SIZE, SIZE, true);
loadimage(&img[10], _T("10.bmp"), SIZE, SIZE, true);
loadimage(&img[11], _T("11.bmp"), SIZE, SIZE, true);
loadimage(&img[9], _T("9.bmp"), SIZE, SIZE, true);
while (1)
{
BeginBatchDraw();//开始画图
putimage(0, 0, &img[12]); //显示图片
setbkmode(TRANSPARENT); //背景透明
settextcolor(RED);//文字颜色
settextstyle(30, 0, L"微软雅黑");//文字信息巴拉巴拉
outtextxy(SIZE * ROW / 2 - 70, SIZE * COL / 2 + 90, L"👉开始van游戏");
settextcolor(RED);
settextstyle(30, 0, L"微软雅黑");
outtextxy(SIZE * ROW / 2 - 70, SIZE * COL / 2 + 130, L"👉溜了溜了");
ExMessage msg; //鼠标事件
msg = getmessage(EM_MOUSE | EM_KEY);//接收鼠标给的信息
if ((msg.x >= ROW * SIZE / 2 - 70) && (msg.x <= ROW * SIZE / 2 + 90) && (msg.y >= COL * SIZE / 2 + 90) && (msg.y <= COL * SIZE / 2 + 90 + 30))//鼠标区间
{
settextcolor(GREEN);
settextstyle(30, 0, L"微软雅黑");
outtextxy(SIZE * ROW / 2 - 70, SIZE * COL / 2 + 90, L"👉开始van游戏");
if (WM_LBUTTONDOWN == msg.message)//如果被按下
{
Van();
}
}
if ((msg.x >= ROW * SIZE / 2 - 70) && (msg.x <= ROW * SIZE / 2 + 50) && ((msg.y >= COL * SIZE / 2 + 130) && (msg.y <= COL * SIZE / 2 + 130 + 30)))
{
settextstyle(30, 0, L"微软雅黑");
settextcolor(GREEN);
outtextxy(SIZE * ROW / 2 - 70, SIZE * COL / 2 + 130, L"👉溜了溜了");
if (WM_LBUTTONDOWN == msg.message)
{
closegraph();
exit(0);
}
}
EndBatchDraw();
}
return 0;
}
2.3van()的部分
void Van()
{
HWND MineSweeper = initgraph(SIZE * ROW, SIZE * COL); //搭建窗口
SetWindowText(MineSweeper, L"扫雷"); //窗口命名
int mine[ROWS][COLS] = { 0 };//创建数组
Inint(mine);//初始=布雷+数雷+加密
//DWORD start, end;
//start = GetTickCount();
//CString str;
//int clock = 0;
//char a[100];
while (1)
{
Map(mine);//进入游戏的界面
ExMessage msg; //鼠标事件
msg = getmessage(EM_MOUSE | EM_KEY);;//接收鼠标给的信息
int x, y;
switch (msg.message)
{
case WM_RBUTTONDOWN://右键按下
x = msg.x / SIZE + 1;
y = msg.y / SIZE + 1;
if (mine[x][y] >= 19 && mine[x][y] <= 28)//是空白
{
if (mine[x][y] == 19)
{
count++;
}
mine[x][y] += 40;//标记
}
else if (mine[x][y] > 30)//是雷
{
mine[x][y] -= 40;//取消标记
}
Map(mine);//此处是为了增加游戏的流畅度
break;
case WM_LBUTTONDOWN://左键按下
x = msg.x / SIZE + 1;
y = msg.y / SIZE + 1;
if (mine[x][y] >= 19 && mine[x][y] <= 28)//空白区
{
if (20 == mine[x][y])//有0的地方
{
mine[x][y] -= 20;
count++;
Open(mine, x, y);//展开
}
else
{
mine[x][y] -= 20;
count++;
}
}
if (-1 == mine[x][y])
{
if (MessageBox(MineSweeper, L"踩雷!是否继续游戏?", L"提示", MB_YESNO) == IDYES)
{
//end = GetTickCount();
//str.Format(L"%d%s", clock,a);
//MessageBox(str,"提示",MB_OK);
main();
}
else
{
exit(0);
}
}
Map(mine);
break;
}
if (count == ROW * COL)//判断输赢
{
if (MessageBox(MineSweeper, L"游戏结束!您赢了\n是否返回菜单", L"提示", MB_YESNO) == IDYES)
{
count = 0;
main();
}
else
{
break;
}
}
}
}
2.4Inint()部分
void Inint(int mine[ROWS][COLS])
{
//置零
for (int i = 0; i < ROWS; i++)
{
for (int j = 0; j < ROWS; j++)
{
mine[i][j] = { 0 };
}
}
//种雷
int N = MINE;
while (N)
{
int x = rand() % ROW + 1;
int y = rand() % COL + 1;
if (0 == mine[x][y])
{
mine[x][y] = -1;
N--;
}
}
//数雷
for (int i = 1; i < ROW + 1; i++)
{
for (int j = 1; j < COL + 1; j++)
{
if (-1 != mine[i][j])
{
for (int m = i - 1; m <= i + 1; m++)
{
for (int n = j - 1; n <= j + 1; n++)
{
if (-1 == mine[m][n])
{
mine[i][j]++;
}
}
}
}
}
}
//简单加密
for (int i = 1; i < ROW + 1; i++)
{
for (int j = 1; j < COL + 1; j++)
{
mine[i][j] += 20;
}
}
}
2.5Map()部分
void Map(int mine[ROWS][COLS])
{
for (int i = 1; i < ROW + 1; i++)//forfor扫描游戏区
{
for (int j = 1; j < COL + 1; j++)
{
BeginBatchDraw();
if (-1 == mine[i][j])
{
putimage((i - 1) * SIZE, (j - 1) * SIZE, &img[10]);
}
else if (mine[i][j] >= 0 && mine[i][j] <= 8)
{
putimage((i - 1) * SIZE, (j - 1) * SIZE, &img[mine[i][j]]);
}
else if (mine[i][j] >= 19 && mine[i][j] <= 28)
{
putimage((i - 1) * SIZE, (j - 1) * SIZE, &img[9]);
}
else if (mine[i][j] > 30)
{
putimage((i - 1) * SIZE, (j - 1) * SIZE, &img[11]);
}
EndBatchDraw();
}
}
}
2.6Open()部分
void Open(int mine[ROWS][COLS], int m, int n)
{
Map(mine);
for (int i = m - 1; i <= m + 1; i++)
{
for (int j = n - 1; j <= n + 1; j++)
{
//保证是在游戏区
if (m > 0 && m < ROW + 1 && n >0 && n < COL + 1)
{
if (mine[i][j] > 20 && mine[i][j] <= 28)
{
mine[i][j] -= 20;
count++;
}
if (mine[i][j] == 20)
{
mine[i][j] -= 20;
count++;
Open(mine, i, j);//回调,因为你打开之后存在打开的数值还是0的情况
}
}
}
}
}
后记
扫雷参考大佬的代码因为经费不足而自己脚踏缝纫机做了土里土气的界面
在后期我会把剩下的功能一一补上,并且将part2部分进行真·详解思路