`
shine1200
  • 浏览: 42041 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

巧用Event.RENDER优化Flash渲染效率

 
阅读更多
在Flash或Flex开发中,我们经常需要操作可视化的显示对象(有可能是普通的Sprite或MovieClip,也可能是更复杂的Flex Component),我们可能需要不停的设置它们的尺寸或位置,而且这样的设置代码可能会分散在我们的类的各个方法里面。注意观察您是否发现,在同一次代码执行过程中,我们会有重复性的设置工作,比如在某一个方法里设置了组件的宽度,然后在另外一个验证方法里马上又改变了这个组件的宽度。注意对显示对象的属性设置,显然要比更改一个普通对象的属性会引起更高的消耗。这样没有必要的重复性设置,如果量很大,就可能对我们应用的性能造成影响。

另一种情况是,我们设置了组件的尺寸或其它显示属性,但不希望每一次设置都对组件直接产生影响,而希望以一种合并执行的方式,这种方式显然更符合我们的期望,也可以降低一些计算量。比如我们要在组件的尺寸发生变化之后,重新绘制背景,那么我们可能先设置组件的宽度,然后设置组件的高度(或者反过来,或者只设置一个,就像下面一行代码展示的),但我们不希望每次操作都反映到组件的改变,而是缓存起来,等待下一次渲染列表更新的时候,执行渲染操作。

header.width = stage.stageWidth;
header.height = stage.stageHeight;
复制代码
如果我们不考虑性能优化,那么常规思路就是,重写width和height的getter和setter,然后在每一次设置里都调用一下绘制背景的方法,这样保证无论是单独设置宽度或高度,或者都设置,都可以让背景得以重新绘制。如下面的代码所示:



package com.riameeting.fingerchart.mobile.view
{
import flash.display.Sprite;
import flash.events.Event;
public class Header extends Sprite
{
private var _width:Number;
private var _height:Number;
override public function get width():Number
{
return _width;
}
override public function set width(value:Number):void
{
if(_width == value) return;
_width = value;
measure();
}
override public function get height():Number
{
return _height;
}
override public function set height(value:Number):void
{
if(_height == value) return;
_height = value;
measure();
}
public function Header()
{
super();
}
//绘制背景的方法
private function measure():void
{
graphics.clear();
graphics.beginFill(0xCCCCCC,1);
graphics.drawRect(0,0,width,height);
graphics.endFill();
trace("draw complete");
}
}
}
普通浏览复制代码保存代码打印代码
package com.riameeting.fingerchart.mobile.view
{
import flash.display.Sprite;
import flash.events.Event;
public class Header extends Sprite
{
private var _width:Number;
private var _height:Number;
override public function get width():Number
{
return _width;
}
override public function set width(value:Number):void
{
if(_width == value) return;
_width = value;
measure();
}
override public function get height():Number
{
return _height;
}
override public function set height(value:Number):void
{
if(_height == value) return;
_height = value;
measure();
}
public function Header()
{
super();
}
//绘制背景的方法
private function measure():void
{
graphics.clear();
graphics.beginFill(0xCCCCCC,1);
graphics.drawRect(0,0,width,height);
graphics.endFill();
trace("draw complete");
}
}
}package com.riameeting.fingerchart.mobile.view
{
import flash.display.Sprite;
import flash.events.Event;
public class Header extends Sprite
{
private var _width:Number;
private var _height:Number;
override public function get width():Number
{
return _width;
}
override public function set width(value:Number):void
{
if(_width == value) return;
_width = value;
measure();
}
override public function get height():Number
{
return _height;
}
override public function set height(value:Number):void
{
if(_height == value) return;
_height = value;
measure();
}
public function Header()
{
super();
}
//绘制背景的方法
private function measure():void
{
graphics.clear();
graphics.beginFill(0xCCCCCC,1);
graphics.drawRect(0,0,width,height);
graphics.endFill();
trace("draw complete");
}
}
}
这样的代码实现,当然是可以正常工作的,但您或许也注意到了其中存在可能重复性的执行工作。如果我们同时设置了宽度和高度,实际上绘制背景的方法被执行了两次。这只是一个简单的例子,多余的操作显然没有产生多大的影响,但防患于未然,我们是否可以优化这个操作呢?

借助于Event.RENDER事件,我们可以将属性的变更推迟到下一次渲染。思路就是,当宽度或高度改变,我们不立即触发绘制背景的方法,而是加以标记,并侦听Event.RENDER事件,在下一次渲染的时候会执行回调方法,完成背景绘制。优化后的代码:



package com.riameeting.fingerchart.mobile.view
{
import flash.display.Sprite;
import flash.events.Event;
public class Header extends Sprite
{
private var _width:Number;
private var _height:Number;
private var _needUpdate:Boolean = false;
override public function get width():Number
{
return _width;
}
override public function set width(value:Number):void
{
if(_width == value) return;
_width = value;
needUpdate = true;
}
override public function get height():Number
{
return _height;
}
override public function set height(value:Number):void
{
if(_height == value) return;
_height = value;
needUpdate = true;
}
public function get needUpdate():Boolean
{
return _needUpdate;
}
public function set needUpdate(value:Boolean):void
{
if(_needUpdate == value) return;
_needUpdate = value;
if(_needUpdate) {
addEventListener(Event.RENDER,measure);
if(stage != null) stage.invalidate();
} else {
removeEventListener(Event.RENDER,measure);
}
}
public function Header()
{
super();
}
private function measure(...args):void
{
graphics.clear();
graphics.beginFill(0xCCCCCC,1);
graphics.drawRect(0,0,width,height);
graphics.endFill();
trace("draw complete");
needUpdate = false;
}
}
}
普通浏览复制代码保存代码打印代码
package com.riameeting.fingerchart.mobile.view
{
import flash.display.Sprite;
import flash.events.Event;
public class Header extends Sprite
{
private var _width:Number;
private var _height:Number;
private var _needUpdate:Boolean = false;
override public function get width():Number
{
return _width;
}
override public function set width(value:Number):void
{
if(_width == value) return;
_width = value;
needUpdate = true;
}
override public function get height():Number
{
return _height;
}
override public function set height(value:Number):void
{
if(_height == value) return;
_height = value;
needUpdate = true;
}
public function get needUpdate():Boolean
{
return _needUpdate;
}
public function set needUpdate(value:Boolean):void
{
if(_needUpdate == value) return;
_needUpdate = value;
if(_needUpdate) {
addEventListener(Event.RENDER,measure);
if(stage != null) stage.invalidate();
} else {
removeEventListener(Event.RENDER,measure);
}
}
public function Header()
{
super();
}
private function measure(...args):void
{
graphics.clear();
graphics.beginFill(0xCCCCCC,1);
graphics.drawRect(0,0,width,height);
graphics.endFill();
trace("draw complete");
needUpdate = false;
}
}
}package com.riameeting.fingerchart.mobile.view
{
import flash.display.Sprite;
import flash.events.Event;
public class Header extends Sprite
{
private var _width:Number;
private var _height:Number;
private var _needUpdate:Boolean = false;
override public function get width():Number
{
return _width;
}
override public function set width(value:Number):void
{
if(_width == value) return;
_width = value;
needUpdate = true;
}
override public function get height():Number
{
return _height;
}
override public function set height(value:Number):void
{
if(_height == value) return;
_height = value;
needUpdate = true;
}
public function get needUpdate():Boolean
{
return _needUpdate;
}
public function set needUpdate(value:Boolean):void
{
if(_needUpdate == value) return;
_needUpdate = value;
if(_needUpdate) {
addEventListener(Event.RENDER,measure);
if(stage != null) stage.invalidate();
} else {
removeEventListener(Event.RENDER,measure);
}
}
public function Header()
{
super();
}
private function measure(...args):void
{
graphics.clear();
graphics.beginFill(0xCCCCCC,1);
graphics.drawRect(0,0,width,height);
graphics.endFill();
trace("draw complete");
needUpdate = false;
}
}
}
如果您也从事Flex开发,那么应该了解到在Flex的组件设计中已经应用了这种实施模式,以便让结构复杂的Flex组件尽可能的获取更好的渲染效率。比如Flex组件的callLater事件,就是这个思路。您可以查阅Flex文档了解这方面的信息。
分享到:
评论

相关推荐

    flash as3 pv3d实现的魔方效果源文件

    在渲染函数中,我们会更新物体的位置和旋转,然后使用`render()`方法绘制场景。 6. **光照和材质**:为了增加视觉效果,我们可以添加光源和材质。PV3D中的`PointLight`或`DirectionalLight`类用于模拟光线,`...

    As3.0通过XML加载图片3d效果

    ActionScript是Adobe Flash Professional和Flex Builder等工具中的编程语言,广泛用于创建互动性的Web内容,而XML则是一种结构化数据格式,常用于存储和传输信息。 首先,让我们理解XML在AS3.0中的应用。XML是一种...

    如何把Papervision3d物体加到 flex项目中(附 旋转圆球例子)

    Papervision3D是一个强大的开源库,用于在Adobe Flash Player环境中构建三维(3D)图形。而Flex则是一种基于ActionScript 3.0的开发框架,用于构建富互联网应用程序(RIA)。将两者结合,可以创建具有高级3D视觉效果...

    starling中文API

    10. **Performance优化**:Starling提供了一些性能优化技巧,比如使用RenderState来减少状态切换,使用CacheAsBitmap提高复杂形状的绘制速度。 总之,"Starling中文API"是开发者掌握Starling框架的关键资源,它详细...

    使用FLEX 和 Actionscript开发FLASH 游戏(四)-1

    在本篇教程中,我们将继续深入探讨如何使用FLEX和ActionScript开发Flash游戏。在上一部分,我们学会了在屏幕上绘制图形。现在,我们将使游戏更具交互性,添加鼠标输入功能,以及创建动态背景,使玩家的飞船能在其中...

    fusion chart 多曲线图

    SWF文件是Adobe Flash的文件格式,以前常用于在网络浏览器中展示动态内容,包括图表。 首先,要创建一个多曲线图,你需要在HTML页面中引入FusionCharts的JavaScript库和SWF文件。SWF文件是FusionCharts的核心组件,...

    Papervision3D Essentials 源码

    RenderEngine负责将3D模型渲染到2D屏幕上。 4. **材质与纹理**:Material和Texture类是定义物体表面特性的关键,包括颜色、反射、透明度等。通过它们,可以给3D对象赋予丰富多彩的外观。 5. **灯光系统**:Light类...

    pv3d场景旋转图源码

    在3D图形编程领域,PV3D(Papervision3D)是一个广泛使用的开源库,主要用于Adobe Flash平台上实现三维图形和交互式场景。PV3D利用ActionScript 3.0语言,为开发者提供了构建复杂3D场景的能力,包括动画、交互和视觉...

    Openlayers实现扩散的动态点(水纹效果)

    动态扩散的核心在于`flash()`函数,它使用`requestAnimationFrame`来实现动画效果。这个函数会在每次地图渲染后执行,逐步改变点的大小和透明度,模拟扩散的效果: ```javascript var duration = 1000; function ...

    starling使用范例

    Starling是一个基于Adobe Flash Player和Adobe AIR的2D游戏开发框架,它利用硬件加速图形渲染,为开发者提供了高性能的游戏开发环境。本示例主要讲解如何使用Starling进行基本的编程实践,包括创建舞台、添加图像、...

    Osg开发问题文档

    2. **优化策略**:考虑使用动态链接来减小最终可执行文件的大小。 #### 七、OsgWidget中嵌入Flash **问题描述**:使用`osgWidget+Hikari`库来嵌入Flash内容,但存在兼容性和稳定性问题。 **解决方案**: 1. **...

    ExtAspNet_v2.3.2_dll

    -修正CheckBox控件的CheckedChanged事件会被触发两次的BUG(Data PostBack->AutoPostBack, Event PostBack->EnablePostBack)。 -为TextBox,TextArea,DatePicker,NumberBox,TriggerBox等控件增加AutoPostBack属性...

    flex 树状图

    Flex是一种基于ActionScript和Flash Player运行时的开源框架,用于构建富互联网应用程序(RIA)。在Flex中,可以使用Tree控件来创建树状图,它能够以层级结构展示数据,适用于展示目录、组织架构或者复杂的数据关系...

    ExtAspNet v2.2.1 (2009-4-1) 值得一看

    -修正CheckBox控件的CheckedChanged事件会被触发两次的BUG(Data PostBack->AutoPostBack, Event PostBack->EnablePostBack)。 -为TextBox,TextArea,DatePicker,NumberBox,TriggerBox等控件增加AutoPostBack属性...

    flex lifecycle

    - Flex 会在渲染事件 (`render event`) 发生时调用这些方法。 #### 三、关键方法解析 - **`invalidateProperties()`:** 通知 Flex 在下一个验证周期执行 `commitProperties()` 来处理属性变化。 - **`...

    超级玛丽游戏

    主循环通常包含三个主要部分:更新(Update)、渲染(Render)和事件处理(Event Handling)。 2. 碰撞检测:游戏中的碰撞检测是确保角色与环境、敌人、道具等交互的关键。超级玛丽中,需要对马里奥、砖块、蘑菇等...

Global site tag (gtag.js) - Google Analytics