51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 2400|回复: 0
打印 上一主题 下一主题

游戏入口控制的基本部分

[复制链接]
  • TA的每日心情
    慵懒
    2015-1-8 08:46
  • 签到天数: 2 天

    连续签到: 1 天

    [LV.1]测试小兵

    跳转到指定楼层
    1#
    发表于 2008-1-10 17:23:16 | 只看该作者 回帖奖励 |正序浏览 |阅读模式
    先建了一个CGame类,把游戏控制的基本部分包装起来。
    结构如下:

    #pragma once
    class CGame
    {
    public:
         CGame(void);
         ~CGame(void);
         // 开始游戏
         int Start(void);
        private:
         // 游戏消息循环
         int GameLoop(void);
         // 游戏运行状态
         bool bIsRunning;
    };


    然后把WinMain里面的消息循环放到了GameLoop里面
    在WinMain里面原本消息循环的位置调用Game::Start()代替

    // // 开始游戏
    int CGame::Start(void)
    {
    // 读取游戏设置
    // 初始化DirectDraw
    //
    bIsRunning = true;

    return GameLoop();
    }
    // 游戏消息循环
    int CGame::GameLoop(void)
    {
    MSG msg;
    while (bIsRunning)
    {
      if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
      {
       if (msg.message==WM_QUIT)
       {
        //myDebug->OutDebug("Game Terminated...\n");
        //break;
        bIsRunning = false;
       }
       TranslateMessage(&msg);
       DispatchMessage(&msg);
      }
    }
    return msg.wParam;
    }


    消息循环部分还需要修改,在游戏窗口在非活动状态的时候等待消息,以阻塞线程,降低CPU资源占用。
    在回调函数WndProc里面,加入检测窗口是否在活动状态的代码:

    case WM_ACTIVATE: //应用程序是否活动
          if(LOWORD(wParam)==WA_INACTIVE)
               geGame.SetActive(false);
              else if(HIWORD(wParam))
          {
               geGame.SetActive(false);
               return 0;
          }
              else
          {
               SetCursor(NULL);
               Game.SetActive(true);
          }

    上面的代码有两处SetActive(false),原理是从gpgame的圣剑2 copy的(现在好像个人/小团队开发的游戏都离不开“剑”字)还没搞清原理。不过需要注意的是,从非活动状态恢复的时候,需要重新获取输入、绘图设备等等。

    至此CGame类大致的架构已经出来了。源码如下:



    //Game.cpp
    #include "StdAfx.h"
    #include ".\game.h"
    CGame::CGame(void)
    : bIsRunning(false)
    , bActive(false)
    {
    }
    CGame::~CGame(void)
    {
    }
    // // 开始游戏
    int CGame::Start(void)
    {
    // 读取游戏设置
    // 初始化DirectDraw
    // 开始游戏
    bIsRunning = true;
    return GameLoop();
    }
    // 游戏消息循环
    int CGame::GameLoop(void)
    {
    MSG msg;
    while (bIsRunning)
    {
      if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
      {
       if (msg.message==WM_QUIT)
       {
        bIsRunning = false; //退出游戏
        break;
       }
       TranslateMessage(&msg);
       DispatchMessage(&msg);
      }else if(!bActive){
       WaitMessage(); //等待消息
      }else{
       MainLoop(); //游戏主循环
      }
    }
    return msg.wParam;
    }
    // 设置窗口是否活动
    void CGame::SetActive(bool Active)
    {
    bActive = Active;
    }
    // 游戏主循环,负责更新状态,绘图翻页,响应等
    void CGame::MainLoop(void)
    {
    return;
    }



    //Game.h
    #pragma once
    class CGame
    {
    public:
    CGame(void);
    ~CGame(void);
    // // 开始游戏
    int Start(void);
    private:
    // 游戏消息循环
    int GameLoop(void);
    // 游戏运行状态
    bool bIsRunning;
    public:
    // 窗口是否活动状态
    bool bActive;
    // 设置窗口是否活动
    void SetActive(bool Active);
    // 游戏主循环,负责更新状态,绘图,响应等
    void MainLoop(void);
    };


    下一次就是DirectX的初始化了
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-11-27 02:57 , Processed in 0.065843 second(s), 28 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表