1.简介:xp经典小游戏-扫雷,(附源码);特点:雷的数量、位置随机,每胜利一局,视野扩大一圈,界面展示如下图:
2.语言、工具:C语言;visual studio或者vc 6.0都可以,需要easyX库,点击自行下载安装即可,里面也有教程,故此不再赘述,一些图片素材,声音素材;
3.原理:
设定一个N*N的数组,-1表示雷,0-8表示的是非雷位置周围雷的数量;
首先对数组先任意位置随机取随机个位置为-1,再对数组进行遍历,找出安全区周围雷的数量,数组元素值范围(-1~8);
将每个元素加20来对数组进行元素隐藏,数组元素值范围(19-28);
操作鼠标左键点击翻开则对数组元素值在19~28的元素减20,操作鼠标右键点击:标记则对数组元素值在19~28的元素加20,取消标记则对数组元素值在39~48的元素减20;
图形界面:准备图片素材,按元素值不同填充显示不同图片;
4.关键点:a.数组的操作处理及遍历;b.图形界面的绘制;c.获取鼠标信息;d.随机数;
5.代码实现:
a.用到的头文件:
#include
#include
#include//随机数srand
#include
#include
#pragma comment(lib,"winmm.lib")
b. 初始化游戏,获取随机数,随机填充雷,获取安全区附近的雷数量,隐藏雷
//初始化游戏
void game_init()
{
srand((unsigned int)time(NULL));//得到非伪随机数
//init matrix
for (int i = 0; i < K; i++)
{
for (int j = 0; j < K; j++)
map[i][j] = 0;
}
int a=0;
while (a >= 3*N||a <= N)//随机雷数量
a = rand() % (3*N);
//为后面方便,留空外框
//埋雷,-1 雷
for (int i = 0; i < a;)
{
int r = rand() % N + 1;//随机行(1~10)
int c = rand() % N + 1;//随机列
if (map[r][c] == 0)
{
map[r][c] = -1;
i++;
}
}
//得出其他元素的值--安全区周围的雷数
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
{
if (map[i][j] != -1)
for (int m = i - 1; m <= i + 1; m++)
for (int n = j - 1; n <= j + 1; n++)
{
if (map[m][n] == -1)
map[i][j] += 1;
}
}
//隐藏,点一下就减去20恢复
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
{
map[i][j] += 20;
}
hwnd = GetHWnd();
}
c.游戏窗口
//游戏窗口刷新
void window_set()
{
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
{
if (map[i + 1][j + 1] == -1)
{
putimage(i*SIZE, j*SIZE, &img[9]);//雷
}
else if (map[i + 1][j + 1] >= 0 && map[i + 1][j + 1] <= 8)//0~8,非雷
putimage(i*SIZE, j*SIZE, &img[map[i + 1][j + 1]]);
else if (map[i + 1][j + 1] >= 19 && map[i + 1][j + 1] <= 28)//19~28,隐藏的
putimage(i*SIZE, j*SIZE, &img[10]);
else if (map[i + 1][j + 1] >= 39 && map[i + 1][j + 1] <= 48)//29~38,标记
putimage(i*SIZE, j*SIZE, &img[11]);
}
}
d.点开的一个0后,自动把周围的翻开
/点0后,递归把周围的0打开
void openZero(int x, int y)
{
map[x][y] -= 20;
for (int i = x - 1; i <= x + 1; i++)
{
for (int j = y - 1; j <= y + 1; j++)
{
if (i >= 1 && i <= N&&j >= 1 && j <= N)
{
if (map[i][j] >= 19 && map[i][j] <= 28)
{
if (map[i][j] == 20)
openZero(i, j);
else
map[i][j] -= 20;
}
}
}
}
}
e.鼠标点击玩游戏
//鼠标点击玩游戏
void playGame()
{
MOUSEMSG msg = { 0 };//定义鼠标消息
msg = GetMouseMsg();//获取
switch (msg.uMsg)
{
case WM_LBUTTONDOWN:
if (map[msg.x / SIZE + 1][msg.y / SIZE + 1] == 20)//
openZero(msg.x / SIZE + 1, msg.y / SIZE + 1);
else if (map[msg.x / SIZE + 1][msg.y / SIZE + 1] >= 19 && map[msg.x / SIZE + 1][msg.y / SIZE + 1] <= 28)
map[msg.x / SIZE + 1][msg.y / SIZE + 1] -= 20;
break;
case WM_RBUTTONDOWN:
if (map[msg.x / SIZE + 1][msg.y / SIZE + 1] >= 19 && map[msg.x / SIZE + 1][msg.y / SIZE + 1] <= 28)
map[msg.x / SIZE + 1][msg.y / SIZE + 1] += 20;
else if (map[msg.x / SIZE + 1][msg.y / SIZE + 1] >= 39 && map[msg.x / SIZE + 1][msg.y / SIZE + 1] <= 48)
map[msg.x / SIZE + 1][msg.y / SIZE + 1] -= 20;
break;
}
}
f.游戏主循环
while (1)
{
int num = 0;
window_set();
playGame();
//如果矩阵里出现-1,就结束了
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= N; j++)
{
if (map[i][j] == -1)
{
window_set();
for (int t = 1; t <= N; t++)
{
for (int p = 1; p <= N;p++)
{
if (map[t][p] == 19)
map[t][p] -= 20;
else if (map[t][p] == 39)
map[t][p] -= 40;
mciSendString(L"open ./res/start.wav alias BGM", 0, 0, 0);
mciSendString(L"play BGM", 0, 0, 0);
window_set();
Sleep(5);
}
}
MessageBox(hwnd, L"失败!", L"", MB_OK);
mciSendString(L"close BGM", NULL, 0, NULL);
return 0;//失败
}
}
}
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= N; j++)
{
if (map[i][j] == 19 || map[i][j] == 39)
{
num++;
}
if (map[i][j]>= 0 && map[i][j] < 9)
{
num++;
}
if (num == N*N)
{
window_set();
MessageBox(hwnd, L"VICTORY!", L"", MB_OK);
N++;
return 1;//成功
}
}
}
}
6.源代码
#include
#include
#include//随机数srand
#include
#include
#pragma comment(lib,"winmm.lib")
int N = 10;//雷最少的数量,横纵数量
#define K 50//足够大的数组
int map[K][K];//全局变量初始时是0
IMAGE img[12];
#define SIZE 50
HWND hwnd;
//初始化游戏
void game_init()
{
srand((unsigned int)time(NULL));//得到非伪随机数
//init matrix
for (int i = 0; i < K; i++)
{
for (int j = 0; j < K; j++)
map[i][j] = 0;
}
int a=0;
while (a >= 3*N||a <= N)//随机雷数量
a = rand() % (3*N);
//为后面方便,留空外框
//埋雷,-1 雷
for (int i = 0; i < a;)
{
int r = rand() % N + 1;//随机行(1~10)
int c = rand() % N + 1;//随机列
if (map[r][c] == 0)
{
map[r][c] = -1;
i++;
}
}
//得出其他元素的值--安全区周围的雷数
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
{
if (map[i][j] != -1)
for (int m = i - 1; m <= i + 1; m++)
for (int n = j - 1; n <= j + 1; n++)
{
if (map[m][n] == -1)
map[i][j] += 1;
}
}
//隐藏,点一下就减去20恢复
for (int i = 1; i <= N; i++)
for (int j = 1; j <= N; j++)
{
map[i][j] += 20;
}
hwnd = GetHWnd();
}
//游戏窗口刷新
void window_set()
{
for (int i = 0; i < N; i++)
for (int j = 0; j < N; j++)
{
if (map[i + 1][j + 1] == -1)
{
putimage(i*SIZE, j*SIZE, &img[9]);//雷
}
else if (map[i + 1][j + 1] >= 0 && map[i + 1][j + 1] <= 8)//0~8,非雷
putimage(i*SIZE, j*SIZE, &img[map[i + 1][j + 1]]);
else if (map[i + 1][j + 1] >= 19 && map[i + 1][j + 1] <= 28)//19~28,隐藏的
putimage(i*SIZE, j*SIZE, &img[10]);
else if (map[i + 1][j + 1] >= 39 && map[i + 1][j + 1] <= 48)//29~38,标记
putimage(i*SIZE, j*SIZE, &img[11]);
}
}
//点0后,递归把周围的0打开
void openZero(int x, int y)
{
map[x][y] -= 20;
for (int i = x - 1; i <= x + 1; i++)
{
for (int j = y - 1; j <= y + 1; j++)
{
if (i >= 1 && i <= N&&j >= 1 && j <= N)
{
if (map[i][j] >= 19 && map[i][j] <= 28)
{
if (map[i][j] == 20)
openZero(i, j);
else
map[i][j] -= 20;
}
}
}
}
}
//鼠标点击玩游戏
void playGame()
{
MOUSEMSG msg = { 0 };//定义鼠标消息
msg = GetMouseMsg();//获取
switch (msg.uMsg)
{
case WM_LBUTTONDOWN:
if (map[msg.x / SIZE + 1][msg.y / SIZE + 1] == 20)//
openZero(msg.x / SIZE + 1, msg.y / SIZE + 1);
else if (map[msg.x / SIZE + 1][msg.y / SIZE + 1] >= 19 && map[msg.x / SIZE + 1][msg.y / SIZE + 1] <= 28)
map[msg.x / SIZE + 1][msg.y / SIZE + 1] -= 20;
break;
case WM_RBUTTONDOWN:
if (map[msg.x / SIZE + 1][msg.y / SIZE + 1] >= 19 && map[msg.x / SIZE + 1][msg.y / SIZE + 1] <= 28)
map[msg.x / SIZE + 1][msg.y / SIZE + 1] += 20;
else if (map[msg.x / SIZE + 1][msg.y / SIZE + 1] >= 39 && map[msg.x / SIZE + 1][msg.y / SIZE + 1] <= 48)
map[msg.x / SIZE + 1][msg.y / SIZE + 1] -= 20;
break;
}
}
int game()
{
game_init();
while (1)
{
int num = 0;
window_set();
playGame();
//如果矩阵里出现-1,就结束了
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= N; j++)
{
if (map[i][j] == -1)
{
window_set();
for (int t = 1; t <= N; t++)
{
for (int p = 1; p <= N;p++)
{
if (map[t][p] == 19)
map[t][p] -= 20;
else if (map[t][p] == 39)
map[t][p] -= 40;
mciSendString(L"open ./res/start.wav alias BGM", 0, 0, 0);
mciSendString(L"play BGM", 0, 0, 0);
window_set();
Sleep(5);
}
}
MessageBox(hwnd, L"失败!", L"", MB_OK);
mciSendString(L"close BGM", NULL, 0, NULL);
return 0;//失败
}
}
}
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= N; j++)
{
if (map[i][j] == 19 || map[i][j] == 39)
{
num++;
}
if (map[i][j]>= 0 && map[i][j] < 9)
{
num++;
}
if (num == N*N)
{
window_set();
MessageBox(hwnd, L"VICTORY!", L"", MB_OK);
N++;
return 1;//成功
}
}
}
}
return 1;
}
void loadimg()
{
initgraph(N*SIZE, N*SIZE);
loadimage(&img[0], L"./res/0.jpg", SIZE, SIZE);
loadimage(&img[1], L"./res/1.jpg", SIZE, SIZE);
loadimage(&img[2], L"./res/2.jpg", SIZE, SIZE);
loadimage(&img[3], L"./res/3.jpg", SIZE, SIZE);
loadimage(&img[4], L"./res/4.jpg", SIZE, SIZE);
loadimage(&img[5], L"./res/5.jpg", SIZE, SIZE);
loadimage(&img[6], L"./res/6.jpg", SIZE, SIZE);
loadimage(&img[7], L"./res/7.jpg", SIZE, SIZE);
loadimage(&img[8], L"./res/8.jpg", SIZE, SIZE);
loadimage(&img[9], L"./res/9.jpg", SIZE, SIZE);
loadimage(&img[10], L"./res/10.jpg", SIZE, SIZE);
loadimage(&img[11], L"./res/11.jpg", SIZE, SIZE);
}
int main()
{
while (1)
{
loadimg();
int k = game();
}
return 0;
}