⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 saolei.cpp

📁 经典扫雷程序 和windows自带扫雷一模一样 供学习使用
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	fstream file;
	file.open( "SaoLei.txt", ios_base::out );                //ios_base::out丢弃当前的数据
	file << LeiQuWidth << ' ' << LeiQuHight << ' ' << LeiNum << ' ' << iSelection << ' ' 
		 << mark << ' ' << color << ' ' << sound << ' ' << herotime[0] << ' ' << herotime[1] << ' ' << herotime[2] << ' ' 
		 << heroname[0] << ' ' << heroname[1] << ' ' << heroname[2];
	file.close();
}

LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)               
//回调函数,由操作系统调用
{
	HDC         hdc ,hdcMem ;                                //设备环境描述表句柄
	PAINTSTRUCT ps ;                                         //绘图结构体
	static HINSTANCE   hInstance ;
	HPEN        hPen ;
	HMENU       hMenu ;

	static HBITMAP hBrick, hCounter, hFace;
	static int     cxClient, cyClient, cxBrick, cyBrick, cxCounter, cyCounter, cxFace, cyFace;
	static BITMAP  brick, counter, face;
	int            fwKeys, x, y, i, j;
	RECT           Rect ;
	static int     oldx = -1, oldy = -1;                   
	CHAR           buffer[255];

	switch (message)
	{
		case WM_CREATE: 
			//创建窗口
			hInstance = ((LPCREATESTRUCT) lParam) ->hInstance ;
			OpenFile();
			SendMessage (hwnd, WM_COMMAND, IDM_BEGIN, 0) ;   //将当前状态设置初始化文件里的参数

			cxBrick = brick.bmWidth ;
			cyBrick = brick.bmHeight / 16 ;
			cxCounter = counter.bmWidth ;
			cyCounter = counter.bmHeight / 12 ;	
			cxFace = face.bmWidth ;
			cyFace = face.bmHeight / 5 ;

			return 0 ;

		case WM_SIZE:   
			//获取客户区大小
			cxClient = LOWORD (lParam) ;
			cyClient = HIWORD (lParam) ;
			return 0 ;

		case WM_TIMER:  
			//计时器
			if (stop)
				return 0;
			if(sound)
				PlaySound (TEXT ("432.wav"), NULL, SND_FILENAME | SND_ASYNC) ;
			if (TmNum < 1000)                                          //计时器到999时停止
				TmNum++ ;

			Rect.left   = cxClient-15-3*cxCounter ;
			Rect.top    = 15 ;
			Rect.right  = cxClient-15;
			Rect.bottom = 15 + cyCounter ;
			InvalidateRect (hwnd, &Rect, TRUE);                        //更新计时器显示的数字
			return 0 ;

		case WM_PAINT:   
			//重绘
			hdc = BeginPaint (hwnd, &ps) ;                             //获取设备环境,必须与EndPaint成对使用
			hdcMem = CreateCompatibleDC (hdc) ;                        //必须与DeleteDC成对
			
			SetWindowPos (hwnd,NULL,0,0,26+cxBrick*LeiQuWidth,
				           114+cyBrick*LeiQuHight,SWP_SHOWWINDOW|SWP_NOMOVE | SWP_NOZORDER);  //改变窗口大小

			hPen = CreatePen (PS_SOLID, 5, RGB(255,255,255)) ;                          //用白、灰线画边框
			SelectObject (hdc, hPen) ;
			MoveToEx (hdc, cxClient, 0, NULL) ;
			LineTo (hdc, 0, 0) ;
			LineTo (hdc, 0, cyClient) ;
			hPen = CreatePen (PS_SOLID, 2, RGB(255,255,255)) ;
			SelectObject (hdc, hPen) ;
			MoveToEx (hdc, 10, cyClient-6, NULL) ;
			LineTo (hdc, cxClient-8, cyClient-6) ;
			LineTo (hdc, cxClient-8, 55) ;
			MoveToEx (hdc, 10, 45, NULL) ;
			LineTo (hdc, cxClient-8, 45) ;
			LineTo (hdc, cxClient-8, 10) ;
			hPen = CreatePen (PS_SOLID, 2, RGB(128,128,128)) ;
			SelectObject (hdc, hPen) ;
			MoveToEx (hdc, cxClient-10, 53, NULL) ;
			LineTo (hdc, 8, 53) ;
			LineTo (hdc, 8, cyClient-5) ;
			MoveToEx (hdc, 10, 45, NULL) ;
			LineTo (hdc, 10, 10) ;
			LineTo (hdc, cxClient-8, 10) ;

			FacePainter (hwnd, hdc, hdcMem, hFace, cxClient, cxFace, cyFace) ;        //画笑脸
			CounterPainter (hwnd, hdc, hdcMem, hCounter, cxCounter, cyCounter) ;      //画计数器
			TimerPainter (hwnd, hdc, hdcMem, hCounter, cxClient, cxCounter, cyCounter) ; //画计时器
			BrickPainter (hwnd, hdc, hdcMem, hBrick, cxBrick, cyBrick) ;              //画雷区

			DeleteDC (hdcMem) ;
			EndPaint (hwnd, &ps) ;
			return 0 ;

		case WM_LBUTTONUP:                                                      
			//左键抬起,布雷&翻砖
			x = LOWORD (lParam) ;
			y = HIWORD (lParam) ;

			if (!stop)                //游戏未结束
			{
				FcNum = SmileUp ;
				if(oldx != -1)         //撤销左键按下时的操作
				{					
					LeiQu[oldx][oldy] -= Blank;
					oldx = -1;
				}

			if ((x >= 10) && (x < 10+cxBrick*LeiQuWidth) && (y >= 55) && (y < 55+cyBrick*LeiQuHight)) //雷区内
			{
				x = (int ((x-10) / cxBrick));       //计算对应的数组中的坐标
				y = (int ((y-55) / cyBrick));			
								
	            if ( TmNum == 1000)                 //游戏还未开始,开始游戏
				{
					MineLayer();                    //布雷
					TmNum = 0 ;                     
					SetTimer(hwnd, ID_TIMER, 1000, NULL) ;//计数器开始以秒为单位计数									
				}				

				if ( LeiQu[x][y] < 50)               //砖可翻,递归翻砖
				{
					MineTurner (x, y) ;
					LeiTurn++;			            //每调用一次递归翻砖,已翻的砖数加1		
				}
				else if (LeiQu[x][y] == 100)        //踩到雷,爆炸
				{
					Exploder (x, y);
				}

				if(LeiTurn == LeiQuWidth*LeiQuHight-LeiNum)          //游戏成功
				{
					Succeed();                                        
					switch(iSelection)                              
						//非自定义,且破纪录,弹出输入名字对话框,并将名字和时间存在对应的英雄榜数组中,然后弹出英雄榜
					{
					case IDM_LOW:
						if (TmNum < herotime[0])
						{
							herotime[0] = TmNum ;
							DialogBox (hInstance,MAKEINTRESOURCE(IDD_HERO),hwnd,DefineProc);
							DialogBox (hInstance,MAKEINTRESOURCE(IDD_HEROLIST),hwnd,DefineProc);
						}
						break ;
					case IDM_MIDDLE:	
						if (TmNum < herotime[1])
						{
							herotime[1] = TmNum ;
							DialogBox (hInstance,MAKEINTRESOURCE(IDD_HERO),hwnd,DefineProc);
							DialogBox (hInstance,MAKEINTRESOURCE(IDD_HEROLIST),hwnd,DefineProc);
						}
						break ;
					case IDM_HIGH:		
						if (TmNum < herotime[2])
						{
							herotime[2] = TmNum ;
							DialogBox (hInstance,MAKEINTRESOURCE(IDD_HERO),hwnd,DefineProc);
							DialogBox (hInstance,MAKEINTRESOURCE(IDD_HEROLIST),hwnd,DefineProc);
						}
						break ;
					default:
						break;
					}						
				}
			}
			}

			if (FcNum == SmileDown)                                 //重新开始
			{
				FcNum = SmileUp ;
				SendMessage (hwnd, WM_COMMAND, IDM_BEGIN, 0) ;
			}

			InvalidateRect (hwnd, NULL, TRUE);
			
			return 0 ;

		case WM_LBUTTONDOWN: 
			//左键按下
			x = LOWORD (lParam) ;
			y = HIWORD (lParam) ;

			if (!stop)        //游戏未结束的情况下,左键按下雷区中未有标记的砖,砖显示为被翻开的样子(实未翻开),笑脸变为惊恐状
			{
			    if ((x >= 10) && (x < 10+cxBrick*LeiQuWidth) && (y >= 55) && (y < 55+cyBrick*LeiQuHight)) 
				{
				FcNum = Frighten ;                       //笑脸变为惊恐状
				Rect.left   = (cxClient-cxFace)/2 ;
			    Rect.top    = 15 ;
			    Rect.right  = (cxClient+cxFace)/2;
			    Rect.bottom = 15+cyFace ;
			    InvalidateRect (hwnd, &Rect, TRUE);

				x = (int ((x-10) / cxBrick));             //计算对应的数组中的坐标
				y = (int ((y-55) / cyBrick));
				
			    if (LeiQu[x][y]%100 == 0)                //未有标记
				{
					if ( (x != oldx) || (y != oldy) )
					{
						LeiQu[x][y] += Blank;            //显示为被翻开的样子
						Rect.left   = x*cxBrick+10 ;
			            Rect.top    = y*cxBrick+55 ;
			            Rect.right  = (x+1)*cxBrick+10;
			            Rect.bottom = (y+1)*cxBrick+55 ;
			            InvalidateRect (hwnd, &Rect, TRUE);
						oldx = x;
						oldy = y;
					}
				}
				}
			}

			if ((x >= (cxClient-cxFace)/2) && (x <= (cxClient+cxFace)/2) && (y >= 15) && (y <= 15+cyFace)) 
				//在笑脸区左键按下,笑脸显示被按下
			{
				FcNum = SmileDown ;
				Rect.left   = (cxClient-cxFace)/2 ;
			    Rect.top    = 15 ;
			    Rect.right  = (cxClient+cxFace)/2;
			    Rect.bottom = 15+cyFace ;
			    InvalidateRect (hwnd, &Rect, TRUE);
			}		
						
			return 0 ;

		case WM_MOUSEMOVE:                                                        
			//鼠标左键被按下时移动,显示的翻开的雷随着鼠标移动,或笑脸随着鼠标移动被按下或弹起
			fwKeys = wParam ;
			x = LOWORD (lParam) ;
			y = HIWORD (lParam) ;

			if (fwKeys == MK_LBUTTON)          //移动时鼠标左键被按下
			{
			    if (!stop)                         //游戏未结束
				{
				   if ((x >= 10) && (x < 10+cxBrick*LeiQuWidth) && (y >= 55) && (y < 55+cyBrick*LeiQuHight)) //雷区内
				   {
				      x = (int ((x-10) / cxBrick));
				      y = (int ((y-55) / cyBrick));

			          if (LeiQu[x][y]%100 == 0)                //砖未有标记
					  {
					       if ( (x != oldx) || (y != oldy) )
						   {
						        if ( oldx != -1 )
								{
						        	LeiQu[oldx][oldy] -= Blank;  //原来翻开的砖翻回去
						        	Rect.left   = oldx*cxBrick+10 ;
			                        Rect.top    = oldy*cxBrick+55 ;
			                        Rect.right  = (oldx+1)*cxBrick+10;
			                        Rect.bottom = (oldy+1)*cxBrick+55 ;
			                        InvalidateRect (hwnd, &Rect, TRUE);
								}
						        LeiQu[x][y] += Blank ;          //显示为被翻开的样子
						        Rect.left   = x*cxBrick+10 ;
			                    Rect.top    = y*cxBrick+55 ;
			                    Rect.right  = (x+1)*cxBrick+10;
			                    Rect.bottom = (y+1)*cxBrick+55 ;
			                    InvalidateRect (hwnd, &Rect, TRUE);
					        	oldx = x;
					        	oldy = y;
						   }
					  }
				   }
			       else                              //鼠标移动到雷区外,把原来翻开的砖翻回去
				   {
				        if ( oldx != -1 )
						{
				        	LeiQu[oldx][oldy] -= Blank;
				        	Rect.left   = oldx*cxBrick+10 ;
			                Rect.top    = oldy*cxBrick+55 ;
			                Rect.right  = (oldx+1)*cxBrick+10;
			                Rect.bottom = (oldy+1)*cxBrick+55 ;
			                InvalidateRect (hwnd, &Rect, TRUE);
				        	oldx = -1;
						}
				   }
				}

			    if ((x >= (cxClient-cxFace)/2) && (x <= (cxClient+cxFace)/2) && (y >= 15) && (y <= 15+cyFace)) 
				{
					FcNum = SmileDown ;         //点到笑脸上,笑脸显示为按下
				}
			    else                            //移到笑脸区外,笑脸变回笑(哭)脸

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -