飞机空战V11修改优化篇Word格式文档下载.docx

上传人:b****6 文档编号:16150787 上传时间:2022-11-21 格式:DOCX 页数:12 大小:1.35MB
下载 相关 举报
飞机空战V11修改优化篇Word格式文档下载.docx_第1页
第1页 / 共12页
飞机空战V11修改优化篇Word格式文档下载.docx_第2页
第2页 / 共12页
飞机空战V11修改优化篇Word格式文档下载.docx_第3页
第3页 / 共12页
飞机空战V11修改优化篇Word格式文档下载.docx_第4页
第4页 / 共12页
飞机空战V11修改优化篇Word格式文档下载.docx_第5页
第5页 / 共12页
点击查看更多>>
下载资源
资源描述

飞机空战V11修改优化篇Word格式文档下载.docx

《飞机空战V11修改优化篇Word格式文档下载.docx》由会员分享,可在线阅读,更多相关《飞机空战V11修改优化篇Word格式文档下载.docx(12页珍藏版)》请在冰豆网上搜索。

飞机空战V11修改优化篇Word格式文档下载.docx

Sunsu

*E-mail:

641655502@

*Date:

2013-02-01

-----------------------------------------------------------------------------------------------------------------------------*/

前言:

前面今天已经实现飞机空战的基本对战功能,我方战机可以与敌机进行正常对战,可以设置我方战机和敌机的生命值,实现游戏难度的增加。

问题的发现:

破程序竟然占了将近27M内存,肯定要优化了。

1.

游戏运行一段时间后不能运行了,程序崩溃退出了,这是什么问题呢,很郁闷呢,仔细想想了,看了下CPlaneDoc类

原来这样,数据的存储我都是来组织的,这样就有一个大问题,数组的大小是固定的,程序一旦运行,系统就分配给数组固定大小的内存,不可以扩展,这样当敌机的数量超过了100架,或者我方战机和敌机发了超过了1000发子弹的话,数组将会溢出,出现越界访问问题,程序自然退出了。

好了,知道了问题就对症下药了,优化数据结构,换用可动态增长的数组和链表存储结构,我首先想到的是C++的库函数里的CArry类,查看了MSDN,用法还就简单,还有Example

用法还就简单,#include<

afxtempl.h>

头文件。

不用不知道,一用吓一跳,报了一大堆错,看了半天发现,貌似在使用自定义的类作为其数组元素时,类中必须有合适复制构造函数和重载的=运算符,麻烦了,还是自己封装把,自给自足,就用链表把,以前上数据结构课程时经常用,熟悉。

分析一下类需实现的功能,具有自动数组元素自动收缩功能,当一个数组元素删除时,后面的元素能自动向前缩进,可以动态增加元素,重载[]运算符,可以计算数组元素的个数,

类设计如下:

采用模版编写,增强了类的可复用性,因为需要不同类型的数组元素。

两点说明:

1.类设计好后,使用时编译器报了一大推莫名其妙的链接错误,编译没有问题,链接出问题了,查了查资料,由于本人采用的是VC6.0编译器,此编译器比较老,所以不支持模版分离编译,即模版类的声明和定义必须放在一个文件里,不能分开放在头文件和源文件中,这个问题以前在大一时就遇到过,当时还有同学讨论了好长时间,时间久了,忘记了,没有及时吸取教训,导致这次在这个问题上有浪费了好长时间。

2.重载operator[]时的时候,应该返回数组元素本身值的引用,这样才可以直接对元素本身的数据成员进行修改。

类设计完成后,修改CPlaneWarDoc类中的数据成员,采用自定义的类组织数据。

这样敌机,敌机子弹和我方子弹的数量就可以动态添加和删除了,当敌机和子弹移动出了窗口界面显示范围就将其删除,节约内存。

2.

还有个问题,就是图片的显示问题。

我们为每个实例都设置了一个数据成员,用来存储图片,这个成员是从基类CWarObject继承而来的,这样就导致一个问题,每个敌机都是一样的,敌机的每个子弹的显示图片也是一样的,我方子弹也是一样,这样为每个角色实例都设置一张图片,是不是太浪费内存了,可不可以用类的静态成员来保存图片数据成员,因为类的静态成员是属于类自身的,不属于某个具体实例,这样在内存该类的所有实例共享同一张图片,节约了系统资源。

因为静态成员是属于类自身的,所以必须要重新设计基类和继承的子类了,因此基类不能再有m_Image成员,必须将m_Image设置为子类的数据成员。

可是每个角色的图片又不一样,敌机和我方战机显示图片并不一样,之前CPlane类的设计是为了更好的体现复用性,所以敌机和我当战机都是CPlane的实例。

所以必须重新设计飞机和子弹类,从基类派生出各自自己的专属类。

敌机子弹类:

我方战机子弹类:

敌机类:

我方战机类:

3.

重点说说屏幕界面绘制的问题。

这是V1.0版本中使用的界面屏幕绘制代码部分。

程序中多次使用InvalidateRect(LPCRECTlpRect,BOOLbErase=TRUE)来通知屏幕更新视图,MSDN对这个函数的解释:

参数lpRect指定了屏幕更新区域,下一次发送WM_PAINT消息时,这个CRect矩形区域将会增加到屏幕的更新区域中,显然使用这个函数比使用Invalidate(BOOLbErase=TRUE)这个函数效率高。

但是这样导致了一个问题,多次使用InvalidateRect(LPCRECTlpRect,BOOLbErase=TRUE),

如果bErase为TRUE,还是会导致屏幕在局部矩形区域不断擦出背景,不断重画,如果背景与所画图形差别较大,将会产生严重的闪烁,定时器时间间隔越短,屏幕局部闪烁越厉害,导致程序运行不流畅,影响对游戏的操作。

前面讲过可以通过使用双缓冲来实现屏幕绘制。

何为双缓冲,通俗讲就是把所有的绘制代码现在内存里画好,然后再一次性输出到屏幕,每次都这样,由于人眼视觉暂留原理,玩家将看到的连续的画面切换。

我们平时看岛国动漫火影或海贼,动漫放的非常流畅,没有一点闪烁,电影也是,动漫和电影都是一帧一帧不断替换的,每一帧之间相差特别小,所以这样观众肉眼看不出停顿,观察到的是一段段移动流畅的视频,基于这个原理,我实现的游戏界面绘制也是这个原理,不管屏幕背景画刷如何,每次更新时,都不需要擦出背景,直接现在内存中画,画好了一次性输出到屏幕覆盖先前屏幕上的图像,由于图像之间差别不大,所以看不出停顿现象。

基于这个原理,我们为CPlaneWarView类添加一个CDCm_MemDC数据成员,初始话为内存DC,在OnDraw()函数里直接现在内存m_MemDC里画好图像,在一次性输出到屏幕DC。

OnDraw()函数代码部分:

这样使用双缓冲技术优化界面显示还带来另一个好处,将屏幕绘制功能和定时器游戏角色位置移动控制功能完全分离,逻辑上代码会更清晰,定时器里不需要计算出最小绘制无效矩形,减少CPU负荷,一举多得。

呵呵。

4.开启多线程。

虽然在前面我们利用了双缓冲技术,是屏幕绘制代码和角色状态控制代码有了更好的逻辑独立性,但这仅仅使程序的代码功能更加模块化。

仔细分析看看,屏幕绘制代码的执行和角色控制代码的执行还是同步的,并没有达到异步执行,我们在前面定时器消息相应函数里做的是计算角色状态信息的工作,既然是计算,完全交与辅助线程去做,充分利用线程并发执行的优势,使主线程负责屏幕绘制,辅线程负责角色状态计算,使程序并发执行,加快程序运行速度。

这样的话就完全没有必要相应WM_TIMER消息了,创建一个线程执行函数DWORDWINAPIRoleControl(LPVOID)初始状态为挂起状态,再用PeekMessage()为辅线程创建消息队列用于和主线程通信。

这样就可以不需要定时器了,当我方战机炸毁的时候主线程想辅助线程发送WM_QUIT消息就可以终止辅助线程的执行。

到这里,优化阶段工作已经基本完成。

附上效果图:

内存占用减小到7M多,看来优化代码还是很有必要的。

(游戏运行流畅,无丝毫闪烁)

游戏暂停状态:

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 小学教育 > 语文

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1