文章目录

  • 前言
    • 每日鸡汤
    • 基本思路
    • 衔接基础班扫雷
  • 准备阶段
  • 正文
    • 一.雷盘信息的存储
      • 1.设置雷盘11*11与初始化
      • 2.放置雷
      • 3.放置雷周围的信息
    • 二.图形化界面
      • 1.创建与初始化窗口
      • 2.加载图片
      • 3.放入图片
      • 4.加密格子
    • 三.鼠标点击
      • 1.具体步骤
      • 2.代码实现
    • 四.递归展开
      • 1.具体步骤
      • 2.代码实现
    • 五.判断输赢
      • 1.具体步骤
      • 2.代码实现
  • 六.设置音乐与点击音效
    • 1.播放音乐
    • 2.播放音效
    • 七.总结代码
      • 1.运行逻辑的代码:mine.cpp
      • 2.头文件代码:mine.h
      • 3.实现逻辑的代码:源.cpp
  • 总结

前言

每日鸡汤

 不为模糊不清的未来过分担忧,只为清清楚楚的现在奋发图强。

基本思路

衔接基础班扫雷

 如果思路不是特别清晰的兄弟,建议多看一下基础版扫雷:数组之实战篇——带你从0到1实现扫雷(简易版)
 如果EasyX图形库不是特别明白:可以看一下这篇文章:入门EasyX图形库(带你进入不一样的程序窗口,超详解)
或者B站我自己找的教程:史上最详细的easyx图形库入门讲解
 这一篇与上一章的部分思路相同:放置雷与初始化雷盘,不过由于我们的游戏界面为图形化界面我们的雷盘只需设置一个存放信息(雷和雷周围的信息),而且放雷的时候可以直接将雷的信息放在雷的周围更加方便,由于存放信息的雷盘只有一个,因此我们设置整形的数组会更加方便一些!

准备阶段

所需图片:

图片资源: 百度云盘,点击即可进去
提取码: 6666
防止字符集出现问题:

为了更好的理解下文我们先把头文件先给出:

#define _CRT_SECURE_NO_WARNINGS 1
#define ROWS 11//行
#define COLS 11//列
#define COL (ROWS-2)//打印的列,括号是为了防止运算冲突4
#define ROW (COLS-2)//打印的行
#define MINE 10
#include <graphics.h>//要包含在SIZE的前面,防止与里面的SIZE冲突。EasyX要用
#define SIZE 50
#include <stdio.h>
#include <time.h>//time函数的头文件,c++只能用这个
#include <stdlib.h>//srand和rand函数的头文件,c++只能用这个
#include <mmsystem.h>//播放音乐所用的头文件,是系统自带的
#pragma comment(lib,"winmm.lib")//加载静态库
//初始化函数
void Initboard(int board[ROWS][COLS],int rows, int cols,int m);
//打印函数
void Printboard(int board[ROWS][COLS], int row, int col);
//设置雷的函数
void Setmine(int board[ROWS][COLS], int row, int col);
//加载图片的函数
void loadimages();
//放图片的函数
void putimages(int board[ROWS][COLS], int row, int col);
//加密的函数
void password(int board[ROWS][COLS], int rows, int cols);
//鼠标信息的函数
void mouseimages(int board[ROWS][COLS]);
//判断输赢的函数
void judge(int mine[ROWS][COLS]);

正文

说明:我们先在实现的逻辑的源文件实现函数的功能,,最后我们再把功能汇总一下,这样逻辑比较顺。

一.雷盘信息的存储

1.设置雷盘11*11与初始化

作用:防止在排查雷时,数组越界。
说明:数组已经初始化,下面只是初始化雷盘的函数。
代码:

//这里四个参数的功能与基础篇相同
void Initboard(int board[ROWS][COLS], int rows, int cols, int m)
{int i = 0;int j = 0;for (i = 0; i < rows; i++){for (j = 0; j < cols; j++){board[i][j] = 0;}}
}

2.放置雷

注意:
1.在.cpp后缀的文件中引用time函数时只能用time.h
2.在.cpp后缀的文件中引用srand函数和rand函数时只能用stdlib.h
说明:下面的代码的随机数起点已经在项目开始时建立,下面是设置雷的函数
代码:

void Setmine(int board[ROWS][COLS], int row, int col)
{int count = 0;while (count<MINE){//随机坐标//横坐标,行int x = rand() % 9 + 1;//1——9//纵坐标,列int y = rand() % 9 + 1;if (board[x][y] == 0){board[x][y] = -1;//在雷的周围加1,下面的放置雷周围的信息会有说明mine_information(board,x,y);count++;}}
}

3.放置雷周围的信息

图解:

注意:是在每次放一个雷后在周围加一,到这就可理解上面的代码了。
代码:

//放置static的目的是将外部链接属性改为内部链接属性,使此函数只能在实现逻辑的
//源文件中进行使用,更为安全。
static void mine_information(int board[ROWS][COLS], int x, int y)
{int i = 0;int j = 0;for (i = x - 1; i <= x + 1; i++){for (j = y - 1; j <= y + 1; j++){if (i != x || j != y)//i与j不能同时为x和y{board[i][j] += 1;}}}
}

二.图形化界面

1.创建与初始化窗口

在main函数里面创建

int main()
{//创建一个9*50(宽),10*50(高),并且展示控制台窗口。initgraph((ROW) * SIZE, (COL+1) * SIZE, SHOWCONSOLE);//游戏的逻辑省去了,最后接上去getchar();closegraph();retuen 0;
}

2.加载图片

我们先把所需的图片加载之后才能进行使用,否则使用不了。
代码:

void loadimages()
{char fill[50] = "";int i = 0;for (i = 0; i < 12; i++){sprintf(fill, "./扫雷/%d.jpg", i);loadimage(&image[i], fill,SIZE,SIZE);//设置50*50的大小}loadimage(&image[12], "./扫雷/12.jpg",SIZE*ROW,SIZE);//设置450*50的大小
}

3.放入图片

如何放呢?
前九行放雷信息的图片,最后一行放雷的个数的图片。
尤其注意:行和列与横坐标和纵坐标的关系,将行和列转化成界面的纵坐标和横坐标,再放进去。

代码:

void putimages(int board[ROWS][COLS],int row, int col)
{putimage(0, ROW * SIZE, &image[12]);int i = 0;int j = 0;for (i = 1; i <= row; i++){//行为纵坐标for (j = 1; j <= col; j++){//列为横坐标int n = board[i][j];//方便书写if (n == -1){putimage((j - 1) * SIZE, (i - 1) * SIZE, &image[9]);}else if (n >= 0 && n <= 8){putimage((j - 1) * SIZE, (i - 1) * SIZE, &image[n]);}//加密之后else if (n >= 19 && n <= 28){putimage((j - 1) * SIZE, (i - 1) * SIZE, &image[10]);//加密格子}else if (n >= 39 && n <= 48){putimage((j - 1) * SIZE, (i - 1) * SIZE, &image[11]);//标记}}}
}

4.加密格子

 将格子加上20之后就将格子加密了,当你点击时,这个格子所对应的数组的元素减去二十,再把原来的图片(这个位置存储的信息)放上去即可。
代码:

void password(int board[ROWS][COLS], int rows, int cols)
{//将所有格子都加上20int i = 0;int j = 0;for (i = 0; i < rows; i++){for (j = 0; j < cols; j++){board[i][j] +=20;}}
}

三.鼠标点击

1.具体步骤

1.获取鼠标信息
2.将鼠标信息转化为数组下标
3.将鼠标信息进行分发
4.将情况分类进行解密与加密

2.代码实现

void mouseimages(int board[ROWS][COLS])
{if (MouseHit()){MOUSEMSG msg = GetMouseMsg();//列对应横坐标int col = msg.x / SIZE + 1;//行对应纵坐标int row = msg.y / SIZE + 1;int m = board[row][col];switch (msg.uMsg)//分发鼠标信息{case WM_LBUTTONDOWN:if (m >= 19 && m <= 48)//只有在这个范围才执行操作,否则会将这个格子弄没{board[row][col] -= 20;}//递归展开省略了break;case WM_RBUTTONDOWN:if (m >= 19 && m <= 28){board[row][col] += 20;}break;}}
}

四.递归展开

1.具体步骤

1.在为空格时,将周围的格子打开,且不为自身
2.打开的格子是加密的
3.加密的格子不是雷
4.如果为空继续调用

2.代码实现

static void  Nullarround(int board[ROWS][COLS], int x, int y)
{if (board[x][y] == 0)//判断是否为空白{int i = 0;int j = 0;for (i = x - 1; i <= x + 1; i++){for (j = y - 1; j <= y + 1; j++){if (i != x || j != y){if (board[i][j] != 19 && board[i][j] >= 9)//比没加密大就是加密的格子,且加密的格子不为雷{board[i][j] -= 20;Nullarround(board, i, j);//继续调用,为空格继续展开。}}}}}
}

五.判断输赢

1.具体步骤

 每次打开后都要判断一下,递归展开中也是。说明,这里如果输了或赢了,我们设置一个标志为flag为0,如果每次点击不为雷,那就加一,输了就设置为-1。
在赢或输之后我们就提示一下,是否要继续再开一把。

2.代码实现

void judge(int mine[ROWS][COLS])
{if (flag == -1){//失败int isok = MessageBox(GetHWnd(), "很遗憾!你输了!是否再来一把?", "提示", MB_OKCANCEL);if (isok == IDOK){flag = 0;//将游戏初始化,意思就是再开一把Initboard(mine, ROWS, ROWS, 0);Setmine(mine, ROW, COL);password(mine, ROWS, ROWS);}else{exit(5201314);//参数为随机数,退出程序。}}if (flag == ROW * COL - MINE){//胜利int isok = MessageBox(GetHWnd(), "很高兴!你赢了!是否再来一把?", "提示", MB_OKCANCEL);if (isok == IDOK){flag = 0;//将游戏初始化Initboard(mine, ROWS, ROWS, 0);Setmine(mine, ROW, COL);password(mine, ROWS, ROWS);}else{exit(5201314);//随机数}}
}

六.设置音乐与点击音效

入门EasyX的教程里面都有细说,如果不明白可以看一下教程,就在文章开头,点击即可进入。

1.播放音乐

代码:

    //初始化界面时要打开音乐mciSendString("open ./扫雷/卡农.mp3", 0, 0, 0);//打开音乐后要播放音乐mciSendString("play ./扫雷/卡农.mp3 repeat", 0, 0, 0);//游戏结束后要关闭音乐mciSendString("close ./扫雷/卡农.mp3 repeat", 0, 0, 0);

2.播放音效

说明:每次点击要播放,播放完或者下一次播放时关闭,要不然只会响一次。

     mciSendString("close ./扫雷/点击声音.wav", 0, 0, 0);mciSendString("open ./扫雷/点击声音.wav", 0, 0, 0);mciSendString("play ./扫雷/点击声音.wav", 0, 0, 0);

七.总结代码

1.运行逻辑的代码:mine.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include "mine.h"
int flag = 0;
int main()
{initgraph((ROW) * SIZE, (COL+1) * SIZE, SHOWCONSOLE);setbkcolor(WHITE);cleardevice();srand((unsigned int)time(NULL));int mine[ROWS][COLS] = { 0 };Initboard(mine, ROWS, ROWS, 0);Setmine(mine,ROW,COL);password(mine, ROWS, ROWS);Printboard(mine, ROW, COL);mciSendString("open ./扫雷/卡农.mp3", 0, 0, 0);mciSendString("play ./扫雷/卡农.mp3 repeat", 0, 0, 0);loadimages();//每次放图片,鼠标点击,与判断是否结束是循环。while (1){BeginBatchDraw();//批量开始绘图使图形更加的稳定putimages(mine, ROW, COL);FlushBatchDraw();//批量结束绘图使图形更加的稳定mouseimages(mine);judge(mine);//Printboard(mine, ROW, COL);}int ret = getchar();closegraph();
}

2.头文件代码:mine.h

#define _CRT_SECURE_NO_WARNINGS 1
#define ROWS 11
#define COLS 11
#define COL (ROWS-2)
#define ROW (COLS-2)
#define MINE 10
#include <graphics.h>//要包含在SIZE的前面,防止与里面的SIZE冲突。
#define SIZE 50
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
#include <mmsystem.h>
#pragma comment(lib,"winmm.lib")
void Initboard(int board[ROWS][COLS],int rows, int cols,int m);
void Printboard(int board[ROWS][COLS], int row, int col);
void Setmine(int board[ROWS][COLS], int row, int col);
void loadimages();
void putimages(int board[ROWS][COLS], int row, int col);
void password(int board[ROWS][COLS], int rows, int cols);
void mouseimages(int board[ROWS][COLS]);
void judge(int mine[ROWS][COLS]);

3.实现逻辑的代码:源.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include "mine.h"
IMAGE image[13];
extern int flag;
static void  Nullarround(int board[ROWS][COLS], int x, int y)
{if (board[x][y] == 0)//判断是否为空白{int i = 0;int j = 0;for (i = x - 1; i <= x + 1; i++){for (j = y - 1; j <= y + 1; j++){if (i != x || j != y){if (board[i][j] != 19 && board[i][j] >= 9)//比没加密大就是加密的格子{board[i][j] -= 20;flag++;Nullarround(board, i, j);//继续调用,为空格继续展开。}}}}}
}
static void mine_information(int board[ROWS][COLS], int x, int y)
{int i = 0;int j = 0;for (i = x - 1; i <= x + 1; i++){for (j = y - 1; j <= y + 1; j++){if ((i != x || j !=y)&&board[i][j]!=-1){board[i][j] += 1;}}}
}
void Initboard(int board[ROWS][COLS], int rows, int cols, int m)
{int i = 0;int j = 0;for (i = 0; i < rows; i++){for (j = 0; j < cols; j++){board[i][j] = 0;}}
}
void Printboard(int board[ROWS][COLS], int row, int col)
{system("cls");int i = 0;int j = 0;for (i = 1; i <= row; i++){for (j = 1; j <= col; j++){printf("%2d ",board[i][j]);}printf("\n");}
}
void Setmine(int board[ROWS][COLS], int row, int col)
{int count = MINE;while (count){//随机坐标//横坐标,行int x = rand() % 9 + 1;//1——9//纵坐标,列int y = rand() % 9 + 1;if (board[x][y] == 0){board[x][y] = -1;//在雷的周围加1mine_information(board,x,y);count--;} }
}
void loadimages()
{char fill[50] = "";int i = 0;for (i = 0; i < 12; i++){sprintf(fill, "./扫雷/%d.jpg", i);loadimage(&image[i], fill,SIZE,SIZE);}loadimage(&image[12], "./扫雷/12.png",SIZE*ROW,SIZE);
}
void putimages(int board[ROWS][COLS],int row, int col)
{putimage(0, ROW * SIZE, &image[12]);int i = 0;int j = 0;for (i = 1; i <= row; i++){//行为纵坐标for (j = 1; j <= col; j++){//列为横坐标int n = board[i][j];if (n == -1){putimage((j - 1) * SIZE, (i - 1) * SIZE, &image[9]);}else if (n >= 0 && n <= 8){putimage((j - 1) * SIZE, (i - 1) * SIZE, &image[n]);}//加密之后else if (n >= 19 && n <= 28){putimage((j - 1) * SIZE, (i - 1) * SIZE, &image[10]);//加密格子}else if (n >= 39 && n <= 48){putimage((j - 1) * SIZE, (i - 1) * SIZE, &image[11]);//标记}}}
}
//加密
void password(int board[ROWS][COLS], int rows, int cols)
{//将所有格子都加上20int i = 0;int j = 0;for (i = 0; i < rows; i++){for (j = 0; j < cols; j++){board[i][j] +=20;}}
}
void mouseimages(int board[ROWS][COLS])
{if (MouseHit()){MOUSEMSG msg = GetMouseMsg();//列对应横坐标int col = msg.x / SIZE + 1;//行对应纵坐标int row = msg.y / SIZE + 1;int m = board[row][col];switch (msg.uMsg)//分发鼠标信息{case WM_LBUTTONDOWN:if (m >= 19 && m <= 48){mciSendString("close ./扫雷/点击声音.wav", 0, 0, 0);mciSendString("open ./扫雷/点击声音.wav", 0, 0, 0);mciSendString("play ./扫雷/点击声音.wav", 0, 0, 0);board[row][col] -= 20;if (board[row][col] != -1){flag++;}else{flag = -1;break;}}//递归展开Nullarround(board, row, col);break;case WM_RBUTTONDOWN:if (m >= 19 && m <= 28){board[row][col] += 20;}break;}}
}
void judge(int mine[ROWS][COLS])
{if (flag == -1){//失败int isok = MessageBox(GetHWnd(), "很遗憾!你输了!是否再来一把?", "提示", MB_OKCANCEL);if (isok == IDOK){flag = 0;//将游戏初始化Initboard(mine, ROWS, ROWS, 0);Setmine(mine, ROW, COL);password(mine, ROWS, ROWS);}else{mciSendString("close ./扫雷/卡农.mp3", 0, 0, 0);exit(5201314);//随机数}}if (flag == ROW * COL - MINE){//胜利int isok = MessageBox(GetHWnd(), "很高兴!你赢了!是否再来一把?", "提示", MB_OKCANCEL);if (isok == IDOK){flag = 0;//将游戏初始化Initboard(mine, ROWS, ROWS, 0);Setmine(mine, ROW, COL);password(mine, ROWS, ROWS);}else{mciSendString("close ./扫雷/卡农.mp3", 0, 0, 0);exit(5201314);//随机数}}
}

效果:

总结

如果能认真看到这里,我坚信你能收获很多很多!也希望这篇文章能帮助到你,如果觉得不错,请点击一下不要钱的赞,如果有误请温柔的指出,在这里感谢大家了!

入门C语言第三话:数组之实战篇——扫雷(进阶版——图形化界面,递归展开,播放音乐与音效,标记取消雷,记录雷的个数,鼠标点击,文末附有完整代码)相关推荐

  1. 吴恩达机器学习python实现(6):SVM支持向量机(文末附完整代码)

    所有的数据来源:链接:https://pan.baidu.com/s/1vTaw1n77xPPfKk23KEKARA 提取码:5gl2 1 Support Vector Machines 1.1 Pr ...

  2. 【控制系统数字仿真与CAD——实验报告】实验三:离散相似法数字仿真(文末附完整代码 + 实验结果)

    一.实验目的 1. 了解离散相似法的基本原理 2. 掌握离散相似法仿真的基本过程 3. 应用离散相似法仿真非线性系统 4. MATLAB实现离散相似法的非线性系统仿真 5. 掌握SIMULINK仿真方 ...

  3. echarts 折现图和柱状图 样式修改 设置折线样式 背景(文末附带完整代码)

    1.设置折线图样式(修改后)(背景竖条纹间隔,去掉边框,设置折线和节点颜色,设置数据字体颜色) 设置折线样式: 设置折线图的背景样式: 2.设置柱状图样式(修改后) 设置柱子的样式 设置柱状图背景 完 ...

  4. python下载某短视频平台音视频、评论、点赞数(详细教程,文末附完整代码

    前言 整理一下python在抖音网页版的应用 以抓取一个视频及评论为例进行讲解 获取视频 url 随便找一个视频,点击进入详情,页面中地址栏里就是该视频的 url . 手机端复制链接后,先粘到浏览器地 ...

  5. echarts 三种数据双y轴显示 (文末附带完整代码)

    说明:网络引用echarts.js和直接下载echarts引用的样式可能会不一致,需要对折线的样式和字体进行修改的请参考我的另外一篇文章https://blog.csdn.net/Wangwangwa ...

  6. C语言--扫雷进阶版,实现周围坐标展开

    进阶版只需要再简单版的基础上增加一个能实现周围坐标展开的功能,并且改变判断是否胜利的条件. 简单版在之前的发布的文章中可看到 C语言实现简易扫雷小游戏_标仔22的博客-CSDN博客 如何能够实现坐标展 ...

  7. 利用pyecharts绘制新浪微博传播图(文末附完整代码地址)

    文章目录 任务 来龙去脉 过程 绘图代码 绘图参数分析 结点参数格式 联系参数格式 类别参数格式 总览 获取转发关系 构造数据结构 集成json文件 代码地址 任务 延续之前的爬虫任务,最初同学提出的 ...

  8. 【控制系统数字仿真与CAD——实验报告】实验四:黄金分割法最优化PI调节器参数(文末附完整代码 + 实验结果)

    一.实验目的 掌握控制系统计算机辅助设计的原理与方法: 掌握黄金分割法的基本原理: 掌握黄金分割法在参数优化中的应用: 掌握MATLAB的基本编程,实现闭环系统的数字仿真,并增加参数优化过程: 掌握M ...

  9. c# 批量mqtt_C#使用 MQTTnet 快速实现 MQTT 通信(文末有完整Demo下载)

    MQTT(一)C#使用 MQTTnet 快速实现 MQTT 通信(文末有完整Demo下载) 原创weixin_pwtank1983 发布于2018-02-03 10:22:24 阅读数 36681 收 ...

最新文章

  1. EMAIL发送系统(C#+基于SMTP认证) 2.0
  2. python使用matplotlib可视化、使用matplotlib可视化scipy.misc图像、自定义使用winter色彩映射、将不同亮度映射到不同的色彩
  3. TensorFlow 人脸识别实验 ImportError: No module named 'sklearn.model_selection'
  4. 服务发现存储仓库 etcd 使用简介
  5. libgit2 0.28.1 发布,纯 C 实现的可移植 Git 核心开发包
  6. 【图像超分辨率】End-to-End Super-Resolution for Remote-Sensing Images Using an Improved Multi-Scale Residual
  7. CSS3 2D 转换
  8. 十分钟上手 ES 2020 新特性
  9. 【Python3网络爬虫开发实战】1.5.2-PyMongo的安装
  10. 【ElasticSearch】ElasticSearch 中使用衰减函数来完美你的搜索结果
  11. 初涉SEO有感-房途网SEO
  12. windows 10 账号密码策略及规则
  13. python交通标志识别_利用pytorch实现交通标志识别
  14. Vue.js——前端模块化雏形和CommonJS——2020.12.9
  15. 51Talk-Level 7 Unit 2 L4
  16. viper12a电路图_viper12a电磁炉电路图
  17. 最新搜索引擎提交网站的入口及技巧
  18. 利用python绘制分析路易斯安那州巴吞鲁日市的人口密度格局
  19. lterator 迭代器 静态属性Symbol.iterator Symbol(Symbol.iterator)
  20. 基于Spring+SpringMVC+Mybatis分布式敏捷开发系统架构zhen项目

热门文章

  1. 计算机课程体系改革,试论改革教学内容和考试方式构建计算机公共课程体系
  2. 黑苹果更改时间命令_黑苹果Mac系统快捷键修改
  3. (一)固体密度的测量
  4. 前端学习之认识HTML
  5. SDRAM突发读写注意
  6. goahead用jst进行简单互动
  7. General error: 1366 Incorrect string value: '\xF0\x9F\x98\x8A' for column
  8. C++11中类数据成员初始化方法详解
  9. Word文字怎么复制粘贴
  10. 软件测试丨Git分支管理实操,搞定在线合并和本地合并