MFC GDI+的多线程画图问题

神之者 2013-05-16 12:28:28

我最近在做一款STG类游戏.
在图中我们可以看到,我用了比较多的位图.
宇宙背景是位图,飞船是位图,右边的界面是位图,数字也是位图.....

我用了双缓冲的方法防止画面闪烁.
试玩的时候,画面的确不闪,但是很明显的感觉到画面卡顿.
我现在只是画了背景,一个飞船,还有一些数字,就能这么卡,要是加上敌人和子弹,岂不是更卡.
这应该就是GDI+绘图效率低下的体现吧.

于是我想到了多线程画图.于是问题就来了.
在类中声明成员

CCriticalSection m_CS; //声明临界区对象
static UINT DrawScoreThread(LPVOID pParam); //声明线程函数,这个函数是画分数的数字


然后在OnTimer函数中创建线程,OnTimer函数就是我的游戏循环

DrawTime(); //画剩余时间的数字
DrawLife(); //画剩余生命的数字
DrawBomb(); //画炸弹的个数的数字
DrawBackground(); //画背景
pGameBuffer->DrawImage(m_Stage.Player.pMove,Rect(m_Stage.Player.X,m_Stage.Player.Y,62,46),0,0,62,46,UnitPixel); //画飞船
AfxBeginThread(DrawScoreThread,this); //创建线程
Sleep(20); //让主线程睡眠20毫秒,让新创建的线程画图



UINT CBeyondTheCosmosDlg::DrawScoreThread(LPVOID pParam) //新创建的线程
{
CBeyondTheCosmosDlg *CBTC=(CBeyondTheCosmosDlg*)pParam;
CBTC->m_CS.Lock(); //进入临界区

CBTC->DrawScore(); //画分数

CBTC->m_CS.Unlock(); //离开临界区
return 0;
}



void CBeyondTheCosmosDlg::DrawScore() //画分数的函数
{
//pGameBuffer是Graphics类的指针,这个pGameBuffer的作用是缓冲,先把数字画在pGameBuffer上,再一次性画在真正的与DC相关联的Graphics类对象上,这样可以防止画面闪烁
int s=m_Stage.Player.nScore;
pGameBuffer->DrawImage(m_Stage.pNumber,Rect(540,260,64/3,96/3),((s/1000000)%10)*64,0,64,96,UnitPixel); //画百万位数字
pGameBuffer->DrawImage(m_Stage.pNumber,Rect(540+64/3,260,64/3,96/3),((s/100000)%10)*64,0,64,96,UnitPixel); //画十万位数字
pGameBuffer->DrawImage(m_Stage.pNumber,Rect(540+(64/3)*2,260,64/3,96/3),((s/10000)%10)*64,0,64,96,UnitPixel); //画万位数字
pGameBuffer->DrawImage(m_Stage.pNumber,Rect(540+(64/3)*3,260,64/3,96/3),((s/1000)%10)*64,0,64,96,UnitPixel); //以此类推
pGameBuffer->DrawImage(m_Stage.pNumber,Rect(540+(64/3)*4,260,64/3,96/3),((s/100)%10)*64,0,64,96,UnitPixel);
pGameBuffer->DrawImage(m_Stage.pNumber,Rect(540+(64/3)*5,260,64/3,96/3),((s/10)%10)*64,0,64,96,UnitPixel);
pGameBuffer->DrawImage(m_Stage.pNumber,Rect(540+(64/3)*6,260,64/3,96/3),(s%10)*64,0,64,96,UnitPixel);
}


我已经创建了一个线程来画数字,但卡顿的现象并没有缓解,还是很卡,请问是不是我哪里没写对?
求高手提供一个简单的例子
...全文
432 5 打赏 收藏 转发到动态 举报
写回复
用AI写文章
5 条回复
切换为时间正序
请发表友善的回复…
发表回复
Jake443403168 2013-05-16
  • 打赏
  • 举报
回复
然后在OnTimer函数中创建线程,OnTimer函数就是我的游戏循环 --- 每个一段时间就会去执行这个AfxBeginThread创建线程,都不杀死吗
Jake443403168 2013-05-16
  • 打赏
  • 举报
回复
引用 3 楼 qweasd6947 的回复:
[quote=引用 1 楼 Jake443403168 的回复:] 然后在OnTimer函数中创建线程,OnTimer函数就是我的游戏循环 --- 每个一段时间就会去执行这个AfxBeginThread创建线程,都不杀死吗
我在线程使用了return 0;[/quote] sorry,确实是这样 --------- 如果怀疑是画图速度慢可以继续在提高提高绘制效率上下功夫 比如禁画背景,使用CDC::GetClipBox
liuh2013 2013-05-16
  • 打赏
  • 举报
回复
引用 1 楼 Jake443403168 的回复:
然后在OnTimer函数中创建线程,OnTimer函数就是我的游戏循环 --- 每个一段时间就会去执行这个AfxBeginThread创建线程,都不杀死吗
这是最大的问题。
神之者 2013-05-16
  • 打赏
  • 举报
回复
引用 1 楼 Jake443403168 的回复:
然后在OnTimer函数中创建线程,OnTimer函数就是我的游戏循环 --- 每个一段时间就会去执行这个AfxBeginThread创建线程,都不杀死吗
我在线程使用了return 0;
dahaiI0 2013-05-16
  • 打赏
  • 举报
回复
没必要每次都全部画完,需要哪部分更新就画哪部分。另多线程貌似没什么用,最好也不要在其他线程里操作主线程里的UI

684

社区成员

发帖
与我相关
我的任务
社区描述
智能路由器通常具有独立的操作系统,包括OpenWRT、eCos、VxWorks等,可以由用户自行安装各种应用,实现网络和设备的智能化管理。
linuxpython 技术论坛(原bbs)
社区管理员
  • 智能路由器社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧