游戏开发论坛

 找回密码
 立即注册
搜索
查看: 4259|回复: 13

关于游戏循环的一个问题

[复制链接]

64

主题

146

帖子

146

积分

注册会员

Rank: 2

积分
146
发表于 2006-4-16 08:03:00 | 显示全部楼层 |阅读模式
我们大家都知道在所有游戏的 WinMain 的函数中都会有如下的一段代码:
while (TRUE)
    {
      if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
      {
        if (msg.message == WM_QUIT)
          break;
        TranslateMessage(&msg);
        DispatchMessage(&msg);
      }
      else
     ....
   }

我想问的是:像这样的写法,如论无论窗口是否最小化,CPU的占用率都是100%,如何解决这个问题呢?

60

主题

1319

帖子

1319

积分

金牌会员

Rank: 6Rank: 6

积分
1319
发表于 2006-4-16 08:43:00 | 显示全部楼层

Re:关于游戏循环的一个问题

Sleep(1);

1

主题

5

帖子

5

积分

新手上路

Rank: 1

积分
5
发表于 2006-4-16 13:06:00 | 显示全部楼层

Re:关于游戏循环的一个问题

你提的问题也是我想知道的,大家哪位知道请回好吗.

125

主题

364

帖子

396

积分

中级会员

Rank: 3Rank: 3

积分
396
QQ
发表于 2006-4-16 13:19:00 | 显示全部楼层

Re:关于游戏循环的一个问题

WM_ACTIVATE  
当窗口激活的时候使用PeekMessage处理消息
否则用GetMessage处理消息

86

主题

2251

帖子

2386

积分

金牌会员

Rank: 6Rank: 6

积分
2386
QQ
发表于 2006-4-16 15:38:00 | 显示全部楼层

Re:关于游戏循环的一个问题

  1.         MSG msg;        
  2.         for(;;)
  3.         {
  4.                 if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
  5.                 {
  6.                         if(WM_QUIT==msg.message)
  7.                         {
  8.                                 break;
  9.                         }
  10.                         TranslateMessage(&msg);
  11.                         DispatchMessage(&msg);
  12.                 }
  13.                 if(app->IsActive())
  14.                 {
  15.                         Display();
  16.                         _sleep(0);
  17.                 }
  18.                 else
  19.                 {
  20.                         _sleep(0);
  21.                 }
  22.         }
复制代码


这样怎么着都不会高过50%

121

主题

2029

帖子

2034

积分

金牌会员

Rank: 6Rank: 6

积分
2034
QQ
发表于 2006-4-16 18:35:00 | 显示全部楼层

Re:关于游戏循环的一个问题

100%就100%,windows的进程调度会起作用的。

38

主题

275

帖子

281

积分

中级会员

Rank: 3Rank: 3

积分
281
QQ
发表于 2006-4-16 20:26:00 | 显示全部楼层

Re:关于游戏循环的一个问题

  Sleep(0);  好象不行吧?我试了试, Sleep(0);根本不起作用,CPU占用率还是95以上,Sleep(1);就可以了,if(bActive){....}  else  {Sleep(1);}  程序失去焦点后,CPU占用率一下子就降到 0 。
  我是用XP的任务管理器看的。

18

主题

573

帖子

573

积分

高级会员

Rank: 4

积分
573
发表于 2006-4-16 21:04:00 | 显示全部楼层

Re:关于游戏循环的一个问题

当没有Active的时候就调用WaitMessage。另外,可以使用线程,就是麻烦一些,但是效果不错。

2

主题

13

帖子

13

积分

新手上路

Rank: 1

积分
13
发表于 2006-4-16 22:02:00 | 显示全部楼层

Re:关于游戏循环的一个问题

我一般用两种方法解决你说的这个问题:
方法1:用Sleep
大概的代码这样写就OK (不考虑失去焦点问题)
MSG msg;
while(1)
{
    if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)
    {
        if(msg.message == WM_QUIT) break;
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    else
    {
        GameRender();
    }
   
    Sleep(2);    // 注意这里,用Sleep(2)在Windows下虽然实际上达不到2ms的精度,
                    // 但可以 空出一个时间片来让Windows自动调度你的CPU,这样实际运
                    // 行时效果还不错,不会占用CPU 100% (我在WinXP Sp2下试验过)
}

但是这种方法对FPS要求比较高的不太适用,因为每次循环的时间是很不定的,因为Windows本身的时钟就不太准,不过对于一般要求不高的小游戏,这是个较简便的解决方案。

方法2:使用失去焦点就WaitMessage的方法,大致代码如下:
MSG msg
while(1)
{
    if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)
    {
        if(msg.message == WM_QUIT) break;
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    else if ( g_bActive )
    {
        GameRender();
    }
    else WaitMessage();
}

实际使用中还可在循环中用GetTickCount判断时间以控制 FPS,这种方法精度稍微高一些。

86

主题

2251

帖子

2386

积分

金牌会员

Rank: 6Rank: 6

积分
2386
QQ
发表于 2006-4-17 15:47:00 | 显示全部楼层

Re: Re:关于游戏循环的一个问题

kevinlynx: Re:关于游戏循环的一个问题

  Sleep(0);  好象不行吧?我试了试, Sleep(0);根本不起作用,CPU占用率还是95以上,Sleep(1);就可以了,...


我用的是"_sleep(0);"和“Sleep(0);”的实现应该不一样吧。(这仅仅是我根据实际情况的猜测)

MSDN中的Sleep():
Parameters
  dwMilliseconds
     ...
     A value of zero causes the thread to relinquish the remainder of its time slice to any other thread of equal priority that is ready to run. If there are no other threads of equal priority ready to run, the function returns immediately, and the thread continues execution.

因此Sleep(0);是100%就对了

据说Sleep()的精确度是30ms


以前GameRes一位坛友所说的:

Sleep(0)和Sleep(1)当然是有区别的,Sleep(1)由于系统在切换进程的时候需要花上一定的时间,不同的机器所花时间不一样,这样导致Sleep(1)不一定等于Sleep1ms,在我的机器上大致需要6~10ms,而Sleep(0)不一样,基本上就很快了,但是这个时候CPU的占用会提高N多,当然如果在渲染的部分占用太多的CPU,在这里Sleep(0)和Sleep(1)区别不是很大
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-24 08:35

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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