图片显示特效之背景循环滚动

Tommorow

发布日期: 2019-01-09 12:16:55 浏览量: 1284
评分:
star star star star star star star star star_border star_border
*转载请注明来自write-bug.com

背景

大家玩游戏的时候,特别是横板游戏,应该会注意到,角色移动的时候,背景是会不停的变化的。如果游戏地图很大的话,可能背景不会重复,但是,如果游戏地图很小的话,大家应该会发现地图会循环显示。背景的循环显示,可以帮助节约游戏的图片资源,同时也可以增加游戏的趣味性。

那么,本文想要介绍的就是背景图片的循环滚动的实现原理和过程。之前,自己写的小游戏也常使用到这个技术,现在,就把学习的心得写成文档,分享给大家。

实现原理

为了方便大家理解背景的单向循环滚动的原理,我就详细分析一个简单的实例。首先,我们先来看下面这张图片,这张图片被均匀分成:红、绿、蓝三个部分。

那么,如果要实现它单向循环滚动的话,就应该每次循环都要“移花接木”般地绘图。意思是说,如果,图片向左单向滚动的话,那就每次循环,都要把左边一小部分的图片,移到图片末尾,然后再统一显示。每次循环都如此,这样就实现了背景的单向循环滚动。

就以上面的图片为例子,首先第 1 次循环,我们看到的效果是这样的:

第 2 次循环,我们把左边一小部分,目前是红色部分移到图片末尾,再显示出来,图片效果是:

第 3 次循环,我们仍然是把把左边一小部分,目前是绿色部分移到图片末尾,再显示出来,图片效果是:

再往下循环,那么大家应该可以看到规律了吧,图片重复了,又开始从头开始进行操作循环显示了。图片还是这一张图片,但是,我们把“移花接木”地显示,每次把左边的一小部分画面,都放到图片末尾来绘制,就能实现动态的效果。

编程实现

  1. int iWidth = 640; // 图片宽度
  2. int iHeight = 480; // 图片高度
  3. int iWidthRecord = 0; // 移动宽度记录
  4. int m = 10; // 每次循环移动宽度
  5. while (TRUE)
  6. {
  7. // 背景单向循环滚动
  8. WindowShadesPaint(hWnd, iWidthRecord);
  9. // 更新绘制宽度
  10. iWidthRecord = (iWidthRecord + m) % iWidth;
  11. // 停顿一下
  12. Sleep(50);
  13. }
  1. // 背景单向循环滚动
  2. BOOL WindowShadesPaint(HWND hWnd, int iWidthRecord)
  3. {
  4. // 获取窗口的客户区域的显示设备上下文环境的句柄
  5. HDC hDC = ::GetDC(hWnd);
  6. // 创建一个与hDC兼容的内存设备上下文环境
  7. HDC hBuf = ::CreateCompatibleDC(hDC);
  8. // 加载位图, 获取位图句柄
  9. HBITMAP hBmp = (HBITMAP)::LoadImage(NULL, "test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
  10. // 选择位图句柄到hBuf中, 并获取返回的原来位图句柄
  11. HBITMAP hOldBmp = (HBITMAP)::SelectObject(hBuf, hBmp);
  12. // 背景单向循环滚动
  13. int iWidth = 640; // 图片宽度
  14. int iHeight = 480; // 图片高度
  15. // 绘制左边部分
  16. ::BitBlt(hDC, 0, 0, (iWidth-iWidthRecord), iHeight, hBuf, iWidthRecord, 0, SRCCOPY);
  17. // 绘制右边部分
  18. ::BitBlt(hDC, (iWidth - iWidthRecord), 0, iWidthRecord, iHeight, hBuf, 0, 0, SRCCOPY);
  19. // 还原位图对象
  20. ::SelectObject(hBuf, hOldBmp);
  21. // 释放位图
  22. ::DeleteObject(hBmp);
  23. // 释放兼容的内存设备上下文环境
  24. ::DeleteDC(hBuf);
  25. // 释放设备上下文环境
  26. ::ReleaseDC(hWnd, hDC);
  27. return TRUE;
  28. }

程序测试

我们呢就直接运行程序,直接可以看到图片在单向的循环滚动显示。由于画面是动态的,所以,我就截几张代表性的图片作为展示。

总结

类似的实现原理,如果之前你们有接触过,可以先把程序实现出来,然后,一边运行程序,看着实现效果对应实现原理去理解比较好。

其中,要注意的是,因为这个图片显示,是一直循环显示的,所以,如果显示图片的这段代码放在窗口主线程的话,窗口会一直被卡住,所以,建议这段显示部分的代码,创建一个多线程,把它放在多线程中显示,这样就不会影响主线程的操作了。

上传的附件 cloud_download BackgroundRolling_Test.7z ( 268.45kb, 3次下载 )

发送私信

成功其实很简单,就是当你坚持不住的时候,再坚持一下

9
文章数
8
评论数
最近文章
eject