当前位置:C++技术网 > 精选软件 > win32实现的最简单的打地鼠游戏

win32实现的最简单的打地鼠游戏

更新时间:2015-12-27 23:45:12浏览次数:1+次

    打地鼠游戏就是以随机数和命中检测的游戏,本来也是再简单不过的了。不过做的好的游戏,就用上了漂亮的图形画面,让游戏界面更加好看,再带上音效,效果就很棒。
    打地鼠游戏的核心就是一个随机和一个坐标检测。随机的是地鼠(目标矩形)的位置,鼠标单击后就得到当前的鼠标的坐标,然后检测坐标是否在地鼠头部的范围内。如果在这个范围内,就表示击中了,就要加分,同时播放击中的爆炸效果和圆形的击中效果。然后显示总分。

    我们先看看效果,运行的程序击中后有爆炸音效:

win32实现的最简单的打地鼠游戏效果

【win32实现的最简单的打地鼠游戏效果】
    我们在WM_CREATE消息即窗口创建时就启动计时器计时。在计时器消息里,不断的产生随即矩形的起点坐标,也就是左上角的坐标。然后右下角的坐标实际上就是控制矩形的大小,我们利用左上角的坐标加上宽度和高度来确定。这样就可以固定矩形的大小。然后就是让客户区实现,让WM_PAINT消息来绘制矩形。代码如下:
case WM_TIMER:
    GetClientRect(hwnd,&rectClient);
    rect.left = rand()%(rectClient.right-rectSize);
    rect.right = rect.left+rectSize;
    rect.top = rand()%(rectClient.bottom-rectSize);
    rect.bottom = rect.top+rectSize;
    InvalidateRect(hwnd,NULL,TRUE);
    return 0;
    在WM_PAINT消息中,我们要画出矩形,而矩形的范围则是在WM_TIMER消息中已经确定,所以只需要画出来即可。然后还要显示总分。那么客户区绘制消息就这么多了。
    那么这样就解决了第一个核心问题即随机矩形位置的实现。下面一个就是检测是否命中。
    我们在鼠标左键单击消息WM_LBUTTONDOWN来做检测。首先需要获取鼠标的坐标,使用GET_X_LPARAM和GET_Y_LPARAM来提取坐标。然后就是要使用到一个检测函数PtInRect。这个函数是此游戏的第二个核心。
    PtInRect函数是检测一个点是否在一个矩形内部,第一个参数就是一个矩形的地址,第二个参数就是点POINT变量。如果点在矩形内,则返回真,否则返回假。这样就可以实现检测功能了。如果检测击中了,就使用PlaySound函数来播放爆炸音效。同时在矩形内画一个白色的椭圆。默认的填充颜色就是白色,所以调用Ellipse函数即可达到这个效果,而椭圆的参数就是矩形的四个参数咯。
    还要注意一个问题,PlaySound函数要正常使用,需要导入lib静态库。为了不增加项目的设置的麻烦,我们使用指令导入,即:
#pragma comment(lib,"WINMM.lib")
    这样你只要将这个完整的代码复制,就不用担心设置的问题。下面是完整的代码:
#include "windows.h"
#include "Windowsx.h"
#include <tchar.h>
#pragma comment(lib,"WINMM.lib")
// - 项目是Unicode字符集
LRESULT CALLBACK WinProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam)
{
    HDC hdc;
    PAINTSTRUCT ps;
    static int Sum=0;
    static RECT rect,rectClient;
    int rectSize=100;
    static TCHAR Msg[100]=_T("");
    SYSTEMTIME st;
    switch (message)
    {
    case WM_CREATE:
        SetTimer(hwnd,0,200,NULL);
        return 0;
     case WM_PAINT:
         hdc = BeginPaint(hwnd,&ps);
         SelectObject(hdc,GetStockObject(GRAY_BRUSH));
         Rectangle(hdc,rect.left,rect.top,rect.right,rect.bottom);
         wsprintf(Msg,_T("当前得分:%d"),Sum*100);
         TextOut(hdc,0,0,Msg,lstrlen(Msg));
         EndPaint(hwnd,&ps);
         return 0;
     case WM_LBUTTONDOWN:
         {
             hdc=GetDC(hwnd);
             POINT pt;
             pt.x = GET_X_LPARAM(lParam);
             pt.y = GET_Y_LPARAM(lParam);
             if(PtInRect(&rect,pt))
             {
                 Sum++;
                 PlaySound(_T("b.wav"),NULL,SND_FILENAME|SND_ASYNC);
                 Ellipse(hdc,rect.left,rect.top,rect.right,rect.bottom);
             }
             ReleaseDC(hwnd,hdc);
         }
         return 0;
    case WM_TIMER:
        GetClientRect(hwnd,&rectClient);
        rect.left = rand()%(rectClient.right-rectSize);
        rect.right = rect.left+rectSize;
        rect.top = rand()%(rectClient.bottom-rectSize);
        rect.bottom = rect.top+rectSize;
        InvalidateRect(hwnd,NULL,TRUE);
        return 0;
     case WM_DESTROY:
         PostQuitMessage(0);
         return 0;
     default:
         return DefWindowProc(hwnd, message, wParam, lParam);
    }
}

int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrev,LPSTR lpCmd,int iShow)
{
    TCHAR ClassName[] = _T("MyClass");
    TCHAR title1[] = _T("C++技术网http://www.cjjjs.com-打地鼠游戏简版");
    WNDCLASS wndClass;
    wndClass.cbClsExtra=0;
    wndClass.cbWndExtra=0;
    wndClass.hbrBackground= (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndClass.hCursor=LoadCursor(NULL,IDC_HAND);
    wndClass.hIcon=LoadIcon(NULL,IDI_APPLICATION);
    wndClass.hInstance = hInstance;
    wndClass.lpfnWndProc = WinProc;
    wndClass.lpszClassName = ClassName;
    wndClass.lpszMenuName=NULL;
    wndClass.style=CS_HREDRAW|CS_VREDRAW;

    if(!RegisterClass(&wndClass))return 0;
    HWND hwnd = CreateWindow(ClassName,title1,WS_OVERLAPPEDWINDOW,0,0,440,400,NULL,NULL,hInstance,NULL);
    ShowWindow(hwnd,SW_SHOWNORMAL);

    MSG msg;
    while (GetMessage(&msg,NULL,0,0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    return msg.wParam;
}