zoukankan      html  css  js  c++  java
  • C项目实践--贪吃蛇(2)

    12.按键处理

    函数名称:key_down

    函数功能:按键处理函数,主要包括:1.刚开始或结束时的按键处理,游戏开始时,按任意键进入游戏,游戏运行过程中按回车键是游戏的暂停或开始的切换键;2.游戏运行过程中,按上、下、左、右键对蛇移动的方向进行控制。具体实现如下:

    void key_down(WPARAM wParam)
    {
        if(state != game_run)
        {
            if(wParam == VK_RETURN)
            {
                //在游戏不是运行状态时按下回车键
                //则运行游戏
                switch(state)
                {
                case game_start:
                        state = game_run;
                        break;
                case game_pause:
                    state = game_run;
                    //state = game_pause;
                    break;
                case game_over:
                    new_game();
                    state = game_run;
                    break;
                }
            }
        }
        else{
            //否则在游戏运行状态下
            switch(wParam)
            {
            case VK_UP: //向上键
                //dirt表示蛇当前的移动方向,属于全局变量
                if(dirt != DOWN)
                {
                    dirt = UP;
                }
                break;
            case VK_LEFT: //左键
                if(dirt != RIGHT)
                {
                    dirt = LEFT;
                }
                break;
            case VK_RIGHT:
                if(dirt != LEFT)
                {
                    dirt = RIGHT;
                }
                break;
            case VK_DOWN:
                if(dirt != UP)
                {
                    dirt = DOWN;
                }
                break;
            case VK_RETURN:
                state = game_pause;
                break;
            }
        }
        //刷新绘图窗口
        InvalidateRect(gameWND , NULL , TRUE);
    }

    13.改变窗口大小

    函数名称:resize

    函数功能:改变窗口大小时将调用本函数,根据窗口现有的大小,改变内存位图和字体等的大小,以便窗口绘图时适应新的窗口尺寸。具体实现如下:

    void resize()
    {
        HDC hdc ;
        LOGFONT lf; //字体逻辑结构
     
        //根据窗口的大小改变内存位图的大小
        hdc = GetDC(gameWND);
        GetClientRect(gameWND,&clientRC);
        SelectObject(memDC,memBMOld);
        DeleteObject(memBM);
        memBM = CreateCompatibleBitmap(hdc,clientRC.right,clientRC.bottom);
        memBMOld = (HBITMAP)SelectObject(memDC,memBM);
     
        //根据窗口的大小改变大字体的大小
        DeleteObject(bigFont);
        memset(&lf,0,sizeof(LOGFONT));
        lf.lfWidth = (clientRC.right - clientRC.left) / CHARS_IN_LINE;
        lf.lfHeight = (clientRC.bottom - clientRC.top) / 4;
        lf.lfItalic = 1;
        lf.lfWeight = FW_BOLD;
        bigFont = CreateFontIndirect(&lf);
        //根据窗口的大小改变小字体的大小
        DeleteObject(smallFont);
        lf.lfHeight = clientRC.bottom / (ROWS + 2);
        lf.lfWidth = lf.lfHeight*3 / 4;
        lf.lfItalic = 0;
        lf.lfWeight = FW_NORMAL;
        smallFont = CreateFontIndirect(&lf);
     
        ReleaseDC(gameWND,hdc);
    }

    14.初始化

    函数名称:initialize

    函数功能:初始化游戏。具体实现如下:

    void initialize()
    {
        PAINTSTRUCT ps;
        LOGFONT lf;
        HDC hdc;
        int i;
     
        hdc = GetDC(gameWND);
        GetClientRect(gameWND,&clientRC); //取得客户区绘图窗口的大小
        memDC = CreateCompatibleDC(hdc); //创建内存DC
        memBM = CreateCompatibleBitmap(hdc,clientRC.right,clientRC.bottom);//创建内存位图
        memBMOld = (HBITMAP)SelectObject(memDC,memBM);
        blackBrush = CreateSolidBrush(BLACK);//创建画笔和字体等
        snakeBrush = CreateSolidBrush(GREEN);
        for(i = 0; i < FOOD_COUNT; i++)
        {
            foodBrush[i] = CreateSolidBrush(food_color[i]);
        }
        grayPen  = CreatePen(PS_SOLID , 1, GRAY);
        memset(&lf, 0, sizeof(LOGFONT));
        //设置字体属性
        lf.lfWidth = (clientRC.right- clientRC.left) / CHARS_IN_LINE;
        lf.lfHeight = (clientRC.bottom - clientRC.top) / 4;
        lf.lfItalic = 1;
        lf.lfWeight = FW_BOLD;
        bigFont = CreateFontIndirect(&lf);
        lf.lfHeight = clientRC.bottom / (ROWS + 2);
        lf.lfWeight = lf.lfHeight*3/4;
        lf.lfItalic = 0;
        lf.lfWeight = FW_NORMAL;
        smallFont = CreateFontIndirect(&lf);
        ReleaseDC(gameWND,hdc);
        EndPaint(gameWND,&ps);
    }

    15.释放资源

    函数名称:finalize

    函数功能:游戏结束之前,释放初始化游戏时创建的资源。具体实现如下:

    void finalize()
    {
        int i = 0;
        DeleteObject(blackBrush);
        DeleteObject(snakeBrush);
        for(i = 0; i < FOOD_COUNT; i++)
        {
            DeleteObject(foodBrush[i]);
        }
     
        DeleteObject(grayPen);
        DeleteObject(bigFont);
        DeleteObject(smallFont);
        SelectObject(memDC,memBMOld);
        DeleteObject(memBM);
        DeleteDC(memDC);
    }

    16.回调函数

    函数名称:WndProc

    函数功能:用来处理windows消息。具体实现如下:

    //响应Windows消息的回调函数,用来处理windows消息
    LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
    {
        switch(message)
        {
        case WM_SIZE: //改变窗口大小
            resize();
            return 0;
        case WM_ERASEBKGND:
            return 0;
        case WM_PAINT:  //绘制内存位图到窗口
            paint();
            return 0;
        case WM_KEYDOWN:
            key_down(wParam); //用户操作处理
            return 0;
        case WM_DESTROY:
            PostQuitMessage(0);
            return 0;
        }
        return DefWindowProc(hwnd, message, wParam, lParam);
    }

    17.程序入口

    函数名称:WinMain

    函数功能:Windows程序的入口,类似于DOS程序的main函数,所以这个函数名必须是WinMain。具体实现如下:

    int WINAPI WinMain(HINSTANCE  hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
    {
        MSG msg;
        WNDCLASS wndclass; //窗口类
     
        //窗口类属性
        wndclass.style = CS_HREDRAW | CS_VREDRAW;
        wndclass.lpfnWndProc = WndProc;
        wndclass.cbClsExtra = wndclass.cbWndExtra = 0;
        wndclass.hInstance = hInstance;
        wndclass.hIcon = LoadIcon(NULL,IDI_APPLICATION);
        wndclass.hCursor = LoadCursor(NULL,IDC_ARROW);
        wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
        wndclass.lpszMenuName  = NULL;
        wndclass.lpszClassName = APP_NAME;
        RegisterClass(&wndclass); //注册窗口类
        //创建窗口
        gameWND = CreateWindow(APP_NAME,
            APP_TITLE,
            WS_OVERLAPPEDWINDOW,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            CW_USEDEFAULT,
            NULL,NULL,
            hInstance, NULL);
        //初始化游戏资源
        initialize();
        //显示窗口
        ShowWindow(gameWND, iCmdShow);
        UpdateWindow(gameWND);//更新窗口
        new_game();//新游戏
        for(;;)//进入windows消息循环, 直到接收到退出消息为止
        {
            if(state == game_run)
            {
                run_game();
            }
            if(PeekMessage(&msg,NULL,0,0,PM_NOREMOVE))
            {
                if(GetMessage(&msg,NULL,0,0))
                {
                    TranslateMessage(&msg);
                    DispatchMessage(&msg);
                }else{
                    break;
                }
            }
        }
        finalize(); //释放资源
        return msg.wParam;//返回消息参数
     
    }
    自此整个项目功能基本实现完毕

    5.系统操作过程

    游戏运行后,首先进入欢迎主界面,如图:

    image

    在欢迎主界面中按任意键进入贪吃蛇游戏,游戏界面如图:

    image

    游戏结束界面如图:

    image

    6.总结与Bug记录

    Bug.1

    系统提示Char* 与LPCWSTR 不兼容,就是就在每个char*变量前加上(LPCWSTR)强制转换,就没有提示错误信息了,但是运行之后,发现字符串显示为乱码。 上网查资料其中有一方案说,通过右键项目属性将Unicode字符串更改为多字节字符串即可。按照执行,乱码解决。

    总结

    下一步待实现功能:

    1.随着贪吃蛇吃的食物的增多,应该适当加快其运动速度以增加游戏难度

    2.游戏桌面的大小应适应不同分辨率屏幕自动按相应大小显示,使得全屏时,游戏桌面及提示信息全部在同一屏幕上显示。

  • 相关阅读:
    array_map()与array_shift()搭配使用 PK array_column()函数
    Educational Codeforces Round 8 D. Magic Numbers
    hdu 1171 Big Event in HDU
    hdu 2844 poj 1742 Coins
    hdu 3591 The trouble of Xiaoqian
    hdu 2079 选课时间
    hdu 2191 珍惜现在,感恩生活 多重背包入门题
    hdu 5429 Geometric Progression 高精度浮点数(java版本)
    【BZOJ】1002: [FJOI2007]轮状病毒 递推+高精度
    hdu::1002 A + B Problem II
  • 原文地址:https://www.cnblogs.com/AI-Algorithms/p/3427580.html
Copyright © 2011-2022 走看看