(本次复习依托扫雷游戏的编写,对前文所学图形库、函数、分支、循环、等内容进行复习,重点内容及相关说明如下)
1.扫雷游戏规则
本次扫雷游戏规则及要求为:要求绘制500*500的地图,共100个格子。要求在这100个格子里随机分布10个雷,在初始状态下,玩家见到全部被方块覆盖的地图。鼠标左键一次,如果按到雷则提示游戏结束,如果非雷,则显示这个点显示四周(包括对角)的雷的数量;鼠标右键用来标记该地点可能有雷的存在,再次点击旗子则撤销旗子。游戏胜利为全部点完全部数无雷区域,游戏结束标志为点到雷。
2.鼠标操作
MOUSEMSG 定义一个鼠标结构体(相当于定义一边变量)
以下内容可以用 msg.XXX 的方式使用(msg为定义的鼠标名,XXX为可替代名)
uMsg; // 当前鼠标消息
mkCtrl; // Ctrl 键是否按下
mkShift; // Shift 键是否按下
mkLButton; // 鼠标左键是否按下
mkMButton; // 鼠标中键是否按下
mkRButton; // 鼠标右键是否按下
x; // 当前鼠标 x 坐标
y; // 当前鼠标 y 坐标
wheel; // 鼠标滚轮滚动值 (120 的倍数)
相关的鼠标消息
// WM_MOUSEMOVE 鼠标移动
// WM_MOUSEWHEEL 鼠标滚轮拨动
// WM_LBUTTONDOWN 左键按下
// WM_LBUTTONUP 左键弹起
// WM_LBUTTONDBLCLK 左键双击
// WM_MBUTTONDOWN 中键按下
// WM_MBUTTONUP 中键弹起
// WM_MBUTTONDBLCLK 中键双击
// WM_RBUTTONDOWN 右键按下
// WM_RBUTTONUP 右键弹起
// WM_RBUTTONDBLCLK 右键双击
3.图形库
图形库的使用包括定义一个画板、加载图形库函数、关闭图形姐妹三个部分(组成要完整,不然无法正确使用)
定义一个画版:initgraph(numb1,numb2);
加载图形库函数:
加载图片:loadimage(&image[],L"文件位置“);
输出图片:putimage(numb1i,numb2j,&image[]);
(更多常见函数请见easyx库)
关闭图形界面:closegraph();
4.循环结构、分支结构、函数、数组
格式占位符的详细内容请见格式站位符文末
if语句、switch语句的详细内容请见分支结构
需要说明的是:
if语句有三种写法,else后不加条件,if的条件后直接加; 则表示无执行语句
switch语句的default:后可以加执行语句,表示其他条件都不满足的情况下执行(前提是,每个条件后都有break;)
while、for、do while 语句的详细说明请见循环结构
需要说明的是:
三目运算符与for有着相似的作用,但是for写起来更加直观、易懂
上述的循环结构和分支结构均可相互嵌套
函数的详细说明请见函数-基本函数-传参
需要说明的是:
如果定义了全局变量,那么在函数中只要使用了全局变量,那么只要全局变量发生变化,函数的下次执行会按照新的值进行
(后文会学通过指针改变实参的值,需要注意区别)
数组详细的说明请见数组说明
数组需要注意的是:
数组的赋值通常与for循环进行搭配
数组与指针还有部分交集,请见数组说明
5.说明
1.存在一个bug
实例中的代码运行以及说明本次复习所需内容已经满足,但是存在持续右键出错的bug,未改2
2.循环的起始值、数组的起始值
循环的起始值,特别是for循环是自己定义的,
数组的起始值,都从下标为0开始(也就是下标为0,是数组的第一个元素)
4.本次扫雷的关键点
理解扫雷,除了应具备上述基础知识以外,还应该了解扫雷的游戏规则及设计思路,这样在写起来才知道每一步在做什么
6.代码实例
#include<stdio.h>
#include<iostream>
#include<stdlib.h>
#include<time.h>
#include<easyx.h>
IMAGE image[12];
int map[10][10] = { 0 };
int flag = 0;//用于判断游戏是否结束
void inIt()
{
//加载图片
loadimage(&image[0], L"素材/数字0.jpg");
loadimage(&image[1], L"素材/数字1.jpg");
loadimage(&image[2], L"素材/数字2.jpg");
loadimage(&image[3], L"素材/数字3.jpg");
loadimage(&image[4], L"素材/数字4.jpg");
loadimage(&image[5], L"素材/数字5.jpg");
loadimage(&image[6], L"素材/数字6.jpg");
loadimage(&image[7], L"素材/数字7.jpg");
loadimage(&image[8], L"素材/数字8.jpg");
loadimage(&image[9], L"素材/雷.jpg");
loadimage(&image[10], L"素材/方块.jpg");
loadimage(&image[11], L"素材/红旗.jpg");
//用随机数生成10个雷
srand((unsigned)time(NULL));
int x, y;
for (int i = 0; i < 10; )
{
x = rand() % 10;
y = rand() % 10;
if (map[x][y] != -1)
{
map[x][y] = -1;
++i;
}
}
//计算每个格周围的雷数量
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j < 10; ++j)
{
if (map[i][j] == -1)
{
for (int q = i - 1; q < i + 1; ++q)
{
for (int w = j - 1; w < j + 1; ++w)
{
if (q >= 0 && q <= 10 && w >= 0 && w <= 10 && map[q][w] != -1)
{
map[q][w] += 1;
}
}
}
}
}
}
}
void draw()
{
for (int i = 0; i < 10; ++i)
{
for (int j = 0; j < 10; ++j)
{
switch (map[i][j])
{
case 10:putimage(50 * i, 50 * j, &image[0]); break;
case 11:putimage(50 * i, 50 * j, &image[1]); break;
case 12:putimage(50 * i, 50 * j, &image[2]); break;
case 13:putimage(50 * i, 50 * j, &image[3]); break;
case 14:putimage(50 * i, 50 * j, &image[4]); break;
case 15:putimage(50 * i, 50 * j, &image[5]); break;
case 16:putimage(50 * i, 50 * j, &image[6]); break;
case 17:putimage(50 * i, 50 * j, &image[7]); break;
case 18:putimage(50 * i, 50 * j, &image[8]); break;//前面为数字0-8
case 19:putimage(50 * i, 50 * j, &image[9]); break;//雷
case 21:putimage(50 * i, 50 * j, &image[11]); break;//红旗
default:putimage(50 * i, 50 * j, &image[10]); break;//方块
}
}
}
}
void play()
{
MOUSEMSG msg;
int i, j;
while (1)
{
msg = GetMouseMsg();
switch (msg.uMsg)
{
case WM_LBUTTONDOWN:
{
i = msg.x / 50;
j = msg.y / 50;
if (map[i][j] == 0)
{
for (int q = i - 1; q <= i + 1; ++q)
{
for (int w = j - 1; w <= j + 1; ++w)
{
if (q >= 0 && q <= 9 && w >= 0 && w < 10 && map[q][w] != -1)
{
if (map[q][w] <= 8)
{
map[q][w] += 10;
flag++;
}
}
}
}
}
else if (map[i][j] == -1)
{
flag = -1;
return;
}
else if (map[i][j] <= 8)
{
map[i][j] += 10;
flag++;
return;
}
}
break;
case WM_RBUTTONDOWN:
i = msg.x / 50;
j = msg.y / 50;
if (map[i][j] == 21)
{
putimage(50 * i, 50 * j, &image[10]);
map[i][j] = 0;
}
else
{
putimage(50 * i, 50 * j, &image[11]);
map[i][j] = 21;
}
break;
}
}
}
int main()
{
initgraph(500, 500);
inIt();
while (1)
{
draw();
play();
if (flag == -1)
{
if (MessageBox(GetHWnd(), L"GAMEOVER", L"您输了!", MB_RETRYCANCEL) == IDRETRY)
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
map[i][j] = 0;
}
}
inIt();
}
else
{
exit(0);
}
}
else if (flag == 10 * 10 - 3)//3个雷
{
if (MessageBox(GetHWnd(), L"太厉害了", L"你赢了", MB_YESNO) == IDYES)
{
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++)
{
map[i][j] = 0;
}
}
inIt();
}
else
{
exit(0);
}
}
}
system("pause");
closegraph();
return 0;
}