Archive for ‘Develop’

PV3D Culling & Clipping

今天来谈谈3D开发中的两个重要知识点Culling(剔除)和Clipping(切分)。

render

左图表示一个完整的3D渲染流程,可以看到Culling和Clipping处理发生在投射计算和渲染计算之前。

Culling过程是用于剔除不需要参与渲染的物体和三角面,从而达到节约资源的目的。一般来说Culling分为以下4种:

  1. Frustum culling:视锥剔除,PV3D里最重要的剔除方式,下面详述。
  2. Back-face culling:当面背对相机时候剔除,由PV3D自动执行。
  3. Contribution culling:当物体在画面上过小情况下的剔除,PV3D里面没有这种机制,但是可以用远平面(camera.far)来剔除。
  4. Occlusion culling:包藏剔除,适用于一个物体完全被另一个物体遮挡的情况,PV3D不包含这种机制。

Frustum culling在PV3D中分两种:分别是基于camera(相机)和基于viewport(视口)的。

使用以下代码开启基于相机的剔除功能(DebugCamera是默认开启的):

camera.useCulling = true;

通过查看do3d.culled属性可以知道物体是否被剔除。要注意这种剔除机制是针对整个物体(do3d)计算的,只有当整个物体完全不在视锥内,才会被剔除。


More...

Design Pattern #2 – Singleton, Registry & Dependency Injection

在MVC模式的具体实现中,另一个令人困扰的问题就是:如何处理各个对象之间的依赖关系。

2010-02-25_00606

Ricard Lord在Flex London User Group上的演讲清楚的描述了这个问题。

在DI(Dependency Injection 依赖注入)还没有被引入ActionScript框架开发中的年代,处理依赖关系的方法主要就是利用Singleton(单例)模式。这是一种被滥用得最多的模式。包括Adobe官方的MVC框架Cairngorm也是使用这种模式。

后来的PureMVC采用了Registry Pattern / Model Locator Pattern来代替单例,但是也没能从根本上解决问题。类中包含了冗余的代码去获取依赖,也使得单元测试变得困难。

ActionScript 3新增的反射机制让DI模式的实现成为可能,也让ActionScript开发框架的发展更接近于Java等成熟语言。MateSwizParsley和后面要介绍的Robotlegs都使用了DI模式。

其实不论是Singleton,Registry还是DI,都是要解决OOP中的依赖问题。但只有DI模式通过语言的反射机制实现了运行时注入的功能,从而将编译时依赖转移到了运行时。

当前最流行的开发框架是Robotlegs,它在PureMVC的基础上修改而来,被业内誉为“正确的PureMVC”。Robotlegs通过SwiftSuspenders类库实现了基于自定义元数据(meta)的依赖注入功能,建立了MVCS(Model-View-Controller-Service)模式的基本构架。作者Shaun Smith在这篇文章中详述了框架设计背后的思想。

上篇文章介绍MVC基本概念的时候提到用Observer模式来实现松耦合。在上述几个ActionScript框架中,都用不同的方式实现了系统事件发送类的单例(Single Event Dispatcher):通过一个统一的事件发送者在MVC架构中的对象之间传递信息。

但是,由于ActionScript的事件机制并不完美,所以最近业内又开始流行使用Robert Penner开发的代替方案AS3 Signals。我曾经做过一番尝试:可以告别编写事件名常量和自定义事件的繁琐,可以将事件写入接口等特性给人的感觉果然比较直观。所以如果将来Robotlegs能够在事件机制上整合Signals那就更好了,比如这个

至此MVC模式的介绍就告一段落,总结来说:MVC把GUI程序划分为Model Layer和Presetation Layer,设计了Model-View-Controller三大模块的职责和关联方式。在表现层根据不同的耦合关系又细分多种模式。MVC现在的发展趋势是用DI、Observer模式等方法来实现模块之间的松耦合。

最后一点题外话,Ricard Lord的演讲还提到了Framework和Toolkit的区别,主要就是是否需要继承框架里的基类。Toolkit比较灵活,无需更改对象的继承关系。Robotlegs就属于这种,所以已经有出现把RobotlegsGaia Framework结合在一起的尝试

Design Pattern #1 – MVC & MVP

学习Design Pattern(设计模式)不是为了搞学术研究更不是装B,主要还是我有点洁癖:面对越来越复杂的ActionScript开发(主要是网站,还不包括Flex),我希望找点理论依据来做下指导,不仅把开发思路整理地井井有条,也可以更合理的分工协作。在我看来设计模式就是针对写代码中通常会遇见的情况而给出的指导性方法。遵循设计模式而写的代码最大的好处就是很直观,逻辑很清晰。当然还具有易扩展、易测试、可重用等等等等好处。本文大多数是这几年的开发经验有感而发,不是很严谨的学术文章,如有错误疏漏之处,请多包涵。

今天要谈的设计模式是在GUI程序设计中最常见的模式之一:MVC。在我2004年写论文的时候,曾把MVC模式和Web开发中的三层结构的概念混为一谈,直到今天才发现一直是我的理解错误。MVC模式是GUI界面开发的指导模式,基于表现层分离的思想把程序分为三大部分:Model-View-Controller,呈三角形结构(如下图)。Model是指数据以及应用程序逻辑,View是指Model的视图,也就是用户界面。这两者都很好理解,关键点在于Controller的角色以及三者之间的关系(也就是图中的那几个箭头)。

MVC

在MVC模式中,Controller和View同属于表现层,通常成对出现。Controller被设计为处理用户交互的逻辑。一个通常的误解是认为Controller负责处理View和Model的交互,而实际上View和Model之间是可以直接通信的。由于用户的交互通常会涉及到Model的改变和View的更新,所以这些可以认为是Controller的副作用。认清模式设计的目的对于帮助区分后来的MVP模式非常重要。

再来看看MVC架构图中的一条虚线。出于Model需要与View保持同步的基本需求,最初设计的时候这条也是实线,表示Model和View是紧密耦合的。但是实际开发中View通常都不是唯一的,为了适应一个Model对应多个View的情况,引入了Observer模式(在ActionScript开发中可以认为是事件机制)。在这种模式下,Model并不需要知道有多少View的存在,View观察/监听Model发生的改变并作出对应的更新。有兴趣的朋友可以看看关于这两种同步方式的描述:Flow SynchronizationObserver Synchronization

MVC模式出现在1978-1979年间,当时的用户交互还很简单。随着计算机图形界面的发展,用户界面越来越复杂,开始包含更多的显示逻辑。比如很多开发工具支持数据绑定,事件绑定等等特性,一些对用户交互的处理已经封装到组件中去了。所以为了适应这些转变,MVC模式也出现了很多变体,其中最著名的就是Dolphin Smalltalk的MVP(Model-View-Presenter)模式。

MVP

我们可以对比上图与MVC模式的结构,好像仅仅是把Controller换成了Presenter。这可不是在玩文字游戏。在MVP中,Persenter被设计为包含表现层逻辑的单元。与Controller相对的是,Presenter主要是负责表现逻辑,处理用户交互变成了附带的功能。主要设计的目的的不同决定了模式的不同。

其实MVC发展到今天,Controller早已是Presenter的内涵,但开发者们习惯上还是都用Controller来描述。

2006年,Martin Fowler把MVP模式细分为两种表现层模式(Presetation Pattern):Supervising ControllerPassive View

SupervisingController
Supervising Controller

PassiveView
Passive View

Model-View-Controller三者之间的明暗对比关系说明了表现层在MVC模式中所处的位置。Supervising Controller和Passive View之间的区别在于后者完全切断了View和Model之间的联系,使得Controller变为View的代理。如果需要数据绑定等特性支持,或者考虑把一些简单的交互逻辑放在View中,就属于Supervising Controller模式。

此外,还有几种模式也属于表现层模式:Presentation ModelView HelperCode Behind。其中只有Code Behind模式是用继承的方式实现的,Flash IDE下的文档类和类绑定就是属于这一种。几种模式的区别主要是以下几点:

  1. View和Presenter/Controller是否存在相互引用
  2. 状态保存在哪里
  3. 逻辑保存在哪里
  4. 单元测试是否容易进行

相对而言,用复合方式实现的模式灵活性较高一些。具体细节可以去这里看详细介绍,这里就不细述了。

本文主要总结了MVC/MVP模式中三者的概念区分,以及它们的联系。下一篇中我们就通过几个流行的ActionScript MVC框架来学习MVC模式中另一个重要的知识点:如何实现三者之间的联系——基于单例、注册模式或者依赖注入。

参考资料:

X’mas

新鲜出炉!ES创意部呕心沥血制作之圣诞树工坊,祝大家圣诞快乐~

ES X'mas 2009

深入Flash CS4编译技术

Compiled Clip和SWC File

Compiled Clip和SWC File都包含经过编译后的Flash内容,区别在于:一个是“Clip”,存在于库中;另一个是“File”,是独立的文件。

2009-12-09_00391

如上图所示,在为ActionScript导出的元件上点击右键,可以看到生成Compiled Clip和导出SWC File的选项。这里常见的误解是以为这个操作只会编译当前选择的元件,实际的情况是除此之外还会把库中所有第一帧导出的元件也一同编译进来。要确认Compiled Clip或者SWC File中包含了些什么类,可以用闪客精灵等破解软件或者Flash Develop自带的SWC浏览工具来分析。


More...

Page 1 of 1912345»...Last »