📄 bomb.c~
字号:
adry1 = adry+1;
break;
case 8:
adrx1 = adrx+1;
adry1 = adry-1;
break;
}
/*在方格范围内.如果某方向方格没有被遮盖,则已打开的方格个数变量加1*/
if (adrx1>=0 && adry1>=0 && adrx1<sg_boxnumx && adry1<sg_boxnumy
&& bom[adrx1][adry1].hit)
test_open++; /*已打开的方格个数变量加1*/
else /*在方格范围内.如果某方向方格文本框被显示,则地雷没有被标识为0*/
if(adrx>=0 && adry1>=0 && adrx1<sg_boxnumx && adry1<sg_boxnumy
&& !bom[adrx1][adry1].test)
flag_opened = 0;
i++; //下一个方向
} /*如果8个方向已打开的方格数等于方格内显示的数值,且地雷没有被标识*/
if ((test_open == bom[adrx][adry].value) && !flag_opened)
{ /*如果方格没有被打开,显示地雷*/
if (!Open (hWnd, adrx, adry))
BombOut (hWnd); /*已打开的方格数等于全部方格数减去地雷数,则完成任务*/
if (itime == (sg_boxnumx*sg_boxnumy-bombnum))
Finished(hWnd);
}
}
/***********************************************************名 称:DrawDigit()*功 能: 绘制0-9数字位图*入口参数: hWnd 窗口(或控件)句柄* buffer 字符串数组* CLOCK 时间*出口参数:无**********************************************************/
void DrawDigit(HDC hdc, char* buffer, int CLOCK)
{
int x;
PBITMAP bmp; //定义位图数据结构指针
/*如果是时间,定位在时间控件;否则,则定位在地雷数控件*/
if (CLOCK)
x = x_clock;
else
x = x_bomnum;
/*将0-9数字位图存入buffer数组*/
while(*buffer){
bmp = sg_bmpDigit + (*buffer - '0');
FillBoxWithBitmap(hdc, x, 0, 0, 0, bmp);
x += WIDTH_DIGIT;
buffer++;
}
}
/***********************************************************名 称:myLoadBitmap()*功 能: 从文件中加载位图资源*入口参数: bm 位图对象指针 * filename 图标文件名(可以包含路径)*出口参数: 加载成功返回图标句柄**********************************************************/
static int myLoadBitmap (BITMAP* bm, const char* filename)
{
char full_path [MAX_PATH + 1]; //定义位图路径变量
strcpy (full_path, "res/"); //图标文件夹名赋给路径变量
strcat (full_path, filename); //图标文件名加在路径名后
return LoadBitmap (HDC_SCREEN, bm, full_path); //返回图标句柄
}
/***********************************************************名 称:get_record_file ()*功 能: 从文件中取得最高记录*入口参数: 无*出口参数: 成功返回最高记录**********************************************************/
static char* get_record_file (void)
{
static char record_file [MAX_PATH + 1] = {'\0'}; //定义记录文件,空路径变量
/*如果文件为空,返回空*/
if (record_file [0] != '\0')
return record_file;
strcpy (record_file, getpwuid (getuid ()) ->pw_dir); /*如果路径变量最后一个字符('\0'前一个字符)不是'/',则追加'/'*/
if (record_file [strlen (record_file) - 1] != '/')
strcat (record_file, "/"); /*将最高分记录追加在路径变量后*/
strcat (record_file, ".highscore.bomb");
return record_file; //返回路径变量
}
/***********************************************************名 称:TestMyWinProc()*功 能: 主窗口过程函数,处理消息*入口参数:hWnd 当前窗口(即接收信息的窗口)的句柄* message 接收到的消息标识* wParam 消息参数1* lParam 消息参数2*出口参数: 返回相应的处理结果**********************************************************/
int TestMyWinProc(HWND hWnd, int message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
char bomn[30], seconds[30];
char buffer[256];
int i, j;
int ran1, ran2;
static RECT bombregion, face, onerect, bombnumber, clock;
static RECT winposition;
MAINWINCREATE CreateInfo; //定义主窗口
FILE* pHighscore; //定义高分记录文件形式
switch (message) {
/*MSG_CREATE窗口建立消息.当窗口成功建立后系统会产生此消息. *用户程序可以在此消息中处理一些变量的初始化,加载资源,建立子窗口等.*/
case MSG_CREATE: /*如果加载地雷位图失败,显示"bitmap error";否则地雷显示TRUE*/
if( myLoadBitmap(&bmpbom,"lei.bmp")<0)
fprintf(stderr,"bitmap error\n");
else
fValidbom = TRUE;
/*如果加载触雷笑脸位图失败,显示"bitmap error";否则触雷笑脸显示TRUE*/
if( myLoadBitmap(&bmpface,"face1.bmp")<0)
fprintf(stderr,"bitmap error\n");
else
fValidface = TRUE;
/*如果加载笑脸位图失败,显示"bitmap error";否则笑脸显示TRUE*/
if( myLoadBitmap(&bitmap1,"face.bmp")<0)
fprintf(stderr,"bitmap error\n");
else
fValid1 = TRUE;
/*如果加载地雷标识位图失败,显示"bitmap error";否则显示TRUE*/
if( myLoadBitmap(&bmpflag,"flag.bmp")<0)
fprintf(stderr,"bitmap error\n");
else
fValidflag = TRUE;
/*如果加载任务完成位图失败,显示"bitmap error";否则显示TRUE*/
if( myLoadBitmap(&bmpfinalface,"finished.bmp")<0)
fprintf(stderr,"bitmap error\n");
else
fValidfinalface = TRUE;
/*如果加载地雷标识错误位图失败,显示"bitmap error";否则显示TRUE*/
if( myLoadBitmap(&bmphitfalse,"hitfalse.bmp")<0)
fprintf(stderr,"bitmap error\n");
else
fValidhitfalse = TRUE;
/*加载0-9数字位图*/
for (i = 0; i < 10; i++){
sprintf(buffer, "%d.bmp", i); //将10个位图名存入buffer数组变量中
myLoadBitmap(sg_bmpDigit + i, buffer); //加载0-9数字位图
}
/*当有最高记录时,只读形式打开记录文件,将最高分数及姓名赋为最高记录变量*/
if ((pHighscore = fopen(get_record_file(),"r"))){
for (i = 0; i < 3; i++)
fscanf(pHighscore, "%d, %s",
&score[i].highscore, score[i].name);
fclose(pHighscore); //关闭文件
} /*否则最高记录分数为999,姓名为unknown*/
else
for (i = 0; i < 3; i++){
score[i].highscore = 999;
strcpy(score[i].name, "unknown");
}
/*SetTimer函数创建定时器.指定定时器标识号,定时时间.*当定时时间到达时,定时器将会产生MSG_TIMER消息,参数wParam保存了产生消息的定时器标识号;*然后重新运行,进行下次运行.当不需要使用定时器时,调用KillTimer函数删除定时器.*/
/*设置定时器ID_CLOCK,定时1s(1000/FREQ_CLOCK=100=1s)*/#ifdef _TIMER_UNIT_10MS
SetTimer(hWnd, ID_CLOCK, 1000/FREQ_CLOCK);
#else
SetTimer(hWnd, ID_CLOCK, FREQ_CLOCK);
#endif
/*PostMessage:将一条信息发送到指定窗口的消息队列中(并立即返回) *MSG_COMMAND消息标识;ID_NEW消息参数1;0消息参数2*/
PostMessage(hWnd,MSG_COMMAND,ID_NEW,0);
break;
/*MSG_COMMAND命令消息(对话框消息). *当选择下拉菜单功能,按下快捷键,单击按钮时系统会产生此消息,用户程序要做相应功能的操作. *wParam参数包含有子窗口标识符(即菜单项,控件ID)以及通知码,低位字为子窗口标识符,高位字为通知码. *lParam参数为控件窗口句柄*/
case MSG_COMMAND: /*如果点击了ID_ABOUT*/
if (LOWORD(wParam) == ID_ABOUT)
{ /*创建一个窗口*/
InitAbHostedCreateInfo(hWnd,&CreateInfo);
CreateMainWindow(&CreateInfo);
}
/*如果取得了控件ID_CLOSE*/
if (LOWORD(wParam) == ID_CLOSE)
{ /*发送关闭窗口命令消息(MSG_CLOSE)*/
PostMessage(hWnd, MSG_CLOSE, 0, 0);
}
/*如果取得了控件ID_HIGHSCORE*/
if (LOWORD(wParam) == ID_HIGHSCORE)
{ /*创建一个hHighscore主窗口*/
InitHighScoreCreateInfo(hWnd,&CreateInfo);
hHighscore = CreateMainWindow(&CreateInfo); /*显示最高分记录窗口*/
ShowWindow(hHighscore,SW_SHOW);
}
/*如果取得了控件ID_LARGE*/
if (LOWORD(wParam) == ID_LARGE)
{
bombnum = 99; //地雷数设为99
sg_boxnumx = 30; //每行30个方格
sg_boxnumy = 16; //每列16个方格
winwidth = WIDTH_LARGEWIN; //大小设为WIDTH_LARGEWIN
flag_size = 2; //标识设为第2个模式
GetWindowRect(hWnd, &winposition); //取得窗口矩形区域
MoveWindow(hWnd, winposition.left, winposition.top,
WIDTH_LARGEWIN, HEIGHT_LARGEWIN, FALSE); /*发送开始新游戏消息*/
PostMessage(hWnd, MSG_COMMAND, ID_NEW, 0);
} /*如果取得了控件ID_MIDDLE*/
if (LOWORD(wParam) == ID_MIDDLE)
{
bombnum = 40;
sg_boxnumx = 16;
sg_boxnumy = 16;
winwidth = WIDTH_MIDDLEWIN;
flag_size = 1;
GetWindowRect(hWnd, &winposition);
MoveWindow(hWnd, winposition.left, winposition.top,
WIDTH_MIDDLEWIN, HEIGHT_MIDDLEWIN, FALSE);
PostMessage(hWnd, MSG_COMMAND, ID_NEW, 0);
}
/*如果取得了控件ID_SMALL*/
if (LOWORD(wParam) == ID_SMALL)
{
bombnum = 10;
sg_boxnumx = 8;
sg_boxnumy = 8;
winwidth = WIDTH_SMALLWIN;
flag_size = 0;
GetWindowRect(hWnd, &winposition);
MoveWindow(hWnd, winposition.left, winposition.top,
WIDTH_SMALLWIN, HEIGHT_SMALLWIN, FALSE);
PostMessage(hWnd, MSG_COMMAND, ID_NEW, 0);
}
/*如果取得了控件ID_NEW*/
if (LOWORD(wParam) == ID_NEW)
{
bTimer = FALSE; //时间停止
second = 0; //时间为0s
itime = 0; //被打开的方格数为0
leftbombnum = bombnum; //剩余地雷数等于总的地雷数
flag_bombout = 0; //地雷没有被标识
flag_finished = 0; //没有完成
x_bomnum = winwidth / 6; //显示地雷数的位置
x_face = (winwidth*2) / 5; //显示笑脸的位置
x_clock = (winwidth*3) / 5; //显示时钟的位置 /*设置整体方格边框的最左上角x坐标*/
offsetx = (winwidth - WIDTH_BOX*sg_boxnumx)/2-2; /*设置时钟的矩形区域*/
SetRect (&clock, x_clock, 0,
x_clock + WIDTH_CLOCK, HEIGHT_CLOCK);
/*设置笑脸的矩形区域*/
SetRect (&face, x_face, 0,
x_face + WIDTH_FACE, HEIGHT_FACE);
/*设置方格矩形区域*/
SetRect (&bombregion, offsetx, HEIGHT_FACE,
WIDTH_BOX*sg_boxnumx+offsetx,
HEIGHT_BOX*sg_boxnumy+HEIGHT_FACE);
/*设置地雷数的矩形区域*/
SetRect (&bombnumber, x_bomnum, 0,
x_bomnum + WIDTH_BOMNUM, HEIGHT_BOMNUM);
//**************initial bom value**************
/*每个方格都被设为无数字方格*/
for (i = 0; i < sg_boxnumx; i++)
for (j = 0; j < sg_boxnumy; j++)
{ bom[i][j].flag = 0; //没有被标识地雷
bom[i][j].hit = FALSE; //没有被遮盖着
bom[i][j].value = 0; //没有数值
bom[i][j].test = FALSE; //文本框没有显示
bom[i][j].bombout = FALSE; //没有地雷
bom[i][j].error = FALSE; //没有出错
};
for (i = 0; i < (sg_boxnumx*sg_boxnumy); i++)
NoAdr[i].NY = FALSE; //设为无数值
/*随机循环设定地雷,直到等于地雷数*/
srandom( time(NULL)); //在时间开始之前设定
i = 0;
while( i < bombnum )
{
ran1 = random()%sg_boxnumx;
ran2 = random()%sg_boxnumy; /*如果没有被标识为地雷,就被标识,继续设置下一个*/
if(!bom[ran1][ran2].flag)
{
bom[ran1][ran2].flag = 1;
i++;
}
} ;
for (i = 0; i < sg_boxnumx; i++)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -