直接贴代码,有时间再解释
main.c
#include "game.h"
HINSTANCE hInst;
int g = -1, m = 0;
char a[heng][shu] = {0}, b[heng][shu] = {0}, c[heng][shu] = {0};
LRESULT CALLBACK WndProc( HWND hWnd,
UINT message,
WPARAM wParam,
LPARAM lParam) {
PAINTSTRUCT ps;
HDC hdc;
int i,j,z;
int wmId, wmEvent;
static TCHAR szTextBuf[20];
static HPEN hPen; //画笔
static HBRUSH hBrush; //画刷
static HFONT hFont; //声明一个逻辑字体句柄为静态变量
static HWND hStatic;
static HWND hStaticBtn[10][10]; //展示的格子
switch(message) {
case WM_CREATE:
//创建画刷
hBrush = CreateSolidBrush( RGB(0x41, 0x96, 0x4F) );
//创建逻辑字体
hFont = CreateFont( -15/*高度*/, -7.5/*宽度*/, 0/*不用管*/, 0/*不用管*/, 400 /*一般这个值设为400*/,
FALSE/*不带斜体*/, FALSE/*不带下划线*/, FALSE/*不带删除线*/,
DEFAULT_CHARSET, //这里我们使用默认字符集,还有其他以 _CHARSET 结尾的常量可用
OUT_CHARACTER_PRECIS, CLIP_CHARACTER_PRECIS, //这行参数不用管
DEFAULT_QUALITY, //默认输出质量
FF_DONTCARE, //不指定字体族*/
TEXT("微软雅黑") //字体名
);
hPen = CreatePen(PS_SOLID, 2, RGB(255, 0, 0));
//创建静态文本控件
hStatic = CreateWindow(
TEXT("static"), //静态文本框的类名
TEXT("welcome 扫雷"), //控件的文本
WS_CHILD /*子窗口*/ | WS_VISIBLE /*创建时显示*/ | SS_CENTER /*带边框*/,
200 /*X坐标*/, 10/*Y坐标*/, 150/*宽度*/, 40/*高度*/, hWnd/*父窗口句柄*/,
(HMENU)101, hInst, /*当前实例句柄*/ NULL
);
for(i=0; i<10; i++) {
for(j=0; j<10; j++) {
z=i*10+j;
//创建按钮控件szTextBuf
wsprintf(szTextBuf, TEXT("%d"),z);
hStaticBtn[i][j] = CreateWindow(
// TEXT("button"), //按钮控件的类名
TEXT("static"), //按钮控件的类名
TEXT(" "),
WS_CHILD | WS_VISIBLE | WS_BORDER | BS_FLAT/*扁平样式*/,
120+j*33 /*X坐标*/, 60+i*33 /*Y坐标*/, 30 /*宽度*/, 30/*高度*/,
hWnd, (HMENU)z /*控件唯一标识符*/, hInst, NULL
);
}
}
SendMessage(hStatic,WM_SETFONT,(WPARAM)hFont, NULL);//设置文本框字体
for(i=0; i<10; i++) {
for(j=0; j<10; j++) {
SendMessage(hStaticBtn[i][j], WM_SETFONT, (WPARAM)hFont, NULL);//设置按钮字体
}
}
break;
case WM_KEYDOWN: {
if(wParam == VK_ESCAPE) //按下esc退出
DestroyWindow(hWnd);
break;
}
case WM_LBUTTONDOWN: {//左键
j = ( LOWORD(lParam) -120 ) / 33 + 1;
i = ( HIWORD(lParam) -60 ) / 33 + 1;
wsprintf(szTextBuf, TEXT("左键点击\n下标为 %d %d"),i,j);
SetWindowText(hStatic, szTextBuf);
if(i<=10 && i>0 && j<=10 && j>0) {
g = dianji(a, b, c, i, j);
}
dayin(a ,hStaticBtn );
if (g == 0) {
baozha(a, b);
dayin(a ,hStaticBtn );
MessageBox(hWnd, "很不幸,你点到了炸弹\n游戏结束", TEXT("失败"), MB_ICONINFORMATION);
DestroyWindow(hWnd);
}
break;
}
case WM_RBUTTONDOWN: {//右键
j = ( LOWORD(lParam) -120 ) / 33 + 1;
i = ( HIWORD(lParam) -60 ) / 33 + 1;
if(i<=(shu-2) && i>0 && j<=(heng-2) && j>0) {
a[i][j] = '?';
m++;
}
dayin(a ,hStaticBtn );
if (shengli(a, b, m ) == 1) {
MessageBox(hWnd, "游戏胜利", TEXT("胜利"), MB_ICONINFORMATION);
DestroyWindow(hWnd);
}
wsprintf(szTextBuf, TEXT("右键点击\n下标为 %d %d"),i,j);
SetWindowText(hStatic, szTextBuf);
break;
}
case WM_DESTROY: { //请做好善后工作
DeleteObject(hBrush);
DeleteObject(hFont);
DeleteObject(hPen);
PostQuitMessage(0);
break;
}
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) {
WNDCLASSEX wc;
HWND hwnd;
MSG msg;
memset(&wc,0,sizeof(wc));
wc.cbSize = sizeof(WNDCLASSEX);
wc.lpfnWndProc = WndProc;
wc.hInstance = hInstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
chushihua(b);//初始化炸弹和数字
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wc.lpszClassName = "WindowClass";
wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wc.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
if(!RegisterClassEx(&wc)) {
MessageBox(NULL, "Window Registration Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
return 0;
}
hwnd = CreateWindowEx(WS_EX_CLIENTEDGE,"WindowClass","Welcome-扫雷",WS_VISIBLE|WS_OVERLAPPEDWINDOW,
600, /* x */
150, /* y */
600, /* width */
500, /* height */
NULL,NULL,hInstance,NULL);
if(hwnd == NULL) {
MessageBox(NULL, "Window Creation Failed!","Error!",MB_ICONEXCLAMATION|MB_OK);
return 0;
}
while(GetMessage(&msg, NULL, 0, 0) > 0) {
TranslateMessage(&msg);
DispatchMessage(&msg); /* 向WndProc发送消息 */
}
return msg.wParam;
}
game.h(跟终端版相比,基本没变)
#include <stdio.h>
#include <stdlib.h> //这个是清屏函数所属函数库
#include <stdarg.h> //这个是可变入参头文件
#include <time.h> //这个函数库有产生时间戳的函数,产生随机数用
#include <windows.h> //延迟时间函数在这里,为了好看
#include <conio.h> //getch函数的头文件
#define heng (10 + 2) // 顾名思义,横着得,这个20可以随意更改代表扫雷界面的长
#define shu (10 + 2) // 顾名思义,竖着的,这个20同样随意更改,表示宽
#define lei 10 // 顾名思义,雷的数量哈哈哈哈
void denglu(); // 登录界面打印
void game(); // 游戏函数
void chushihua(char a[heng][shu]); // 初始化
void panduan(char b[heng][shu]); // 判断雷周围的数字
void xunzhao(char a[heng][shu], char b[heng][shu], char c[heng][shu], int i, int j);
// 寻找可以扩散的方块,即空白块和最边上的数字块
int dianji(char a[heng][shu], char b[heng][shu], char c[heng][shu], int i, int j);
// 点击图上的方块(当然是通过写坐标)
void baozha(char a[heng][shu], char b[heng][shu]); // 点到雷了,爆炸了
int shengli(char a[heng][shu], char b[heng][shu], int m ); // 胜利!!
void dayin(char a[heng][shu], HWND hStaticBtn[heng-2][shu-2]); // 胜利!!
game.c (跟终端版相比,基本没变)
#include "game.h"
void panduan(char b[heng][shu]) {
int i, j; // 记录每个方块的循环
int x, y; // 记录当前方块的数字
int c = 0; // 记录(雷周围的)数字大小
for (i = 1; i < heng - 1; i++)
for (j = 1; j < shu - 1; j++)
if (b[i][j] != '*') {
c = 0;
for (x = i - 1; x < i + 2; x++)
for (y = j - 1; y < j + 2; y++)
if (b[x][y] == '*')
c++, b[i][j] = c + 48;
}
}
void chushihua(char a[heng][shu]) {
int r = lei;
int i, j;
srand((unsigned int)time(NULL)); // 保证每次产生的雷都不一样
while (r) {
i = rand() % (heng - 2) + 1;
j = rand() % (shu - 2) + 1;
if (a[i][j] != '*') { // 雷可不能放重
a[i][j] = '*';
r--;
}
}
panduan(a);
}
void xunzhao(char a[heng][shu], char b[heng][shu], char c[heng][shu], int i, int j) {
int x, y;
if (i == 0 || j == 0 || i == heng - 1 || j == shu - 1)
; // 把最边上的都给屏蔽掉
else
for (x = i - 1; x < i + 2; x++)
for (y = j - 1; y < j + 2; y++)
if (c[x][y] == 0) { // 每个寻找过得位置都置‘1’,防止浪费栈的空间
c[x][y] = '1';
if (b[x][y] == 0) { // 空白块直接展开,并且寻找下一个
a[x][y] = '0';
xunzhao(a, b, c, x, y);
} else if (b[x][y] > '0' && b[x][y] < '9') // 数字块记录但是不再展开
a[x][y] = b[x][y];
}
}
int dianji(char a[heng][shu], char b[heng][shu], char c[heng][shu], int i, int j) {
if (b[i][j] == '*')
return 0;
else {
xunzhao(a, b, c, i, j);
return 1;
}
}
void baozha(char a[heng][shu], char b[heng][shu]) {
int i, j;
for (i = 0; i < heng; i++)
for (j = 0; j < shu; j++)
if (b[i][j] == '*')
a[i][j] = b[i][j];
}
int shengli(char a[heng][shu], char b[heng][shu], int m ) {
int i, j;
int s = 0;;
if (m == lei)
for (i = 1; i < heng; i++)
for (j = 1; j < shu; j++)
if (b[i][j] == '*' && a[i][j] == '?') // 雷的位置和标记位置一样
s++;
if (s == lei)
return 1;
else
return 0;
}
void dayin(char a[heng][shu], HWND hStaticBtn[heng-2][shu-2]) {
int i,j;
static TCHAR szTextBuf[5];
for(i=0 ; i<heng-2 ; i++) {
for(j=0 ; j<shu-2 ; j++) {
wsprintf(szTextBuf, TEXT("%c"),a[i+1][j+1]);
SetWindowText(hStaticBtn[i][j], szTextBuf);
if(a[i+1][j+1]=='0'){
SetBkColor(hStaticBtn[i][j], RGB(0x41, 0x96, 0x4F) );
}
}
}
}