游戏开发论坛

 找回密码
 立即注册
搜索
查看: 2899|回复: 7

请大家看看下面两种游戏主循环的写法,哪种更正确?

[复制链接]

4

主题

12

帖子

12

积分

新手上路

Rank: 1

积分
12
发表于 2006-1-19 18:41:00 | 显示全部楼层 |阅读模式
[第一模块]我最近看到别人的写法:

        while(1)                //程序主循环
        {
                if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
                {
                                        if (!GetMessage(&msg, NULL, 0, 0))
                           return msg.wParam;

                                       TranslateMessage(&msg);
                                        DispatchMessage(&msg);
                }
                else if(bActive)
                {
                        MainLoop();                //进入游戏主循环
                }
                else WaitMessage();        //等待消息
        }






[第二模块]
//我自己的写法


        while(1)
        {
                if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))       
                {       
                        if(msg.message == WM_QUIT)
                                break;

                        TranslateMessage(&msg);               
                        DispatchMessage(&msg);                               
                }
                else if(bActive)
                {       
                         MainLoop();
                }

        }




[模块1]为我最近看到的别人的一种游戏主循环写法,[模块2]为我自己一直认为正确的写法。  请各位高手指教一下:

(1) WaitMessage()函数有什么作用?应该用它吗?我个人认为没有必要。

(2) 我记得游戏制作的书中都说应该用PeekMessage()处理消息,不用GetMessage()函数。而在[模块1]的主循环代码中却既用了PeekMessage()又用了GetMessage()。大家说是[模块1]的用法正规还是[模块2]的用法正规呢?哪种写法更加的高效和接近商业游戏?




5

主题

22

帖子

22

积分

注册会员

Rank: 2

积分
22
发表于 2006-1-19 20:04:00 | 显示全部楼层

Re:请大家看看下面两种游戏主循环的写法,哪种更正确?

        你所提到的(1)中的方法是<圣2>用的方法,今天恰巧看了一下他的那个源代码,使用WaitMessage()是他自己定义的一个函数,处理他自己定义的一些消息.你的第2个问题,我不知道,我这个不是很了解,我想是因为要处理自己的消息所以就使用的GetMessage()吧

39

主题

102

帖子

102

积分

注册会员

Rank: 2

积分
102
发表于 2006-1-19 23:22:00 | 显示全部楼层

Re:请大家看看下面两种游戏主循环的写法,哪种更正确?

WaitMessage()函数是Windows的系统函数,她的作用是把本程序挂起然后将控制权交给其他应用程序,直到本程序有新的消息为止。所以我觉的用WaitMessage()函数反而不好,因为这样容易让其他程序抢占了游戏的主循环,当然个人观点。

6

主题

110

帖子

110

积分

注册会员

Rank: 2

积分
110
发表于 2006-1-20 16:04:00 | 显示全部楼层

Re:请大家看看下面两种游戏主循环的写法,哪种更正确?

为什么不用
do
{
}while()结构呢

5

主题

22

帖子

22

积分

注册会员

Rank: 2

积分
22
发表于 2006-1-24 11:50:00 | 显示全部楼层

Re:请大家看看下面两种游戏主循环的写法,哪种更正确?

这个是游戏中的代码:
while( RunGame )                //程序主循环
        {
                if(PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE))
                {
            if (!GetMessage(&msg, NULL, 0, 0))
                                return msg.wParam;
            TranslateMessage(&msg);
            DispatchMessage(&msg);
                }
                else if(bActive)
                {
                        MainLoop();                //进入游戏主循环
                }
                else WaitMessage();        //等待消息
        }
这个是tiamo对游戏结构的分析:
先初始化和游戏相关的数据,Ddraw,Dsound,Dmusic,Dinput然后开始消息循环,由一个叫RunGame的变量做为循环的条件,Peek方式,有消息的时候处理消息,在空闲的时候进行游戏主循环。主循环里面先进行延时控制,然后获取输入信息,再根据游戏状态(g_ePlayState)进行不同的处理,这些处理是放到不同的函数里面的,然后得到游戏的一些数据,再根据不同的游戏状态进行屏幕的更新,最后是一个被称为消息队列的东西执行它的一个叫做Run的函数。这个消息队列是由程序来维护的,不是windows的消息队列。设计这样一个消息队列是用来配合脚本的执行。从游戏主循环返回了后,又进行相同的循环,直到RunGame为false为止。这点是由程序控制的,正常情况下GetMessage是不可能得到WM_QUIT消息的。

18

主题

47

帖子

47

积分

注册会员

Rank: 2

积分
47
发表于 2006-1-25 08:39:00 | 显示全部楼层

Re:请大家看看下面两种游戏主循环的写法,哪种更正确?

看到书上说,方法[2]是正确的。

1

主题

25

帖子

25

积分

注册会员

Rank: 2

积分
25
发表于 2006-1-25 11:45:00 | 显示全部楼层

Re:请大家看看下面两种游戏主循环的写法,哪种更正确?

区别在于GetMessage和PeekMessage不同用法,没有消息的时候,一个会挂起等待,一个会返回,另外PeekMessage中的参数PM_NOREMOVE和PM_REMOVE含义不同,5楼已经说了,不明白的可以去看看MSDN,其实个人感觉两种写法含义差不多的。
但是!
第一种里面“return msg.wParam;”就说明了这个程序的最后清理工作必须放在消息里面处理了。而第二种的话,CleanUp放在main的最后面做也可以。
不过我倾向于第三种,详见DXSDK9。b(注意是b,不是c或者更新的什么):
    bool bGotMsg;
    MSG  msg;
    msg.message = WM_NULL;
    PeekMessage( &msg, NULL, 0U, 0U, PM_NOREMOVE );

    while( WM_QUIT != msg.message  )
    {
        // Use PeekMessage() if the app is active, so we can use idle time to
        // render the scene. Else, use GetMessage() to avoid eating CPU time.
        if( m_bActive )
            bGotMsg = ( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) != 0 );
        else
            bGotMsg = ( GetMessage( &msg, NULL, 0U, 0U ) != 0 );

        if( bGotMsg )
        {
                TranslateMessage( &msg );
                DispatchMessage( &msg );
        }
        else
        {
            if( m_bActive )
            {
                Render3DEnvironment();
            }
        }
    }

13

主题

978

帖子

978

积分

高级会员

Rank: 4

积分
978
发表于 2006-1-25 20:25:00 | 显示全部楼层

Re:请大家看看下面两种游戏主循环的写法,哪种更正确?

确实,感觉dx9.0b做的很实在,他的document和project可以直接拿来当教程。不像9.0c上来就是HLSL
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2026-1-23 08:00

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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