代码改变世界

XNA“效率”探索——一个简单的繁花曲线程序

2009-06-11 12:27  JimLiu  阅读(7621)  评论(40编辑  收藏  举报

在某论坛上和别人探讨XNA是否适合做弹幕飞行射击游戏,我认为是可以的,但是别人认为XNA效率不够,在低端机器上,无法处理上千枚子弹的运动。所以我下来做了个小实验。

这是我的繁花曲线程序截图,每一帧都会重新计算这一组繁花曲线的路径。步进量是0.05f,总量是20*pi,就是小圆绕大圆转10圈(其实可以通过计算得到一个刚好不浪费的值)。sin/cos没有优化,直接调用Math.Sin(这个……JIT都直接变成fsin/fcos汇编指令了,真的有那么值得“优化”吗?),子弹方向也没优化,用的Math.Atan。计算的时候算法一般,在绘图的时候用XoY坐标,步进的时候用极坐标。

子弹是一个15帧的Sprite动画,这里设置帧率和其对应的繁花曲线一样,我自己写的Animation,不知道效率怎么样。

我的机器配置:

笔记本Dell 640M,购于2006年,Intel T2300E(双核1.67GHz), Intel GMA950, 4G DDR2 667

除了内存,其他都算“低端”了吧。尤其是显卡。

如图所示,现在画面中有四组繁花曲线,共有5000枚子弹,也就是5000多个SpriteAnimation。FPS大概60差一点。虽然每一枚子弹没有自己的速度和加速度,但是计算繁花曲线的过程基本上可以代表这个运算。浮点运算全在CPU上,效率一般,CPU占用最高也才22%。但是我显卡太弱了,再往上加曲线直到CPU占用50%(单线程极限),显卡就罢工了,这时候应该是显卡渲染Sprite的效率不够,据说Sprite效率不高,等我有时间改成不用Sprite而是用多边形贴图看看有没进步。

下面谈谈测试结果吧:

首先是CPU性能,我相信C#的性能,这点计算量对三年前的主流笔记本电脑CPU基本上构不成威胁,一个核心也没用满。再实际游戏中,即使加上别的计算,只要稍稍做一下多线程优化,利用上多核的优势,我相信CPU性能不会有障碍。

然后是显卡性能,我没有在别的显卡上做测试,但是我的显卡已经非常弱了,这样的显卡有这个成绩我觉得还凑合了,我认为这里可以胜任一个2D的飞行游戏。

然后是内存性能,我没有做特别的测试,但是在运行中有时候FPS会突然降低到30然后反弹到50+,我猜测这是GC在作怪,但是我用来表示每一枚子弹的数据结构都是简单的Vector2或者float,这样的值类型对象跟GC八竿子打不到一尺吧?不过也不排除系统中别的程序在作怪(我开一个kmplayer帧数马上降低一半,因为km播放视频要用DirectShow渲染,会消耗显卡资源,我那个显卡本来就够可怜的了)。

综上所述,我认为使用XNA在主流配置甚至两三年前的主流配置上开发游戏是完全可行的,事实证明国外也有XNA项目,有RTS、MMO也有,甚至有FPS,我有理由相信XNA在主流平台上不会因为“效率”问题而障碍掉。

另一方面对于C#的性能,我一直认为托管语言对于CPU密集型操作不会落后Native语言很多,国内外很多测试也证明了这点。但是我对内存密集型操作还是比较担忧,GC的难以控制常常造成不合时宜的大规模回收内存而lag掉本来稳定的FPS。而使用C/C++的话可以很小心地自己控制平稳地申请/释放内存。对于JIT,我想说:这点时间就忽略吧,实在觉得几个ms的时间也要争的话,就在调用前先把重量级函数调用一下热个身不就好了?

话说回来,XNA虽然有其不足,但是他带来的开发效率的提高也是很可观的。

以下为废话:

我那个繁花曲线写得不好,我忘记极坐标下子坐标的坐标变换怎么做了,所以我得先变成直角坐标再变回来,效率有折扣。还有一个,到绘图点离边界或者圆心的近的时候,小圆圆心角步进量对绘图点移动的线速度贡献会小很多,这样会造成内外圈密集,中间稀疏,就像上图中最大那组曲线的效果,会比较不优美。

谁能支个招解决这个问题啊?

最后是显摆:

来个日本的弹幕飞行设计游戏截图,我玩的。

这个弹幕有5000发吗?有吗?有吗?有吗?有吗?(回音……)