代码改变世界

silverlight游戏设计(三)性能优化篇(上) -- Storyboard与DispatcherTimer的使用

2010-12-23 13:55  姜 萌@cnblogs  阅读(1624)  评论(1编辑  收藏  举报

其实说起性能优化,与其说是技术问题,不如说是编程习惯问题。

在我之前所经历的webgame项目中,

sl与flash对比?按照微软的说法,或许sl能够比flash性能更强。但是如同评判一个程序的好坏一样,绝大多数情况下性能的优劣取决于你是怎么写的代码而不是所依托底层技术。

引起注意

我小小总结了一下,在UI层次上应该注意一下几点:

不要过分使用Storyboard

不要过分使用BitmapEffect

不要过分增加线程数量(比如DispatcherTimer)

自定义控件时精简视觉树,尤其是不必要的容器

合理使用silverlight的GPU加速设置

使用字典而不是遍历(O(1),O(N))

即时清理资源(两个层次,一是释放对象引用、停止不再显示的storyboard,二是显式的调用GC)

…… 

Storyboard

有了blend这样的神器,与其说我们是写动画倒不如说是设计动画。在silverlight的webgame中,我们可以通过storyboard为游戏中的shape附加上n多种变换动画诸如形状、角度、大小、位移、bitmapeffect属性等的渐变,这样一个“特效”就出来了。Storyboard确实很方便,但如果同时开启多个storyboard就会产生很大的性能消耗。下面我们来做个测试,这里有6个球,把鼠标点击任一个球都会触发动画(再次点击会停止动画),点击“全部开启/停止”会触发/停止所有动画。我把cpu占用率显示在最上面了,让我们来看看最后的测试数据。

image

 

动画描述 silverlight cpu占用

不运行任何动画

1%-3%

激活1个动画(这里选取变换ScaleTransform属性,第一行第1个球):

6%-8%

激活1个动画(这里选取变换ScaleTransform属性,带缓动,第一行第2个球):

6%-8%

激活2个动画(这里选取两个变换ScaleTransform属性,第一行前2个球):

10%-17%

激活4个动画(这里选取两个变换ScaleTransform属性,第一行前4个球):

16%-23%

激活所有动画:

21%-29%

可见如果游戏中有多个storyboard动画运行,会消耗不少的性能。通常在UI提醒动画、场景中的动画(比如地图上的一些传动点动画)如果都是用storyboard做的,由于这些动画往往设计成一直运行(RepeatBehavior=Forever)性能会很不好。

DispatcherTimer

在silverlight游戏中,DispatcherTimer是一个重要的角色,如果是一般的Thread或者Timer,我们在其中操作UI时需要借助Dispatcher.BeginInvoke这样的api传送委托,而有了DispatcherTime我们无需关心线程关联性因为其内部已经做好了这部分处理。

DispatcherTimer可以做什么呢,最常见的就是操作游戏中的“精灵”。对于一个好的MMORPG而言,同屏几百人是常有的事。原则上我们需要用最少的线程处理逻辑,当然对于这里的逻辑尽量不要复杂,尤其是不要使用迭代。关于游戏中精灵的设计和精灵的控制会在以后文章给出。

另外大家可以参见杨哥的Silverlight C# 游戏开发:游戏循环体的五种设计方式

原理很简单,这里不多做解释。

实验

实验1:开启100个DispatcherTimer,每个DispatcherTimer分别对一个rect操作实现动画效果。cpu占用大概是16%:

image

实验2:开启1个DispatcherTimer,对100个rect操作实现动画效果。cpu占用大概是11%:

image

 

你也可以动手实验

测试页1:把鼠标点击任一个球都会触发动画(再次点击会停止动画)。

测试页2: 输入数字,选在“多dispatchertimer测试”、“单dispatchertimer测试”。

Get Microsoft Silverlight

本文源码下载