游戏开发论坛

 找回密码
 立即注册
搜索
查看: 6095|回复: 10

关于消息循环和游戏主循环的问题

[复制链接]

1

主题

6

帖子

6

积分

新手上路

Rank: 1

积分
6
发表于 2011-3-11 14:01:00 | 显示全部楼层 |阅读模式
我写了一个2D RPG小程序,里面用ID3DXSprite显示人物图片。用户输入上下左右移动人物。

可是,随着上下左右使用次数的增加,我的程序越来越卡。 按一下上,要过1-2秒之后,才有反应。
我自己觉得是消息堆积了。但是,又不知道如何处理。 下面附上我的主要代码(我这么写 哪里有问题啊):

  1. while(msg.message != WM_QUIT){
  2. if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)){
  3. TranslateMessage(&msg);
  4. DispatchMessage(&msg); }
  5. else if(active) { MainLoop(); }
  6. else { WaitMessage(); } }
复制代码


  1. MainLoop(){
  2. end_time = GetTickCount();
  3. if (end_time > start_time + 30) {
  4. start_time = end_time;
  5. lpKeyboard->GetDeviceState( 256, (LPVOID)KeyboardState);
  6. if (KeyboardState[DIK_UPARROW] & 0x80){
  7. b -= float(10); if (rect.top != 192) temp = 0; rect.top = 192; rect.bottom = 256; rect.left = temp%4 * 32;
  8. rect.right = rect.left + 32; temp++; }
  9. if (KeyboardState[DIK_DOWNARROW] & 0x80){ b +=float(10); if (rect.top != 0) temp = 0; rect.top = 0;
  10. rect.bottom = 64; rect.left = temp%4 * 32; rect.right = rect.left + 32; temp++; }
  11. if (KeyboardState[DIK_LEFTARROW] & 0x80){ a -= float(10); if (rect.top != 64) temp = 0; rect.top = 64;
  12. rect.bottom = 128; rect.left = temp%4 * 32; rect.right = rect.left + 32; temp++; }
  13. if (KeyboardState[DIK_RIGHTARROW] & 0x80){ a += float(10); if (rect.top != 128) temp = 0; rect.top = 128;
  14. rect.bottom = 192; rect.left = temp%4 * 32; rect.right = rect.left + 32; temp++; } }
  15. RenderScene();
  16. }
复制代码


  1. void RenderRole(){
  2. pSprite->Begin(D3DXSPRITE_ALPHABLEND);
  3. D3DXCreateTextureFromFile( g_D3DDevice, L"Tim.png", &tim);
  4. pSprite->Draw( tim, &rect, NULL, &D3DXVECTOR3( a, b, 0.0f), 0xffffffff);
  5. pSprite->End(); }

  6. void RenderScene(){ g_D3DDevice->Clear(0,NULL,D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,0), 1.0f, 0);
  7. g_D3DDevice->BeginScene(); D3DXCreateTextureFromFile(g_D3DDevice, L"4.jpg", &tim);
  8. pSprite->Begin(D3DXSPRITE_ALPHABLEND); pSprite->Draw( tim, NULL, NULL, NULL, 0xffffffff);
  9. RenderRole();
  10. pSprite->End();
  11. g_D3DDevice->EndScene();
  12. g_D3DDevice->Present(NULL,NULL,NULL,NULL); }
复制代码


希望大家帮帮我,困惑好几天了。也不是没看别人的代码,他们好像没用ID3DXSprite,用的DDraw和API。其他真不知道哪里有问题了。

21

主题

296

帖子

296

积分

中级会员

Rank: 3Rank: 3

积分
296
发表于 2011-3-11 16:16:00 | 显示全部楼层

Re:关于消息循环和游戏主循环的问题

原因很简单。
而且这是新手们经常犯的错误。

你的while里面,先处理一个消息,然后渲染一次。这样循环。

那么我要是按4个键,鼠标边移动边按右键,这样一下子产生了6个消息,你这个循环吃得消吗?
6个消息,你先处理一个消息(也就是一个按键),然后渲染一次。
然后再处理一个消息(另一个按键),再渲染一次。。。。。。
你的画面渲染6次之后,才把这6个消息处理完了。
不卡才怪呢。

1

主题

6

帖子

6

积分

新手上路

Rank: 1

积分
6
 楼主| 发表于 2011-3-11 18:07:00 | 显示全部楼层

Re: Re:关于消息循环和游戏主循环的问题

TV游戏: Re:关于消息循环和游戏主循环的问题

原因很简单。
而且这是新手们经常犯的错误。

你的while里面,先处理一个消息,然后渲染一次。这样循环。...


大大,那我应该怎样渲染啊? 我觉得我已经固定帧数了啊。 30ms渲染一次。不应该存在处理不过来的情况啊。

21

主题

296

帖子

296

积分

中级会员

Rank: 3Rank: 3

积分
296
发表于 2011-3-11 18:46:00 | 显示全部楼层

Re:关于消息循环和游戏主循环的问题

问题不在于渲染上。
问题在于消息处理。

while(msg.message != WM_QUIT)
{
if(PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE))
{ TranslateMessage(&msg);  DispatchMessage(&msg); }
else if(active) MainLoop();
}

else WaitMessage(); 这一行删掉,试试看

33

主题

159

帖子

272

积分

中级会员

Rank: 3Rank: 3

积分
272
QQ
发表于 2011-3-11 21:36:00 | 显示全部楼层

Re:关于消息循环和游戏主循环的问题

不用把这么具体的dinput接收段放到mainLoop()这么珍贵的地方去吧,建个frameMove()把键盘操作与sprit操作全扔进去,
我学的时间不长,到现在基本上都是看sdk的例子做成自己的验证程序,
主消息循环里放两个回调,依次fnFrameMove()控制每帧的物体移动和输入操作
fnFrameRender()控制每帧的渲染
建议MainLoop里最好只放函数,不要放具体操作.

函数最好是用函数指针来调用,因为正常的函数是每次用到时才压进内存,用完注销,而函数指针是常驻内存的,当你的程序结束时 system api才会杀过来干掉你的函数.如render move这类每帧要用到的函数,如果每次用到时候再压栈用完解构,其实也浪费了不少填充率.

1

主题

6

帖子

6

积分

新手上路

Rank: 1

积分
6
 楼主| 发表于 2011-3-11 22:28:00 | 显示全部楼层

Re:关于消息循环和游戏主循环的问题

哎 还是不行 不知道怎么回事...

1

主题

49

帖子

49

积分

注册会员

Rank: 2

积分
49
发表于 2011-3-13 18:58:00 | 显示全部楼层

Re:关于消息循环和游戏主循环的问题

把第一个else去了...

1

主题

8

帖子

8

积分

新手上路

Rank: 1

积分
8
发表于 2011-3-16 22:51:00 | 显示全部楼层

Re:关于消息循环和游戏主循环的问题

RenderScene(); 放到 if (end_time > start_time + 30) {} 外面了。

21

主题

296

帖子

296

积分

中级会员

Rank: 3Rank: 3

积分
296
发表于 2011-3-16 23:54:00 | 显示全部楼层

Re: Re:关于消息循环和游戏主循环的问题

herbert_1987: Re:关于消息循环和游戏主循环的问题
RenderScene(); 放到 if (end_time > start_time + 30) {} 外面了。

确实。

1

主题

6

帖子

6

积分

新手上路

Rank: 1

积分
6
 楼主| 发表于 2011-3-17 00:03:00 | 显示全部楼层

Re:关于消息循环和游戏主循环的问题

不是大家说的问题。已经解决了。是我创造了太多的纹理,显卡上的纹理空间不够了,只能和内存进行频繁交换。导致了卡的原因。
另外:谢谢大家。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2025-6-7 16:04

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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