带爆炸效果的扫雷(源码1)

 这个程序是以前写的,编码水平一般,规范性、命名还可以,待改进的地方有很多,大家拷下来自己玩吧。第一次把我写的代码贴出来。ok,开始,先来个截图:

当鼠标单击的时候,有一个爆炸效果将格子炸开。程序简单说明:

包含了计时,等级设置(含自定义),帮助对话框,排行榜。

技术上没有用MFC,纯SDK做的。使用了两个定时器,一个表示成绩,一个播放动画。

算法:如果单击的是空白格子,那么周围所有相连的空白格子都会打开。需要一个队列来辅助搜索,像是数据结构里的图遍历。

键盘响应:用windows的消息处理,灵敏度可以满足需要。对“同时单击左键和右键”的处理方法是,在右键的处理程序中,判断左键是否按下。

对话框:控件的编程。当对话框打开时,计时器要停表;对话框结束后,恢复计时。

排行榜:三个字符串,跟三个数字,存到文件中。文件路径源码中有。

图片:自己画的,水平还行。源码:

主程序:mine.cpp

 

//  mine.cpp : Defines the entry point for the application.
//

#include 
" stdafx.h "
#include 
" resource.h "

#include 
" stdlib.h "
#include 
" stdio.h "

#include 
" map.h "
#include 
" mytimer.h "
#include 
" mytool.h "

#define  MAX_LOADSTRING 100

#define  BOTTOM_H 35  // 这个高度用在设置窗口大小的时候,包含标题栏的高度

//  Global Variables:
HINSTANCE hInst;                                 //  current instance
TCHAR szTitle[MAX_LOADSTRING];                                 //  The title bar text
TCHAR szWindowClass[MAX_LOADSTRING];                                 //  The title bar text

GameMap gamemap;
MYTIMER mytimer;
MYTOOL mytool;

int  screenwidth = 0 ;
int  screenheight = 0 ;

int  iradio = 0 ;

//  Foward declarations of functions included in this code module:
ATOM                MyRegisterClass(HINSTANCE hInstance);
BOOL                InitInstance(HINSTANCE, 
int );
LRESULT CALLBACK    WndProc(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK    About(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK    DlgSet(HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK DlgScore(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK DlgLevel(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);
LRESULT CALLBACK DlgInput(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam);

void  GameWin(HWND hWnd);

//  game
void  InitGame( void );


int  APIENTRY WinMain(HINSTANCE hInstance,
                     HINSTANCE hPrevInstance,
                     LPSTR     lpCmdLine,
                     
int        nCmdShow)
{
     
// TODO: Place code here.
    MSG msg;
    HACCEL hAccelTable;

    
// Initialize global strings
    LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
    LoadString(hInstance, IDC_MINE, szWindowClass, MAX_LOADSTRING);
    MyRegisterClass(hInstance);

    
// Perform application initialization:
    if (!InitInstance (hInstance, nCmdShow)) 
    
{
        
return FALSE;
    }


    hAccelTable 
= LoadAccelerators(hInstance, (LPCTSTR)IDC_MINE);

    
// Main message loop:
    while (GetMessage(&msg, NULL, 00)) 
    
{
        
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) 
        
{
            TranslateMessage(
&msg);
            DispatchMessage(
&msg);
        }

    }


    
return msg.wParam;
}




//
//   FUNCTION: MyRegisterClass()
//
//   PURPOSE: Registers the window class.
//
//   COMMENTS:
//
//     This function and its usage is only necessary if you want this code
//     to be compatible with Win32 systems prior to the 'RegisterClassEx'
//     function that was added to Windows 95. It is important to call this function
//     so that the application will get 'well formed' small icons associated
//     with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance)
{
    WNDCLASSEX wcex;

    wcex.cbSize 
= sizeof(WNDCLASSEX); 

    wcex.style            
= CS_HREDRAW | CS_VREDRAW;
    wcex.lpfnWndProc    
= (WNDPROC)WndProc;
    wcex.cbClsExtra        
= 0;
    wcex.cbWndExtra        
= 0;
    wcex.hInstance        
= hInstance;
    wcex.hIcon            
= LoadIcon(hInstance, (LPCTSTR)IDI_MINE);
    wcex.hCursor        
= LoadCursor(NULL, IDC_ARROW);
    wcex.hbrBackground    
= (HBRUSH)(RGB(0,255,0));
    
//wcex.lpszMenuName    = (LPCSTR)IDC_MINE;
    wcex.lpszMenuName    = NULL;
    wcex.lpszClassName    
= szWindowClass;
    wcex.hIconSm        
= LoadIcon(wcex.hInstance, (LPCTSTR)IDI_SMALL);

    
return RegisterClassEx(&wcex);
}


//
//    FUNCTION: InitInstance(HANDLE, int)
//
//    PURPOSE: Saves instance handle and creates main window
//
//    COMMENTS:
//
//         In this function, we save the instance handle in a global variable and
//         create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance,  int  nCmdShow)
{
    HWND hWnd;
    
    hInst 
= hInstance; // Store instance handle in our global variable
    
    hWnd 
= CreateWindow(szWindowClass, szTitle, 
        WS_OVERLAPPED 
| WS_SYSMENU |WS_MINIMIZEBOX   ,
        CW_USEDEFAULT, 
0400325, NULL, NULL, hInstance, NULL);
    
    
if (!hWnd)
    
{
        
return FALSE;
    }

    
    
    screenwidth 
= GetSystemMetrics(SM_CXFULLSCREEN);
    screenheight
= GetSystemMetrics(SM_CYFULLSCREEN);
    
/ game begin

    gamemap.LoadScore();

    gamemap.SetHINSTANCE(hInstance);
    gamemap.SetHWND(hWnd);
    gamemap.LoadPic();
    gamemap.SetLevel(
0);
    MoveWindow(hWnd,(screenwidth 
-(32*9+150))/2,
                    (screenheight 
-(32*9+70))/2,
                    
32*9+150,32*9+BOTTOM_H,true);
    
    mytimer.SetHWND(hWnd);
    mytimer.SetHINSTANCE(hInstance);
    mytimer.LoadPic();
    mytimer.Clear();
    mytimer.SetPos(
32*gamemap.GetWidth()+40,80);

    mytool.SetHWND(hWnd);
    mytool.SetHINSTANCE(hInstance);
    mytool.LoadPic();
    mytool.SetPos(
32*gamemap.GetWidth()+3032*gamemap.GetHeight()-32);

    SetTimer(hWnd,
2,150,NULL);
    InitGame();
    
    ShowWindow(hWnd, nCmdShow);
    UpdateWindow(hWnd);
    
    
return TRUE;
}


//
//   FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
//   PURPOSE:  Processes messages for the main window.
//
//   WM_COMMAND    - process the application menu
//   WM_PAINT    - Paint the main window
//   WM_DESTROY    - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    
int x,y;
    
int wmId, wmEvent;
    PAINTSTRUCT ps;
    HDC hdc;

    
switch (message) 
    
{
        
case WM_COMMAND:
            wmId    
= LOWORD(wParam); 
            wmEvent 
= HIWORD(wParam); 
            
// Parse the menu selections:
            switch (wmId)
            
{
                
case IDM_ABOUT:
                   DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
                   
break;
                
case IDM_EXIT:
                   DestroyWindow(hWnd);
                   
break;
                
default:
                   
return DefWindowProc(hWnd, message, wParam, lParam);
            }

            
break;
        
case WM_PAINT:
            hdc 
= BeginPaint(hWnd, &ps);
            
// TODO: Add any drawing code here...

            gamemap.SetDC(hdc);
            gamemap.Draw();
            gamemap.DrawAnimation();
            gamemap.DrawButton();
            
            mytimer.SetHDC(hdc);
            mytimer.Draw();

            mytool.SetHDC(hdc);
            mytool.Draw();

            EndPaint(hWnd, 
&ps);
            
break;

        
case WM_LBUTTONDOWN:
            x
=LOWORD(lParam);
            y
=HIWORD(lParam);
            
//按钮
            if(gamemap.button_pos.x<=&& x<=gamemap.button_pos.x+32
                
&& gamemap.button_pos.y<=&& y<=gamemap.button_pos.y+32)
            
{
                gamemap.iFaceState
=1;//press down
            }


            mytool.SetPressDown(x,y);

            
//雷的格子
            x/=32;
            y
/=32;
            
//当游戏没有结束的时候,允许单击格子
            if(gamemap.iState!=G_END)
            
{
                
if(x>=0 && x<=gamemap.GetWidth()-1 
                    
&& y>=0 && y<=gamemap.GetHeight()-1)
                
{
                        mytimer.StartTimer();
                        
if(gamemap.OpenGrid(x,y))
                        
{
                            
//fail
                            mytimer.StopTimer();
                        }

                }

            
                
if(gamemap.CheckWin())
                
{
                    GameWin(hWnd);
                }

            }

            InvalidateRect(hWnd,NULL,
false);
            
break;

        
case WM_LBUTTONUP:
            x
=LOWORD(lParam);
            y
=HIWORD(lParam);
            
//按钮
            if(gamemap.button_pos.x<=&& x<=gamemap.button_pos.x+32
                
&& gamemap.button_pos.y<=&& y<=gamemap.button_pos.y+32)
            
{
                gamemap.iFaceState
=0;//NORMAL
                
//RESET MAP
                InitGame();
                mytimer.Clear();
                mytimer.StopTimer();
            }

            InvalidateRect(hWnd,NULL,
false);

            
switch(mytool.GetButtonPress(x,y))
            
{
            
case E_LEVEL:
                mytimer.PauseTimer();
                DialogBox(hInst, (LPCTSTR)IDD_DIALOG_LEVEL, hWnd, (DLGPROC)DlgLevel);

                MoveWindow(hWnd,
                            (screenwidth 
-(32*gamemap.GetWidth()+150))/2,
                            (screenheight 
-(32*gamemap.GetHeight()+70))/2,
                            
32*gamemap.GetWidth()+150,
                            
32*gamemap.GetHeight()+BOTTOM_H,true);

                mytimer.GoOnTimer();
                   InvalidateRect(hWnd,NULL,
true);
                
break;

            
case E_HELP:
                mytimer.PauseTimer();
                DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About);
                mytimer.GoOnTimer();
                
break;

            
case E_SCORE:
                mytimer.PauseTimer();
                DialogBox(hInst, (LPCTSTR)IDD_DIALOG_SCORE, hWnd, (DLGPROC)DlgScore);
                mytimer.GoOnTimer();
                
break;
            
default:
                
break;
            }

            
break;

        
case WM_RBUTTONUP:
            x
=LOWORD(lParam);
            y
=HIWORD(lParam);            

            x
/=32;
            y
/=32;
            
//当游戏没有结束的时候,允许右击格子
            if(gamemap.iState!=G_END)
            
{
                
if(x>=0 && x<=gamemap.GetWidth()-1 
                    
&& y>=0 && y<=gamemap.GetHeight()-1)
                
{
                    gamemap.SetFlag(x,y);

                    
if(gamemap.CheckWin())
                    
{
                        GameWin(hWnd);
                    }

                }

            }

            InvalidateRect(hWnd,NULL,
false);
            
break;

        
case WM_RBUTTONDOWN:
            x
=LOWORD(lParam);
            y
=HIWORD(lParam);            

            x
/=32;
            y
/=32;
            
//当游戏没有结束的时候,允许右击格子
            if(gamemap.iState!=G_END)
            
{
                
if(wParam & MK_LBUTTON)
                
{
                    gamemap.Open8around(x,y);
                    
if(gamemap.CheckWin())
                    
{
                        GameWin(hWnd);
                    }

                }

            }

            InvalidateRect(hWnd,NULL,
false);
            
break;
            
        
case WM_TIMER:
            
switch(wParam)
            
{
            
case 1:                
                mytimer.TimerInc();
                
break;
            
case 2:                
                
break;
            }
            
            InvalidateRect(hWnd,NULL,
false);
            
break;
        
case WM_DESTROY:
            KillTimer(hWnd,
2);
            PostQuitMessage(
0);
            
break;
        
default:
            
return DefWindowProc(hWnd, message, wParam, lParam);
   }

   
return 0;
}


//  Mesage handler for about box.
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    
switch (message)
    
{
        
case WM_INITDIALOG:
                
return TRUE;

        
case WM_COMMAND:
            
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
            
{
                EndDialog(hDlg, LOWORD(wParam));
                
return TRUE;
            }

            
break;
    }

    
return FALSE;
}


void  InitGame( void )
{
    gamemap.CreateMap();
    gamemap.iState
=G_NULL;
    gamemap.iFaceState
=0;
}


LRESULT CALLBACK DlgSet(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    
int minnum=0;
    
int w;
    
int h;
    
int num;
    
char temp[50]={0};

    
switch (message)
    
{
        
case WM_INITDIALOG:
            SetDlgItemInt(hDlg,IDC_EDIT_WIDTH, gamemap.GetWidth(),FALSE);
            SetDlgItemInt(hDlg,IDC_EDIT_HEIGHT, gamemap.GetHeight() ,FALSE);
            SetDlgItemInt(hDlg,IDC_EDIT_NUM, gamemap.GetNum(), FALSE);

                
return TRUE;

        
case WM_COMMAND:
            
if (LOWORD(wParam) == IDOK)
            
{
                w
=GetDlgItemInt(hDlg,IDC_EDIT_WIDTH,NULL,FALSE);
                h
=GetDlgItemInt(hDlg,IDC_EDIT_HEIGHT,NULL,FALSE);
                num
=GetDlgItemInt(hDlg,IDC_EDIT_NUM,NULL,FALSE);

                
//用户自定义的界面大小
                w= (w<9)?9:w;
                w
= (w>20)?20:w;

                h
= (h<9)?9:h;
                h
= (h>20)?20:h;

                
//横向w个格子,纵向h个格子:
                
//限制雷的个数,最少:w和h中较小的值减一;最多,(w-1)*(h-1)
                minnum=(w>h)?h:w;
                num 
= (num< minnum-1)? minnum-1:num;
                num 
= (num>(w-1)*(h-1))? (w-1)*(h-1):num;

                gamemap.SetMap(w,h,num);
                InitGame();
                mytimer.Clear();

                mytimer.SetPos(
32*gamemap.GetWidth()+40,80);
                   mytool.SetPos(
32*gamemap.GetWidth()+3032*gamemap.GetHeight()-32);                
                
//MessageBox(hDlg,temp,"set",MB_OK);

                EndDialog(hDlg, LOWORD(wParam));                
                
return TRUE;
            }

            
else if(LOWORD(wParam) == IDCANCEL)
            
{
                EndDialog(hDlg, LOWORD(wParam));
                mytimer.GoOnTimer();
                
return TRUE;            
            }

            
break;
    }

    
return FALSE;
}



LRESULT CALLBACK DlgScore(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    
char temp[30]={0};
    
int i;
    
switch (message)
    
{
        
case WM_INITDIALOG:
                
for(i=0;i<=2;i++)
                
{
                    memset(temp,
0,sizeof(temp));
                    gamemap.GetName(i, temp);
                    
if(! strlen(temp))
                    
{
                        strcpy(temp,
"匿名");
                    }

                    SetDlgItemText(hDlg, IDC_STATIC_NAME1
+i, temp);

                    SetDlgItemInt(hDlg, IDC_STATIC_SCORE1
+i, 
                                    gamemap.GetTimeValue(i) ,
false);
                }

                
return TRUE;

        
case WM_COMMAND:
            
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
            
{
                EndDialog(hDlg, LOWORD(wParam));
                
return TRUE;
            }

            
switch(LOWORD(wParam))
            
{
            
case IDC_BUTTON_RESET1:
            
case IDC_BUTTON_RESET2:
            
case IDC_BUTTON_RESET3:
                i
=LOWORD(wParam)-IDC_BUTTON_RESET1;
                gamemap.ResetScore(i);
                SetDlgItemText(hDlg, IDC_STATIC_NAME1
+i, "匿名");
                SetDlgItemInt(hDlg, IDC_STATIC_SCORE1
+i, 999 ,false);
                
break;
            }

            
break;
            
return TRUE;
    }

    
return FALSE;
}



LRESULT CALLBACK DlgLevel(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    
switch (message)
    
{
        
case WM_INITDIALOG:
            iradio
= gamemap.GetLevel();
            CheckRadioButton(hDlg, 
                            IDC_RADIO_LEVEL1,
                            IDC_RADIO_LEVEL1
+2 , 
                            IDC_RADIO_LEVEL1
+iradio);
            
return TRUE;

        
case WM_COMMAND:
            
switch (LOWORD(wParam) )
            
{
            
case IDOK:
                
//MessageBox(hDlg,"set level ok","set dlg",MB_OK);
                gamemap.SetLevel(iradio);
                InitGame();
                mytimer.Clear();
                
                mytimer.SetPos(
32*gamemap.GetWidth()+40,80);
                   mytool.SetPos(
32*gamemap.GetWidth()+3032*gamemap.GetHeight()-32);

                EndDialog(hDlg, LOWORD(wParam));
                
return TRUE;
            
case IDCANCEL:
                EndDialog(hDlg, LOWORD(wParam));
                
return TRUE;
                
            
case IDC_RADIO_LEVEL1:
                iradio
=0;
                
return TRUE;
            
case IDC_RADIO_LEVEL2:
                iradio
=1;
                
return TRUE;
            
case IDC_RADIO_LEVEL3:
                iradio
=2;
                
return TRUE;

            
case IDC_BUTTON_SET:
                EndDialog(hDlg, LOWORD(wParam));
                DialogBox(hInst, (LPCTSTR)IDD_DIALOG_SET, hDlg, (DLGPROC)DlgSet);
                
return TRUE;
            
default:
                
return TRUE;
            }

            
            
break;
    }

    
return FALSE;
}




LRESULT CALLBACK DlgInput(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    
char temp[30]={0};

    
switch (message)
    
{
        
case WM_INITDIALOG:
            gamemap.GetName(gamemap.GetLevel(), temp);
            
if(! strlen(temp))
            
{
                strcpy(temp,
"匿名");
            }

            
            SetDlgItemText(hDlg, IDC_EDIT_INPUT ,temp);
            
return TRUE;

        
case WM_COMMAND:
            
if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL) 
            
{
                memset(temp,
sizeof(temp),0);
                
//处理输入的字符串,12个CHAR
                GetDlgItemText(hDlg,IDC_EDIT_INPUT,temp,13);

                gamemap.WriteScore(gamemap.GetLevel(), temp, mytimer.GetTimeLong());
                EndDialog(hDlg, LOWORD(wParam));
                
return TRUE;
            }

            
break;
    }

    
return FALSE;

}


void  GameWin(HWND hWnd)
{
    gamemap.iFaceState
=2;//win
    gamemap.iState=G_END;
    mytimer.StopTimer();

    
//已破纪录,输入姓名    
    if( gamemap.IsNewScore(gamemap.GetLevel(),
        mytimer.GetTimeLong()) )
    
{
        InvalidateRect(hWnd,NULL,
false);
        DialogBox(hInst, (LPCTSTR)IDD_DIALOG_INPUT, hWnd, (DLGPROC)DlgInput);
    }
                        
    
}


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值