zoukankan      html  css  js  c++  java
  • 游戏引擎及其间单实现

     
    游戏引擎负责处理各种琐碎事务:组件游戏,确保它正确运行及关闭它。将游戏分解为事件:
    下面这些事件只适用于任何游戏的部分核心事件:
        初始化
        启动
        结束
        激活
        停用
        绘制
        循环
     
    初始化事件在一开始运行游戏时发生,这时游戏执行重要的初始设置任务,包括创建游戏引擎本身。启动和结束事件对应于游戏的开始和结束,这时很适合执行与特定的游戏会话相关联的初始化和清理任务。在最小化游戏或者将其发送至后台,然后在恢复时,就将发生激活和停用事件。当游戏需要绘制自身时,将发送绘制事件,类似于WINDOWS WM_PAINT 消息。最后,循环事件使游戏执行一个单独的游戏周期,它非常重要。
     
    游戏的计时机制:游戏在指定的时间内运行的周期越多,看起来就越平滑。事实上,大多数游戏设置都在15 - 16周期每秒的范围内,最快的速度可能达到30周期每秒,比电影还快。除了极少数的一些情况外,应该力求达到的最低速度设置为12周期每秒。
    游戏引擎的类:
    #ifndef _GAMEENGINE_H
    #define _GAMEENGINE_H
    #include 
    <windows.h>

    //游戏事件
    BOOL GameInitialize(HINSTANCE hInstance);     //初始化
    void GameStart(HWND hWnd);                    //启动
    void GameEnd();                               //结束
    void GameActivate(HWND hWnd);                 //激活
    void GameDeactivate(HWND hWnd);               //停用
    void GamePaint(HDC hdc);                      //绘制
    void GameCycle();                             //循环


    //游戏引擎类
    class GameEngine
    {
    protected:
        
    static GameEngine * m_pGameEngine;        //指向自身的静态指针
        HINSTANCE           m_hInstance;          //实例句柄
        HWND                m_hWnd;               //窗口句柄
        TCHAR               m_szWndClass[32];     //窗口类名
        TCHAR               m_szTitle[32];        //标题
        WORD                m_wIcon,m_wSmallIcon; //大小图标
        int                 m_iWidth,m_iHeight;   //游戏区的宽和高
        int                 m_iFrameDelay;        //帧的延迟时间(ms)
        BOOL                m_bSleep;             //休眠状态
    public:
        GameEngine(HINSTANCE hInstance,LPTSTR szWndClass,LPTSTR szTitle,
                   WORD wIcon,WORD wSmallIcon,
    int iWidth=640,int iHeight=480);
        
    ~GameEngine();

        
    static GameEngine * GetEngine() return m_pGameEngine;};
        BOOL   Initialize(
    int iCmdShow);
        LRESULT HandlEvent(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);
        
        HINSTANCE   GetInstance() 
    return m_hInstance ;};
        HWND        GetWindow() 
    return m_hWnd;};
        
    void        SetWindow(HWND hWnd){ m_hWnd=hWnd ;};
        LPSTR       GetTitle()
    return m_szTitle ;};
        WORD        GetIcon() 
    return m_wIcon;};
        WORD        GetSmallIcon() 
    return m_wSmallIcon; };
        
    int         GetWidth() return m_iWidth;};
        
    int         GetHeight() return m_iHeight;};
        
    int         GetFrameDelay() return m_iFrameDelay ;};
        
    void        SetFrameDelay(int iFrameRate){ m_iFrameDelay=1000/iFrameRate;};
        BOOL        GetSleep()
    return m_bSleep;};
        
    void        SetSleep(BOOL bSleep){ m_bSleep=bSleep;};

    }
    ;

    LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam);

    #endif

    其实现文件如下:

    #include "GameEngine.h"

    //静态成员初始化
    GameEngine * GameEngine::m_pGameEngine=NULL;
    //构造成员函数
    GameEngine::GameEngine(HINSTANCE hInstance,LPSTR szWndClass,LPSTR szTitle,
                           WORD wIcon,WORD wSmallIcon,
    int iWidth,int iHeight)
    {
        m_pGameEngine
    =this;
        m_hInstance
    =hInstance;
        m_hWnd
    =NULL;
        
    if(lstrlen(szWndClass)>0)
            lstrcpy(m_szWndClass,szWndClass);
        
    if(lstrlen(szTitle)>0)
            lstrcpy(m_szTitle,szTitle);
        m_wIcon
    =wIcon;
        m_wSmallIcon
    =wSmallIcon;
        m_iWidth
    =iWidth;
        m_iHeight
    =iHeight;
        m_iFrameDelay
    =50;  //默认为20帧每妙
        m_bSleep=TRUE;
    }

    //析构成员函数
    GameEngine::~GameEngine()
    {
    }

    //引擎初始化
    BOOL GameEngine::Initialize(int iCmdShow)
    {
        WNDCLASSEX  wc;

        
    //创建主窗口的类
        wc.cbSize=sizeof(WNDCLASSEX);
        wc.style
    =CS_HREDRAW|CS_VREDRAW;
        wc.lpfnWndProc
    =WndProc;
        wc.cbClsExtra
    =0;
        wc.cbWndExtra
    =0;
        wc.hbrBackground
    =(HBRUSH)(COLOR_WINDOW+1);
        wc.hCursor
    =LoadCursor(NULL,IDC_ARROW);
        wc.hIcon
    =LoadIcon(m_hInstance,MAKEINTRESOURCE(GetIcon()));
        wc.hIconSm
    =LoadIcon(m_hInstance,MAKEINTRESOURCE(GetSmallIcon()));
        wc.hInstance
    =m_hInstance;
        wc.lpszClassName
    =m_szWndClass;
        wc.lpszMenuName
    =NULL;

        
    //注册窗口类
        if(!RegisterClassEx(&wc))
            
    return FALSE;
        
        
    //根据游戏大小计算窗口大小和位置
        int iWindowWidth=m_iWidth+GetSystemMetrics(SM_CXFIXEDFRAME)*2;
        
    int iWindowHeight=m_iHeight+GetSystemMetrics(SM_CYFIXEDFRAME)*2+GetSystemMetrics(SM_CYCAPTION);
        
    if(wc.lpszMenuName!=NULL)
            iWindowHeight
    +=GetSystemMetrics(SM_CYMENU);
        
    int iXWindowPos=(GetSystemMetrics(SM_CXSCREEN)-iWindowWidth)/2;
        
    int iYWindowPos=(GetSystemMetrics(SM_CYSCREEN)-iWindowHeight)/2;

        
    //创建窗口
        m_hWnd=CreateWindow(m_szWndClass,m_szTitle,WS_POPUPWINDOW|WS_CAPTION|WS_MINIMIZEBOX,iXWindowPos,iYWindowPos,
                            iWindowWidth,iWindowHeight,NULL,NULL,m_hInstance,NULL);
        
    if(!m_hWnd)
            
    return FALSE;
        
    //显示和更新窗口
        ShowWindow(m_hWnd,iCmdShow);
        UpdateWindow(m_hWnd);
        
        
    return TRUE;
    }

    //游戏消息处理函数
    LRESULT GameEngine::HandlEvent(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
    {
        
    switch(msg)
        
    {
        
    case WM_CREATE:
            
    //设置游戏窗口并开始游戏
            SetWindow(hWnd);
            GameStart(hWnd);
            
    return 0;
        
    case WM_SETFOCUS:
            
    //激活游戏并更新休眠状态
            GameActivate(hWnd);
            SetSleep(FALSE);
            
    return 0;
        
    case WM_KILLFOCUS:
            
    //停用游戏并更新休眠状态
            GameDeactivate(hWnd);
            SetSleep(TRUE);
            
    return 0;
        
    case WM_PAINT:
            HDC hDc;
            PAINTSTRUCT ps;
            hDc
    =BeginPaint(hWnd,&ps);
            
    //绘制游戏
            GamePaint(hDc);
            EndPaint(hWnd,
    &ps);
            
    return 0;
        
    case WM_DESTROY:
            
    //结束游戏
            GameEnd();
            PostQuitMessage(
    0);
            
    return 0;
        }

        
    return DefWindowProc(hWnd,msg,wParam,lParam);
    }



    LRESULT CALLBACK WndProc(HWND hWnd,UINT msg,WPARAM wParam,LPARAM lParam)
    {
        
    return GameEngine::GetEngine()->HandlEvent(hWnd,msg,wParam,lParam);
    }

    //主函数入口
    int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPreInstance,PSTR szCommandLine,int iCmdShow )
    {   
        MSG msg;
        
    static int  iTickTriger=0;
        
    int         iTickCount;

        
    if(GameInitialize(hInstance))
        
    {
            
    if(!GameEngine::GetEngine()->Initialize(iCmdShow))
                
    return FALSE;
            
    while(TRUE)
            
    {
                
    if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
                
    {
                    
    if(msg.message==WM_QUIT)
                        
    break;
                    TranslateMessage(
    &msg);
                    DispatchMessage(
    &msg);
                }

                
    else
                
    {   
                    
    //确保游戏引擎没有休眠
                    if(!GameEngine::GetEngine()->GetSleep())
                    
    {
                        
    //检查滴答计数,查看是否经历了一个周期
                        iTickCount=GetTickCount();
                        
    if(iTickCount>iTickTriger)
                        
    {
                            iTickTriger
    =iTickCount+GameEngine::GetEngine()->GetFrameDelay();
                            
    //游戏循环
                            GameCycle();
                        }

                    }

                }

            }

        }

        
    //游戏结束
        GameEnd();
        
    return TRUE;
    }


    其使用方法:

    xxx.h文件要先声明一个全局游戏引擎指针。

    #include "resource.h"
    #include 
    "GameEngine.h"

    GameEngine 
    * g_pGame; //全局游戏引擎指针

    然后xxx.cpp文件包含该xxx.h文件,在实现相应的游戏事件:

    #include "Blizzard.h"

    BOOL GameInitialize(HINSTANCE hInstance)
    {
        g_pGame
    =new GameEngine(hInstance,TEXT("PRIZE"),TEXT("PRIZE"),IDI_PRIZE,IDI_PRIZE);
        
    if(g_pGame==NULL)
            
    return FALSE;
        g_pGame
    ->SetFrameDelay(15);
        
    return TRUE;
    }

    void GameStart(HWND hWnd)
    {
        srand(GetTickCount());
    }

    void GameEnd()
    {
    }

    void GameActivate(HWND hWnd)
    {
        HDC hDc;
        RECT rect;
        GetClientRect(hWnd,
    &rect);
        hDc
    =GetDC(hWnd);
        DrawText(hDc,
    "Here comes ....",-1,&rect,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
        ReleaseDC(hWnd,hDc);
    }

    void GameDeactivate(HWND hWnd){}
    void GamePaint(HDC hdc){}
    void GameCycle()
    {
        HDC hDc;
        HWND hWnd
    =g_pGame->GetWindow();
        hDc
    =GetDC(hWnd);
        DrawIcon(hDc,rand()
    %g_pGame->GetWidth(),rand()%g_pGame->GetHeight(),(HICON)(WORD)GetClassLong(hWnd,GCL_HICON));
        ReleaseDC(hWnd,hDc);
    }
  • 相关阅读:
    EF6的DbContext动态连接字符串
    Swagger配置
    Xamarin学习资源收集
    xmarin开发问题收集
    javascript基础
    Vue3.0到底带来来哪些变化视频笔记1
    Git操作
    EFCore 通过数据库生成模型
    Web Deploy远程发布
    ASP.NET CORE系列【七】分析NetCore启动原理
  • 原文地址:https://www.cnblogs.com/mywolrd/p/1930742.html
Copyright © 2011-2022 走看看