一般我们谈到FLEX,首先想到的就是它的组件框架。然而,FLEX SDK与FLEX Builder其实两个不同的产品,一个是开源免费的,一个则不是。后者是前者的支持,但并不是只能作为前者的支持。
当建立AS project项目的时候,FLEX Builder只会使用FLASH的内置类库来进行编译,所以和通常意义的FLEX完全不同,而是区别于FLASH的另一种编译AS文件的手段。下面将会就如何将一个项目从使用FLASH CS3/4迁移至FLEX Builder做出说明。

一个具体项目,是由表现与逻辑两部分组成的。FLA内的图形元件是表现,而AS则是逻辑。所以我们首先的问题就是,如何将表现与逻辑联系在一起。
CS3/4的方法大家应该都很熟悉,就是绑定类。给元件取个类名,相应目录放上一个AS文件,就能将两者联系起来。而在FLEX中,实现这样的功能有两种方法:

1.        Embed
FLEX AS project唯一比FLASH内多的内容,就是这样的元标签。
了解FLEX的应该对Embed非常熟悉,是主要的导入外部资源的方式。具体写法如下:
[Embed(source=”xxx.swf”,symbol=”symbol_name”)]
Public var imageClass:Class;
在之后的语句里,只要var newins:Sprite=new imageClass();addChild(newins);就可以将这个图形元件呈现出来。然而,每次都要建立一个Class的确有些麻烦。下面这种写法是FLEX文档没有涉及的,所以很多人都不知道,实际上可以这样写:
Package{
Import flash.display.Sprite;
[Embed(source=”xxx.swf”,symbol=”symbol_name”)]
Public class ImageClass extends Sprite{
Public function ImageClass():void{
//do something….
}
//the other functions ..
}
}
也就是说,我们在原来的AS文件CLASS前面添加一句[Embed],就可以将它和对应SWF文件内的一个元件联系起来。这样的做法和直接绑定类是一样的。诸如某个元件里还设置了几个实例,如果在CS3中没有勾选自动声明实例,我们需要在AS文件中手动声明实例一样,在FLEX Builder中我们也一样需要这样做,否则就会报错:
Package{
Import flash.display.Sprite;
[Embed(source=”xxx.swf”,symbol=”symbol_name”)]
Public class ImageClass extends Sprite{
//SWF中对应元件内已取名的实例
Public var ins1:Sprite;
Public var ins2:Sprite;
Public var ins3:Sprite;
Public function ImageClass():void{
//do something….
}
//the other functions ..
}
}
说白了,结果就是这样。把原来FLA文件生成SWF,然后在AS文件头上加上Embed来实现绑定,所得到的结果和原来直接绑定是一样的。只是由FLA主动寻找链接的AS文件编译,变成了AS文件寻找指定SWF内的元件一起编译。

当然,还是有一些不同的。这样导入的元件,其内部时间线上的AS会被完全忽略,stop()也不会被保留。而且,内部元件所有的类定义也都会被忽略,只保留类名。多帧元件会被认为是MovieClip,单帧元件会被认为是Sprite,按钮会被认为是SimpleButton,位图会被认为是BitmapData(不过你如果trace一下会看到转过来的其实是对应的asset类,反正是一样的我就不作说明了),不管你原来是否给了它其他的基类,或者绑定过类文件,那部分内容都不会过来。能过来的就是帧标签,舞台上设定的实例名,grid-9定义三种。类名定义也不会过来,你将它绑定到什么类上,它就叫什么类(当然必须要兼容)。
有些时候的确不方便。不过对于游戏来说,这应该是无所谓的吧?

这里有一个例外,如果直接[Embed(source=”xxx.swf”)],不写元件名,也是可以导入的。使用这种方法,类定义,AS都可以保留,就跟直接用loader载入一个外部SWF一样。但同样的,因为两者不在同一个应用域,是不能直接交互的。这样的方法我很少用,具体也不了解,但这样做体积会比较大一点(相当于内镶SWF的字节码),不是很推荐就是了。

2.        SWC
发布设置里,勾上“生成SWC”,即可在生成SWF文件的同时生成一个对应的SWC文件。
将这个SWC文件拖到FLEX的lib目录中,建立的项目就可以直接导入它的所有类,当然也就包括所有元件了。
注意FLA写类名的时候请写好包名。否则进来的所有类全都是顶级类,不import都会被导入(带元件的类很大的――),而且非常容易产生命名冲突,毕竟这个不像第一种方法不导入类名,所以类名+包名一定要不同。
要给元件类定义, extends它就是了,FLA里的基类是什么它的基类就是什么。
Package{
Import swf1.Image1;
Public class ImageClass extends Image1{
Public function ImageClass():void{
//do something….
}
//the other functions ..
}
}
这种方法我比较少用,总觉得管理SWC文件很烦,能导进来的东西来多,感觉不如Embed单纯地导入表现好控制,而且想指哪个目录都可以,用SWC只能限定目录,需要copy来copy去,否则就要设N个lib路径。不过以后的项目我会考虑多使用SWC这样的形式,感觉这个才是主流。

两种方法,修改了swf/swc文件FLEX都不会知道的——,它会认为你没改,不进行重新编译。这时候选择它们所在目录执行刷新就可以了。或者对整个工程目录刷新,或者重启builder



好吧,现在我说优点。
1.        FLA彻底和最终出来的SWF文件没有关系了。事实上,如果你只想用位图来当资源,FLA可以完全不用(Embed可以导入位图,SWC文件也可以用FLEX lib项目来生成)。从一开始就可以完全不考虑这个问题。美工做好了图,更新已有的SWF资源库或者建一个新的都可以,反正就是个图片,每个图一个FLA都无所谓。写AS的也不用和美工抢同一个FLA文件,不管编译测试任何情况都不用。美工要改了图,输出上载,我们更新下SVN,F11,自然就更新了,和其他写AS的配合也一样。一个元件可以被多个输出的SWF所使用――大家都互不干扰,所有过程都可以并行进行。
反正就是这样。搞这个的,应该明白这对开发效率的帮助有多大。
2.        我们可以用Flex Builder来写程序。虽然这个东西是比较大点,但不载入SDK框架,图形编辑界面一般机器都是可以承受的。虽然有FD,但其实还是不如Flex方便,毕竟体积不同。而且可以和java,PHP一起编译,调试――如果需要的话。
不要和VS这样的比,有得用就不错了。
3.        同样是我不想用SWC这种方式的原因。如果用Embed这样的方式的话,绝对不可能再出现找不着代码的情况,因为找不着的代码根本就导不进来——不需要再在这些方面浪费口水了。
应该很多人对我这样的说法有意见――一定要保留时间线代码的话,用SWC导入就是了,至少我们很清楚哪些可能出问题,哪些绝不可能。
4.        这东西就是个IDE,写的还是AS,除了编译环境,还有几个元标签和以前没啥区别,应该是人都可以很容易的转移过来的,安装也简单――
总之就是这样。

缺点嘛,我想到的是
1.        AS project比较裸,除了flash包只能导入一些没啥用的包,FLEX,CS3的组件都不能用,所以我们“只能”求助于第三方类库,像aswing,TweenMax之类。
(但愿能明白我“只能”这个词意味的人能多点)
2.        不能方便,理所当然地在时间线上写代码(一点都不能写,除非找美工要FLA),可能也许会降低一点效率吧……
3.        布局方面还是受到一点限制的。不管怎么说,代码布局还是比拖拉的方式麻烦。用FLEX很多时候都得用代码来实现布局,因为无法对绑定了类的实例内部的实例再绑定类,因为方向不同了(这个比较难表达,用到了自然就明白了)。

目前,大部分公司还是不原意用FLEX来写游戏,这是个事实――
但形成这个事实的原因是复杂的,不能因为这个,就说“使用FLASH就是比FLEX好”,请大家仔细考虑下面的问题:
Adobe到底希望我们用什么来写代码?
为什么要给FLEX搞一个as project?


最后,附送一个联网升级游戏源码,做的比较早,代码比较烂就不要挖苦我了。看明白Embed怎么用就行了。
发布到IIS,tomcat之类的网络服务器,本地运行服务端SocketService.exe(C#写的需要运行库),编译根目录的两个as,然后使用teete.swf开始游戏。