游戏框架搭建

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/flyingsbird/article/details/79554024

1创建TetrisGame类

首先贴出游戏界面图:
俄罗斯方块游戏主界面
上图是俄罗斯方块游戏的主界面,从图中我们可以分解出以下部分:

  1. 游戏主界面边框
  2. 游戏方块显示区域
  3. 游戏方块显示区域网格线
  4. 游戏菜单区域
  5. 下一个方块提示区域边框
  6. 下一个方块提示区域
  7. 下一个方块提示区域网格线
  8. 游戏最高分显示区域边框
  9. 游戏最高分显示区域
  10. 游戏分数显示区域边框
  11. 游戏分数显示区域
  12. 游戏等级显示区域边框
  13. 游戏等级显示区域
  14. 游戏时间显示区域边框
  15. 游戏时间显示区域
  16. 游戏菜单文字

根据以上分析,将TetrisGame类的定义在TetrisGame.H文件中,下面是TetrisGame.H文件源码:

#ifndef _TETRISGAME_H_
#define _TETRISGAME_H_

#include <windows.h>

class TetrisGame
{
public:
    TetrisGame();   
    TetrisGame(HWND hwnd, int left, int top, int width, int high);
    ~TetrisGame();
    void SetRectFrame(int width, int high);
    void SetRectArea(int width, int high);
    void SetRectMenu(int width, int high);
    void SetRectNextFrame(int width, int high);
    void SetRectNextArea(int width, int high);
    void SetRectHighestRecordFrame(int width, int high);
    void SetRectHighestRecordArea(int width, int high);
    void SetRectGameScoreFrame(int width, int high);
    void SetRectGameScoreArea(int width, int high);
    void SetRectGameLevelFrame(int width, int high);
    void SetRectGameLevelArea(int width, int high);
    void SetRectGameTimeFrame(int width, int high);
    void SetRectGameTimeArea(int width, int high);
    void SetMenuFont(HDC hdc);
    void DrawGameInterface(HWND hwnd);

private:
    int     left;                   // 整个游戏区域的左边界
    int     top;                    // 整个游戏区域的上边界
    int     width;                  // 整个游戏区域的宽度
    int     high;                   // 整个游戏区域的高度
    HBRUSH  hBrushGameFrame;        // 整个游戏边框画刷
    HBRUSH  hBrushGameArea;         // 游戏方块区域画刷
    HBRUSH  hBrushGameMenu;         // 游戏菜单区域画刷
    HBRUSH  hBrushGameNextFrame;    // 游戏提示区域边框画刷
    HBRUSH  hBrushGameNextArea;     // 游戏提示方块区域画刷

    HPEN    hPenGridOfGameArea;     // 游戏方块区域的网格线画笔
    HPEN    hPenGridOfNextArea;     // 游戏提示区域的网格线画笔

    RECT    rectFrame;              // 整个游戏边框矩形
    RECT    rectArea;               // 游戏方块区域矩形
    RECT    rectMenu;               // 游戏菜单区域矩形
    RECT    rectNextFrame;          // 游戏提示区域边框矩形
    RECT    rectNextArea;           // 游戏提示方块区域矩形
    RECT    rectHighestRecordFrame; // 游戏最高分边框矩形
    RECT    rectHighestRecordArea;  // 游戏最高分数字区域矩形
    RECT    rectGameScoreFrame;     // 游戏分数边框矩形
    RECT    rectGameScoreArea;      // 游戏分数数字区域矩形
    RECT    rectGameLevelFrame;     // 游戏等级边框矩形
    RECT    rectGameLevelArea;      // 游戏等级数字区域矩形
    RECT    rectGameTimeFrame;      // 游戏时间边框矩形
    RECT    rectGameTimeArea;       // 游戏时间数字区域矩形

    int     RectAreaWidth;          // 每个小方块的宽度
    int     RectFrameHight;         // 信息提示边框高度
    int     NextFrameWidth;         // 下一个方块提示边框宽度
    int     VerticalDistanceOfCom;  // 游戏菜单区域各个提示边框距离

    LOGFONT     lfGameMenu;             // 游戏菜单字体类型
    CHOOSEFONT  cfGameMenu;             // 游戏菜单字体类型选择
};

#endif

为了方便读者理解和博客撰写,这里只是分析了主界面绘制所需的元素,后面会逐步添加其他成员变量和功能函数。

TetrisGame类的实现代码在TetrisGame.cpp文件中实现,下面是TetrisGame.cpp文件源码:

#include "TetrisGame.h"

// 默认构造TetrisGame
TetrisGame::TetrisGame()
{

}

// 有参构造TetrisGame
// 
TetrisGame::TetrisGame(HWND hwnd, int left, int top, int width, int high)
{
    this->left  = left;     // 整个游戏区域的左边界
    this->top   = top;      // 整个游戏区域的上边界
    this->width = width;    // 整个游戏区域的宽度
    this->high = high;      // 整个游戏区域的高度

    hBrushGameFrame     = CreateSolidBrush(RGB(29, 32, 136));       // 创建整个游戏区域边框画刷
    hBrushGameArea      = CreateSolidBrush(RGB(160, 160, 160));     // 创建游戏方块区域画刷
    hBrushGameMenu      = CreateSolidBrush(RGB(49, 0, 74));         // 创建游戏菜单区域画刷
    hBrushGameNextFrame = CreateSolidBrush(RGB(126, 206, 244));     // 创建提示区边框画刷
    hBrushGameNextArea  = hBrushGameMenu;                           // 创建提示区画刷
    hPenGridOfGameArea  = CreatePen(PS_SOLID, 2, RGB(69, 69, 214)); // 创建游戏区域网格线画笔
    hPenGridOfNextArea  = CreatePen(PS_SOLID, 2, RGB(5, 227, 235)); // 创建提示区域网格线画笔

    SetRectFrame(width, high);              // 设置整个游戏边框矩形结构体
    SetRectArea(width, high);               // 设置整个游戏方块区域矩形结构体
    SetRectMenu(width, high);               // 设置游戏菜单区域矩形结构体
    SetRectNextFrame(width, high);          // 设置游戏提示区域边框矩形结构体
    SetRectNextArea(width, high);           // 设置游戏提示方块区域矩形结构体
    SetRectHighestRecordFrame(width, high); // 设置游戏最高分边框矩形结构体
    SetRectHighestRecordArea(width, high);  // 设置游戏最高分数字区域矩形结构体
    SetRectGameScoreFrame(width, high);     // 设置游戏分数边框矩形结构体
    SetRectGameScoreArea(width, high);      // 设置游戏分数数字区域矩形结构体
    SetRectGameLevelFrame(width, high);     // 设置游戏等级边框矩形结构体
    SetRectGameLevelArea(width, high);      // 设置游戏等级数字区域矩形结构体
    SetRectGameTimeFrame(width, high);      // 设置游戏时间边框矩形结构体
    SetRectGameTimeArea(width, high);       // 设置游戏时间数字区域矩形结构体
}                                           

// 析构函数
TetrisGame::~TetrisGame()
{

}

// 设置整个游戏边框矩形结构体
void TetrisGame::SetRectFrame(int width, int high)
{
    rectFrame.left      = 0;
    rectFrame.top       = 0;
    rectFrame.right     = width - GetSystemMetrics(SM_CXBORDER) * 10;
    rectFrame.bottom    = high;
}

// 设置整个游戏方块区域矩形结构体
void TetrisGame::SetRectArea(int width, int high)
{
    rectArea.left   = width / 110;
    rectArea.top    = rectArea.left;
    rectArea.bottom = high - rectArea.left - GetSystemMetrics(SM_CYMENU) * 2;
    rectArea.right  = (rectArea.bottom - rectArea.top) / 2 + rectArea.left;
}

// 设置游戏菜单区域矩形结构体
void TetrisGame::SetRectMenu(int width, int high)
{
    rectMenu.left   = rectArea.right + rectArea.left;
    rectMenu.top    = rectArea.top;
    rectMenu.right  = rectFrame.right - rectArea.left * 2;
    rectMenu.bottom = rectArea.bottom;
}

// 设置游戏提示区域边框矩形结构体
void TetrisGame::SetRectNextFrame(int width, int high)
{
    RectAreaWidth           = (rectArea.right - rectArea.left) / 10;
    RectFrameHight          = RectAreaWidth + rectArea.left * 2;
    NextFrameWidth          = RectAreaWidth * 4 + rectArea.left * 2;
    VerticalDistanceOfCom   = ((rectArea.bottom - rectArea.top) - RectAreaWidth * 8 - rectArea.left * 10) / 6;

    rectNextFrame.left      = rectMenu.left + (rectMenu.right - rectMenu.left - NextFrameWidth) / 2;
    rectNextFrame.top       = rectArea.top + VerticalDistanceOfCom;
    rectNextFrame.right     = rectNextFrame.left + NextFrameWidth;
    rectNextFrame.bottom    = rectNextFrame.top + NextFrameWidth;
}

// 设置游戏提示方块区域矩形结构体
void TetrisGame::SetRectNextArea(int width, int high)
{
    rectNextArea.left   = rectNextFrame.left + rectArea.left;
    rectNextArea.top    = rectNextFrame.top + rectArea.left;
    rectNextArea.right  = rectNextArea.left + RectAreaWidth * 4;
    rectNextArea.bottom = rectNextArea.top + RectAreaWidth * 4;
}

// 设置游戏最高分边框矩形结构体
void TetrisGame::SetRectHighestRecordFrame(int width, int high)
{
    rectHighestRecordFrame.left     = rectNextFrame.left;
    rectHighestRecordFrame.top      = rectNextFrame.bottom + VerticalDistanceOfCom;
    rectHighestRecordFrame.right    = rectNextFrame.right;
    rectHighestRecordFrame.bottom   = rectHighestRecordFrame.top + RectFrameHight;
}

// 设置游戏最高分数字区域矩形结构体
void TetrisGame::SetRectHighestRecordArea(int width, int high)
{
    rectHighestRecordArea.left      = rectHighestRecordFrame.left + rectArea.left;
    rectHighestRecordArea.top       = rectHighestRecordFrame.top + rectArea.left;
    rectHighestRecordArea.right     = rectNextArea.right;
    rectHighestRecordArea.bottom    = rectHighestRecordArea.top + RectAreaWidth;
}

// 设置游戏分数边框矩形结构体
void TetrisGame::SetRectGameScoreFrame(int width, int high)
{
    rectGameScoreFrame.left     = rectNextFrame.left;
    rectGameScoreFrame.top      = rectHighestRecordFrame.bottom + VerticalDistanceOfCom;
    rectGameScoreFrame.right    = rectNextFrame.right;
    rectGameScoreFrame.bottom   = rectGameScoreFrame.top + RectFrameHight;
}

// 设置游戏分数数字区域矩形结构体
void TetrisGame::SetRectGameScoreArea(int width, int high)
{
    rectGameScoreArea.left      = rectNextFrame.left + rectArea.left;
    rectGameScoreArea.top       = rectGameScoreFrame.top + rectArea.left;
    rectGameScoreArea.right     = rectNextArea.right;
    rectGameScoreArea.bottom    = rectGameScoreArea.top + RectAreaWidth;
}

// 设置游戏等级边框矩形结构体
void TetrisGame::SetRectGameLevelFrame(int width, int high)
{
    rectGameLevelFrame.left     = rectNextFrame.left;
    rectGameLevelFrame.top      = rectGameScoreFrame.bottom + VerticalDistanceOfCom;
    rectGameLevelFrame.right    = rectNextFrame.right;
    rectGameLevelFrame.bottom   = rectGameLevelFrame.top + RectFrameHight;
}

// 设置游戏等级数字区域矩形结构体
void TetrisGame::SetRectGameLevelArea(int width, int high)
{
    rectGameLevelArea.left      = rectNextFrame.left + rectArea.left;
    rectGameLevelArea.top       = rectGameLevelFrame.top + rectArea.left;
    rectGameLevelArea.right     = rectNextArea.right;
    rectGameLevelArea.bottom    = rectGameLevelArea.top + RectAreaWidth;
}

// 设置游戏时间边框矩形结构体
void TetrisGame::SetRectGameTimeFrame(int width, int high)
{
    rectGameTimeFrame.left      = rectNextFrame.left;
    rectGameTimeFrame.top       = rectGameLevelFrame.bottom + VerticalDistanceOfCom;
    rectGameTimeFrame.right     = rectNextFrame.right;
    rectGameTimeFrame.bottom    = rectGameTimeFrame.top + RectFrameHight;
}

// 设置游戏时间数字区域矩形结构体
void TetrisGame::SetRectGameTimeArea(int width, int high)
{
    rectGameTimeArea.left   = rectNextFrame.left + rectArea.left;
    rectGameTimeArea.top    = rectGameTimeFrame.top + rectArea.left;
    rectGameTimeArea.right  = rectNextArea.right;
    rectGameTimeArea.bottom = rectGameTimeArea.top + RectAreaWidth;
}

// 设置游戏菜单字体
void TetrisGame::SetMenuFont(HDC hdc)
{
    lstrcpy(lfGameMenu.lfFaceName, TEXT("新宋体"));
    lfGameMenu.lfHeight = RectAreaWidth * 3 / 4;
    lfGameMenu.lfWeight = FW_EXTRABOLD;
    cfGameMenu.lStructSize = sizeof(CHOOSEFONT);
    cfGameMenu.hwndOwner = NULL;
    cfGameMenu.hDC = NULL;
    cfGameMenu.lpLogFont = &lfGameMenu;
    cfGameMenu.iPointSize = 0;
    cfGameMenu.Flags = CF_INITTOLOGFONTSTRUCT | CF_SCREENFONTS | CF_EFFECTS;
    cfGameMenu.rgbColors = RGB(11, 223, 35);
    cfGameMenu.lCustData = 0;
    cfGameMenu.lpfnHook = NULL;
    cfGameMenu.lpTemplateName = NULL;
    cfGameMenu.hInstance = NULL;
    cfGameMenu.lpszStyle = NULL;
    cfGameMenu.nFontType = 0;
    cfGameMenu.nSizeMin = 0;
    cfGameMenu.nSizeMax = 0;

    SelectObject(hdc, CreateFontIndirect(&lfGameMenu));
    SetTextColor(hdc, cfGameMenu.rgbColors);
}

// 绘制游戏界面
void TetrisGame::DrawGameInterface(HWND hwnd)
{
    HDC hdc;                                            // 设备句柄

    hdc = GetDC(hwnd);                                  // 获取设备句柄
    SetMenuFont(hdc);
    MoveWindow(hwnd, left, top, width, high, TRUE);
    SetBkMode(hdc, TRANSPARENT);

    FillRect(hdc, &rectFrame, hBrushGameFrame);
    FillRect(hdc, &rectArea, hBrushGameArea);
    FillRect(hdc, &rectMenu, hBrushGameMenu);
    TextOut(hdc, rectMenu.left + rectArea.left, rectNextFrame.top - RectAreaWidth, TEXT("下一个方块:"),  6);
    FillRect(hdc, &rectNextFrame, hBrushGameNextFrame);
    FillRect(hdc, &rectNextArea, hBrushGameNextArea);
    TextOut(hdc, rectMenu.left + rectArea.left, rectHighestRecordFrame.top - RectAreaWidth, TEXT("最高记录:"), 5);
    FillRect(hdc, &rectHighestRecordFrame, hBrushGameNextFrame);
    FillRect(hdc, &rectHighestRecordArea, hBrushGameNextArea);
    TextOut(hdc, rectHighestRecordArea.left + RectAreaWidth / 25, rectHighestRecordArea.top + RectAreaWidth / 10, TEXT("0000000000"), 10);
    TextOut(hdc, rectMenu.left + rectArea.left, rectGameScoreFrame.top - RectAreaWidth, TEXT("游戏分数:"), 5);
    FillRect(hdc, &rectGameScoreFrame, hBrushGameNextFrame);
    FillRect(hdc, &rectGameScoreArea, hBrushGameNextArea);
    TextOut(hdc, rectGameScoreArea.left + RectAreaWidth / 25, rectGameScoreArea.top + RectAreaWidth / 10, TEXT("0000000000"), 10);
    TextOut(hdc, rectMenu.left + rectArea.left, rectGameLevelFrame.top - RectAreaWidth, TEXT("游戏等级:"), 5);
    FillRect(hdc, &rectGameLevelFrame, hBrushGameNextFrame);
    FillRect(hdc, &rectGameLevelArea, hBrushGameNextArea);
    TextOut(hdc, rectGameLevelArea.left + RectAreaWidth * 3 / 2, rectGameLevelArea.top + RectAreaWidth / 10, TEXT("00"), 2);
    TextOut(hdc, rectMenu.left + rectArea.left, rectGameTimeFrame.top - RectAreaWidth, TEXT("游戏时间:"), 5);
    FillRect(hdc, &rectGameTimeFrame, hBrushGameNextFrame);
    FillRect(hdc, &rectGameTimeArea, hBrushGameNextArea);
    TextOut(hdc, rectGameTimeArea.left + RectAreaWidth / 2, rectGameTimeArea.top + RectAreaWidth / 10, TEXT("00:00:00"), 8);
    SelectObject(hdc, hPenGridOfGameArea);
    for (int i = 1; i < 10; i++)
    {
        MoveToEx(hdc, i * RectAreaWidth + rectArea.left, rectArea.top, NULL);
        LineTo(hdc, i * RectAreaWidth + rectArea.left, rectArea.bottom);
    }
    for (int i = 1; i < 20; i++)
    {
        MoveToEx(hdc, rectArea.left, i * RectAreaWidth + rectArea.top, NULL);
        LineTo(hdc, rectArea.right, i * RectAreaWidth + rectArea.top);
    }

    SelectObject(hdc, hPenGridOfNextArea);
    for (int i = 1; i < 4; i++)
    {
        MoveToEx(hdc, i * RectAreaWidth + rectNextArea.left, rectNextArea.top, NULL);
        LineTo(hdc, i * RectAreaWidth + rectNextArea.left, rectNextArea.bottom);
    }
    for (int i = 1; i < 4; i++)
    {
        MoveToEx(hdc, rectNextArea.left, i * RectAreaWidth + rectNextArea.top, NULL);
        LineTo(hdc, rectNextArea.right, i * RectAreaWidth + rectNextArea.top);
    }
}

俄罗斯方块游戏程序主框架实现代码在MainFrame.h和MainFrame.cpp两个文件中,下面贴出这两个文件的源码:
MainFrame.h

#ifndef _MAINFRAME_H_
#define _MAINFRAME_H_

/****************************************
*         变量命名字首含义参照表          *
* --------------------------------------*
* c     | char或WCHAR或TCHAR             *
* by    | BYTE(无正负号字元)             *
* n     | short                         *
* i     | int                           *
* x, y  | int分别用作x,y坐标          *
* cx, cy| int分别用作x,y长度c代表计数器*
* b或f   | BOOL(int);f代表【旗标】     *
* w     | WORD(无正负号短整数)         *
* l     | LONG(长整数)                 *
* dw    | DWORD(无正负号长整数)            *
* fn    | function(函式)              *
* s     | string(字串)                    *
* sz    | 以位元组值0结尾的字符串      *
* h     | 代号                            *
* p     | 指针                            *
*****************************************/

#include <windows.h>
#include "TetrisGame.h"

TetrisGame *pTetrisGame;        // 创建俄罗斯方块游戏类指针

#endif

MainFrame.cpp


#include "MainFrame.h"


LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow)
{
    static TCHAR    szAppName[] = TEXT("俄罗斯方块");    // 应用程序名
    HWND            hwnd;               // 视窗代号
    MSG             msg;                // 讯息结构
    WNDCLASS        wndclass;           // 视窗类型结构

    wndclass.style          = CS_HREDRAW | CS_VREDRAW;
    wndclass.lpfnWndProc    = WndProc;
    wndclass.cbClsExtra     = 0;
    wndclass.cbWndExtra     = 0;
    wndclass.hInstance      = hInstance;
    wndclass.hIcon          = LoadIcon(NULL, IDI_APPLICATION);
    wndclass.hCursor        = LoadCursor(NULL, IDC_ARROW);
    wndclass.hbrBackground  = (HBRUSH)GetStockObject(WHITE_BRUSH);
    wndclass.lpszMenuName   = NULL;
    wndclass.lpszClassName  = szAppName;

    if (!RegisterClass(&wndclass))
    {
        MessageBox(NULL, TEXT("这个程序需要运行再Windows NT!操作系统上!"), szAppName, MB_ICONERROR);
    }

    hwnd = CreateWindow(szAppName, 
                        szAppName,
                        WS_OVERLAPPEDWINDOW,
                        CW_USEDEFAULT, CW_USEDEFAULT,
                        CW_USEDEFAULT, CW_USEDEFAULT,
                        NULL, NULL, hInstance, NULL);

    ShowWindow(hwnd, iCmdShow);
    UpdateWindow(hwnd);

    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return msg.wParam;
}

LRESULT CALLBACK WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
    static int  cxScreen, cyScreen; // 屏幕分辨率
    static int  cxClient, cyClient; // 客户区域大小
    PAINTSTRUCT ps;         // 绘图结构
    HDC         hdc;        // 装置内容代号

    switch (message)
    {
    case WM_CREATE:
        cxScreen = GetSystemMetrics(SM_CXSCREEN);       // 获取屏幕横向分辨率
        cyScreen = GetSystemMetrics(SM_CYSCREEN);       // 获取屏幕纵向分辨率
        cxClient = cyScreen / 4 * 3;                    // 默认游戏窗口宽度
        cyClient = cxClient * 25 / 22;                  // 默认游戏窗口高度
        pTetrisGame = new TetrisGame(hwnd, (cxScreen - cxClient) / 2, (cyScreen - cyClient) / 2, cxClient, cyClient);
        return 0;

    case WM_PAINT:
        hdc = BeginPaint(hwnd, &ps);

        pTetrisGame->DrawGameInterface(hwnd);

        EndPaint(hwnd, &ps);
        return 0;
    case WM_CLOSE:
        PostQuitMessage(0);
        return 0;
    }

    return DefWindowProc(hwnd, message, wParam, lParam);
}

注意:

本工程是在Visual Studio2015中开发的

阅读更多

没有更多推荐了,返回首页