Flash与Flex3结合学习心得体会

作者:网络 来源:佚名 更新时间:2009-07-04 18:30:42 点击:

今天折腾了大半天flash与flex3的配合,特总结一下心得体会:
1) 如果是通过embed来嵌入swf的话,flex3只支持flashcs2所创建的swf.
2) 如果是通过loader来加载的话,只有as3的swf才能在加载后被控制(这和第一点相反,我花了很长时间才弄明发现这两点,汗!)
3) 如果要直接加载到flex当中,类必须继承uicomponent,这好比在flash中必须继承displayobject
4) 如果要把flash的组建打包给flex使用,应该使用flexcomponentkit,把mc导出成swc。然后在flex中把swc配置到library path后,对应的组建就可以作为一等公明在flex中使用了。如果mc是绑定了类的,那么对应类继承uicomponent就可以了。

 

在googledocs下了一个corelib包,不是蛮实用的(前段时间还自己写trim,浪费时间啊),e文看得累,以备以后查看
//图相用法
import com.adobe.images.jpgencoder;
public function submit():void {
var encoder:jpgencoder = new jpgencoder(80);
var bytes:bytearray = encoder.encode(getbitmapdata());
var request:urlrequest = new urlrequest(upload_page);
//data值就为图片编码数据bytearray;
request.data = bytes;
request.method = urlrequestmethod.post;
//这个是关键,内容类型必须是下面文件流形式;
request.contenttype = “application/octet-stream”;
var loader:urlloader = new urlloader();
loader.load(request);
}
//加密用法
import com.adobe.crypto.sha1;
trace(sha1.hash(”132′));

//utils包比较繁锁,全都是静态方法
import com.adobe.utils.arrayutil;
arrayutil.arraycontainsvalue(arr, value);//arr是否包含value
arrayutil.arraysareequal(arr1, arr2);//arr1,arr2是否相等
arrayutil.copyarray(a);//深拷贝
arrayutil.removevaluefromarray(arr, value);//删除值value

import com.adobe.utils.stringutil;
stringutil.beginswith(str1, str2);//str1是否以str2开头
stringutil.endswith(str1, str2);//str1是否以str2结束
stringutil.ltrim(str);//去左空格
stringutil.rtrim();
stringutil.trim();
stringutil.remove(str1, str2);//从str1删除str2
stringutil.replace(input, replace, replacewith);//把input中的replace置换为replacewith
stringutil.stringsareequal(s1, s2, casesensitive);//s1,s2是否相等,casesensitive是否大小写敏感

import com.adobe.utils.dateutil;
dateutil.comparedates(d1, d2);//比较,d1>d2返回-1,=返回0,<返回1
dateutil.getampm(d);//返回am or pm
….功能比较全, 太多了, 还有几个不知道

import com.adobe.utils.numberformatter;
numberformatter.addleadingzero(5);//返回补0的数,如1变成01

import com.adobe.utils.intutil;
intutil.tohex(n,bigendian);//16进制,bigendian指定是后补0,还是前补0
intutil.rol(n, m);//n右移m位(位运算)
intutil.ror(n, m);//左移

import com.adobe.utils.dictionaryutil;
dictionaryutil.getkeys(d);//得到键名
dictionaryutil.getvalues(d);//得到值

import com.adobe.utils.xmlutil;
这个还不会用,以后慢慢摸,本来as3的xml就很完善了

corelib包下载地址


flash跨域调用问题
由于安全沙箱的限制, 处于不同域下的文件(swf, xml等)在默认状态下是不能相互调用的. 比如a域名下的flash不能访问b域名下的xml. 除非b域名在根目录下的”crossdomain.xml”文档中包含a域名. 但存在以下问题:

1) 不允许改动根目录
解决方法: 在as3允许crossdomain.xml不在根目录中,这时就要用security.loadpolicyfile(”http://www.example.com/sub/dir/pf.xml”);这样的方法来指定. 当然只有crossdomain.xml所在目录是可以访问的.

2) 不允许添加crossdomain.xml
解决方法: 如果要被读取的是swf文件, 只要在主函数中加入flash.system.security.alldomain(”a”)即可. 但如果是其他各式的文件, 比如xml文档的话怎么办呢? 可以把xml读取到b上的b.swf(b上加入flash.system.security.alldomain(”a”)). 然后在a的a.swf中加载b.swf,然后读取b.swf中的xml. 类似于:
_mc =event.target.content as sprite;
trace(_mc["var"]);



loader与urlloader的比较
as3已经中loader与urlloader是两个比较容易混淆的类,特此区分:
应用范围
loader: swf,图片(jpg,png,gif)
urlloader:文本文件(xml,php,jsp…)

使用方法
loader:
loader.contentloaderinfo.addeventlistener(event.complete, loadcomplete);
private function loadcomplete(event:event)
{ trace("done");addchild(loader);}

urlloader:
xmlloader.dataformat=urlloaderdataformat.text;
xmlloader.addeventlistener(event.complete,xmlloaded);
private function xmlloaded(event:event)
{
try {myxml = xml(event.target.data);area.text=myxml;}
catch (e:typeerror) {area.text="load faild:\n"+e.message;}
}


as3-点阵化文字


上面是这两天做的一个小东西,它能够把输入的文字用点阵来描述,并存这些信息存入一个数组当中。然后用这个数组来重新生成“文字”,这些“文字”可以由任意的sprite组成,并且可以随意加上动画。

承蒙大家厚爱,把源文件放在这里供大家下载。为了便于将来扩展,我使用的是observer设计模式,希望不会把大家搞混淆。
源文件下载



javascript与flash互动
在swfobject解决html与flash之间传递参数问题中已经简要介绍了如何使用swfobject在页面中插入flash,如何在初始时由js向flash传递参数,以及运行时flash如何调用javascript中函数。这里主要介绍运行时javascript如何互相传递参数, 并控制flash的播放。

源文件下载

其实js能直接控制flash的播放,主要通过下列方法实现:
play() —————————————- 播放动画
stopplay()————————————停止动画
isplaying()———————————– 动画是否正在播放
gotoframe(frame_number)—————- 跳转到某帧
totalframes()——————————- 获取动画总帧数
currentframe()——————————回传当前动画所在帧数-1
rewind()————————————-使动画返回第一帧
setzoomrect(left,top,right,buttom)——-放大指定区域
zoom(percent)——————————改变动画大小
pan(x_position,y_position,unit)————使动画在x,y方向上平移
percentloaded()—————————-返回动画被载入的百分比
loadmovie(level_number,path)———– 加载动画
tgotoframe(movie_clip,frame_number)- movie_clip跳转到指定帧数
tgotolabel(movie_clip,label_name)—— movie_clip跳转到指定标签
tcurrentframe(movie_clip)————— 回传movie_clip当前帧-1
tcurrentlabel(movie_clip)—————–回传movie_clip当前标签
tplay(movie_clip)—————————播放movie_clip
tstopplay(movie_clip)———————-停止movie_clip的播放
getvariable(variable_name)—————–获取变量
setvariable(variable_name,value)———–变量赋值
tcallframe(movie_clip,frame_number)—call指定帧上的action
tcalllabel(movie_clip,label)—————-call指定标签上的action
tgetproperty(movie_clip,property)——–获取movie_clip的指定属性
tsetproperty(movie_clip,property,number)-设置movie_clip的指定属性

read the rest of this entry »


flash中组件(component)的创建和使用
这里简要介绍flash中自定义组建的创建和使用方法.由于工作的原因,我用的是as2, as3的应该类似。
组建的创建
1 创建一个类文件,比如classloader。这个文件实现组件的主要功能。它可以调用其它类,比如cn.adamstudio.effects.textanimation(这个类自己写,可以是简单的一个trace),这些类将会自动打包到组件中。

//classloader类:
[iconfile("spidercore.png")];
class classloader extends movieclip
{
public function setsize()
{
_width=18;
_height=18;
}

public function donothing():void
{
// trick the compiler into including
// the textanimation class in the component.
cn.adamstudio.effects.textanimation;
}
}

2 创建一个fla文件,如swc_generator。在其中新建一个movieclip,如swc, 设置如下图:


3 在库中这个mc上右键,在右键菜单里选择”component definition…”.设置如下图:


4 此时在库面板中可以看出,mc已经转换成了一个元件.因为元件处在编辑状态.所以直接导入一个png图标到舞台上,如icon.png.这个图标是新建组建的图形标志,将来在库面板和舞台上将会看到它的身影.

5 在库中这个mc上右键,在右键菜单里选择”export swc file …”,保存swc文件.

组建的使用
1 将生成的swc文件拷入:
c:\documents and settings\user \local settings\ application data \adobe \flash cs3 \en \configuration\components\swc

2 新建一个flash文件,如test.fla.在flash中重新打开component面板后,会发现swc目录下有我们拷入的swc文件.将其拖入舞台后,在舞台上删除之.(只需要它在库中).

3 在第一帧上加入代码:
import cn.adamstudio.effects.textanimation;
var textani=new textanimation;

即使本地电脑中没有cn.adamstudio.effects.textanimation,程序照样能运行,因为它这个类已经包含在了swc文件当中.

注:swc_generator.fla和test.fla的输出设置都应该选择as2,否则无法得到正确结果;

源文件下载:源文件


as2 - 创建movieclip的子类
在flash中作视觉表现时,常常需要创建movieclip的子类。下面是一个不错的框架:

avatar子类:
class cn.adamstudio.avatar extends movieclip
{
//定义静态变量,用于初始化
public static var happy:number = 0;
public static var sad:number = 1;
public static var idle:number = 2;

//定义静态方法,用于简洁地创建自己的instance
public static function createavatar(name:string, target:movieclip, depth:number, x:number, y:number):avatar
{
var av:avatar = avatar(target.attachmovie(”avatarsymbol”, name, depth));
av.init(x,y);
return av;
}

//设置instance的坐标
public function init(x:number, y:number):void
{
setstate(avatar.happy);
this._x = x;
this._y = y;
}

//初始化instance
public function setstate(newstate:number):void
{
switch (newstate) {
case avatar.happy :
this.gotoandstop(”happy”);
break;

case avatar.sad :
this.gotoandstop(”sad”);
break;

case avatar.idle :
this.gotoandstop(”idle”);
break;
}
}
}
注:其中的静态变量和静态函数是可选的,可以根据需求的不同而有所变化。

主文档中:
import cn.adamstudio.avatar;
var av:avatar=avatar.createavatar("avatar",_root,0,200,200);

这种方法的特点和优点是用使用子类的静态方法来实例化movieclip的子类,在主文档中非常简洁。
源文件下载

as-可正可负随机数的算法
我以前的写法都是:
math.random()*2-1
今天看到一个比较有意思的写法:
math.random()-math.random()


as3鼠标坐标总结
鼠标是flash里追主要的互动因素,经常需要侦测鼠标事件(as3中鼠标事件小结)和得到鼠标的坐标。鼠标坐标的获取可以分为在文档类和在子类中,两种不同的情况。

1)如果是在时间线轴上,或者文档类上使用:
stage.mousex 和 stage.mousey

2)在子类(如_sprite:sprite)上使用:
_sprite.mousex 和 _sprite.mousey
这里得到的是鼠标相对于_sprite的坐标。如果需要的是相对于舞台的坐标,则应该使用localtoglobal,如:
var mousepoint:point=new point(_sprite.mousex, _sprite.mousey);
mousepoint=_sprite.localtoglobal(mousepoint);
trace("stage coordinates:"+mousepoint);

注:要使用以上代码别忘了 import flash.geom.point;


as3练习-往返运动


这是今天做的一个as3的运动练习,主要是加速和减速运动的配合。发现粒子多了就会出现一些奇怪的现象,比如偶尔会几个粒子在原位置闪动。可能更flash的代码执行顺序有关,暂时还搞不懂。

as3运行时错误中文说明
1000 系统内存不足。 系统可用内存无法满足 flash player 编译代码的需要。请关闭系统上正在运行的某些应用程序或进程。
1001 未实现方法 _。
1002 number.toprecision 的范围是 1 至 21。number.tofixed 和 number.toexponential 的范围是 0 至 20。指定的值不在期望范围之内。 指定的值不在 precision 参数的期望范围之内。number.toprecision 的范围是 1 至 21。number.tofixed 和 number.toexponential 的范围是 0 至 20。
1003 radix 参数必须介于 2 至 36 之间;得到 _。 为方法或属性的 radix 参数传递的值小于 2 或大于 36。请传递一个介于 2 至 36 之间的值作为 radix 参数。
1004 对不兼容的对象调用方法 _。 尝试调用的方法不适用于指定对象。如果已将原型函数从一个对象复制到另一个对象然后又调用此函数,但目标对象类型与原始对象类型不同,则会发生此错 误。请确保目标对象与原始对象的类型相同。有关详细信息,请参阅 ecmascript language specification(《ecmascript 语言规范》)第 3 版中的第 15 章。
1005 数组索引不是正整数 (_)。 尝试使用非正整数的索引值访问数组成员。仅传递正整数作为数组的索引值。
1006 _ 不是函数。 尝试调用不存在的函数时,发生此错误。请确保正在调用正确的函数且自 actionscript 2.0 以来此 api 尚未发生更改。此外,请确保正在使用正确的对象。例如,使用以下代码时,将出现此错误(由于最后一行错误调用了变量 big 而未调用变量 blg):
var blg:string = “foo”;
var big:sprite = new sprite();
var error:int = big.length();
1007 尝试对非构造函数进行实例化。
1008 _ 指代不明确;发现多个匹配的绑定。
1009 无法访问空对象引用的属性或方法。 计算结果为 null 的对象可以不包含任何属性。在某些意外(尽管有效)的情况下,可能发生此错误。以创建 sprite 对象的以下代码为例。由于从未将此 sprite 对象添加到显示列表中(使用 displayobjectcontainer 对象的 addchild() 方法),因此其 stage 属性设置为 null。在这种情况下,此示例将生成此错误,这是因为 sprite 对象的 stage 属性不能拥有任何属性: read the rest of this entry »


air-最新rssreader(基于flash)
经过长时间的努力,终于用flash cs3+as3+air beta2做出了rssreader 2.0。
前一段时间用html+js做了个wordpressreader, 虽然实现了自动升级,等很cool的功能,但界面还是比较简朴。
air读取blog rss - adobe air beta2 实践
wordpressreader 1.1 完成

这次做的rssreader是基于actionscript3的,界面漂亮了很多,而且用户体验也有了显著的提高。
程序下载:http://www.adamstudio.cn/blog/download/rssreader.air
初始介面:

文章阅读界面:

实现的功能:
1 读取服务器端xml文档;
2 将读取的xml文档储存到air的内建本地数据库sqlite !!!(太酷了!)
3 判断网络连接状况,如果网络畅通就读取并以动画的形式展示文章标题,同时用最新文章刷新sqlite中已有文章。如果网络不通,则读取并显示sqlite中储存的文章;
4 以动画形式展示动画文章标题;
5 自定义事件和文章标题与文章内容之间的切换。

多说也无用,试用一下你就知道adobe air有多强了!
程序下载:http://www.adamstudio.cn/blog/download/rssreader.air


flash-navigatetourl取代geturl
as3中使用navigatetourl取代了geturl,个人感觉navigatetourl最大的好处就是方便了传递参数,不足的地方嘛,据说弹出的新窗口会被浏览器拦截。需要使用:externalinterface.call(”window.open”,winurl,”");来避免,但是这是采用了调用js来做,是必须在浏览器支撑并且js可以使用的情况下(没有测试)。
另外发现在adobe air中使用navigatetourl打开连接时,只能在新窗口中打开(不会被浏览器拦截),”_self”,”_parent”,”_top”都没有用.而且都是调用浏览器,而不是在air中打开.

具体用法如下:

package {
import flash.display.sprite;
import flash.net.navigatetourl;
import flash.net.urlrequest;
import flash.net.urlvariables;

public class navigatetourlexample extends sprite {

public function navigatetourlexample() {
var url:string = “http://www.adobe.com”;
var variables:urlvariables = new urlvariables();
variables.examplesessionid = new date().gettime();
variables.exampleuserlabel = “your name”;
var request:urlrequest = new urlrequest(url);
request.data = variables;
try {
navigatetourl(request);
}
catch (e:error) {
// handle error here
}
}
}
}


flash-如何改变动态文本透明度?
因为flash的系统字体不直接支持透明,所以我们得通过嵌入字体或者filter类来解决。简单地通过改变动态文本的alpha或者它做在的mc的alpha都是没有用的。

1 嵌入字体
这种方法最简单,选中动态文本框,然后在属性面板中点嵌入(“embed”)按钮,按后选择要全部字库嵌入,还是只嵌入部分字符。但代价是文件会变大,尤其在嵌入中文字体的时候,绝对是噩梦。当然只是嵌入下载进度0-9这样简单的几个字符,还是非常方便的。

2 filter
这是从blueidea学来的,就是给动态文本增加一个滤镜,即使是空滤镜也可以。
as3中代码
//建立动态文本
var my_txt:textfield=new textfield();
my_txt.autosize = textfieldautosize.left;
my_txt.background = true;
my_txt.border = true;
my_txt.text = “hello world and welcome to the show.”;
//定义滤镜
var txt_blur:blurfilter = new blurfilter(0, 0, 0);
my_txt.filters = [txt_blur];
my_txt.alpha = 0.5;
//加入动态文本
my_txt.x=my_txt.y=50;
addchild(my_txt);
as2中代码
import flash.filters.blurfilter;
var txt_blur:blurfilter = new blurfilter(0, 0, 0);
this.createtextfield(”my_txt”, 1, 100, 100, 300, 100);
my_txt.text = “ddggdgdgdgdg”;
my_txt.filters = [txt_blur];
my_txt._alpha = 50;

3 bitmapdata 和 colormatrixfilter
据hbro说bitmapdata和colormatrixfilter也能实现动态文本的半透明效果。但我这人比较懒,发现一种方法之后就犯懒了。以后有时间再研究吧 ,哈哈。


as3中鼠标事件小结
鼠标事件(mouseevent)和鼠标位置(as3鼠标坐标总结)是ria中最重要的人机交互途径。最近在做一个动态产品展示的系统produtshow的时候才发现自己对鼠标事件的了解有多么肤浅。现在productshow已经做完了,这里把在使用鼠标事件时要注意的问题总结一下:
1 鼠标事件分为mouse_over, mouse_move, mouse_down, mouse_up, mouse_out, mouse_wheel和mouse_leave。其中前六个事件都来自flash.events.mouseevent类,最后一个mouse_leave却是来自flash.events.event,在导入类包的时候一定要注意这个问题,因为我在这点上就花了很长时间调试,才得发现问题所在。
mouse_over - 鼠标移动到目标对象之上时触发, 可以用于模拟按钮的mouse over效果;
mouse_move - 鼠标在目标对象之上移动时触发,主要用于判断。比如判断在拖拽实例时,实例是否在允许的范围之内,如果超出,立刻停止拖拽或者重新设定实例的坐标;
mouse_down - 鼠标在目标对象之上按下时触发。注意,只有按下鼠标左键时才会触发,右键和滚轮都不会触发。在目标对象之外按下鼠标左键,再移动到目标对象之上时,也不会触发;
mouse_up - 鼠标在目标对象之上松开时触发。注意,只有松开鼠标左键时才会触发,右键和滚轮都不会触发。在目标对象之上按下鼠标左键,再移动到目标对象之外松开时,不会触发。但在目标对象之外按下鼠标左键,再移动到目标对象之上松开时,就会触发。
mouse_out- 鼠标移动到目标对象之外时触发。
mouse_wheel - 鼠标在目标对象之上转动滚轮时触发。
mouse_leave - 当光标离开舞台时触发(stage.addeventlistener(event.mouse_leave,leavehandler);)。在使用自定鼠标后,在鼠标离开舞台时,触发mouse_leave事件,然后可以把自定义的鼠标隐藏掉,避免还停留在舞台上。

2 mousechildren。目标对象中含有子实例时,感应鼠标行为的是子时列,而非目标对象。如果使用 cursor.mouseenabled=false; 就可以由目标对象来更应鼠标行为。

3 mouseenabled。当实例重叠时,出于显示列表上方的实例总比下方实例更有优先权感应鼠标行为。当想让下方实例感应鼠标行为时使用 cursor.mouseenabled=false; 即可。这常用于自定义鼠标后,去除自定义鼠标对鼠标行为的干涉,因为自定义鼠标往往一直处于鼠标下方,其他实例无法再感应到鼠标的变化。

另外,也许double_click也应该算做鼠标事件,但要使用它,必须先让doubleclickenabled=true:
var bg:sprite=new sprite();
bg.doubleclickenabled=true;
bg.addeventlistener(mouseevent.double_click,clickhandler);


typeof、is、as的区别
typeof、is、as都是用于判断变量类型的,只是各自的返回值不同。请看下方代码:
var a:number=0;
trace(typeof(a));//输出:number
trace(typeof(typeof(a)));//输出:string
trace(a is number);//输出:true
trace(a as number);//输出:0
trace(a as string);//输出:null



null、nan和undefined的区别
其实null、nan和undefined都是变量的默认初始值。变量类型不同,系统给与的初始值就不同:
int,uint - 0
boolean - false
number - nan
string,array,object - null
未指定变量类型 - undefined



swfobject解决html与flash之间传递参数问题
在彻底摒弃adobe的激活activex控件的方法一文中已经详细分析了使用adobe提供的ac_runactivecontent.js导致html与flash之间不能传递参数的问题。经过adobe论坛里gwd的提示,我转而寻求swfobject的帮助。发现swfobject是一个很好的解决方案。

swfobject英文介绍:http://blog.deconcept.com/swfobject/
swfobject中文翻译:http://www.awflasher.com/flash/articles/swfobj.htm
源文件:swfobject 1.5

关于swfobject的介绍上面两篇文章已经讲的很详细了。我这里只列一段标准的应用和一些上面两篇文章没有提到的问题.

html中的js代码
<script type="text/javascript" src="swfobject.js"></script>
<script type="text/javascript">
// <![cdata[
var so = new swfobject("ascalljs.swf", "mydemo", "500", "400", "9", "#ff6600");
so.addvariable("param1", "parameter1"); // this line is optional, but this example uses the variable and displays this text inside the flash movie
so.addvariable("param2", "parameter2");
so.useexpressinstall('expressinstall.swf');
so.write("flashcontent");
// ]]>
</script><!--被as调用的js函数-->
<script language="javascript">
// <![cdata[
// adds two numbers, and sends the result back to actionscript
function addnumbers(num1, num2)
{
result=num1 + num2;
alert("3+7=" + result);
return (result);
}
// ]]>
</script> read the rest of this entry »


彻底摒弃adobe的激活activex控件的方法
大家知道,在ie中只有激活了activex控件,flash才能够与浏览者交互,否则得手动点一下激活。flash也提供了一个很“方便”的解决方案,就是在发布swf文件的同时,发布html文件即可。这样flash会在生成一个swf文件,一个包含swf的html文件,和一个“ac_runactivecontent.js”文件。html文件通过调用ac_runactivecontent.js,实现激活activex控件。这一切都很便捷,直到你希望在html和flash之间传递参数。
问题出现
在很多商业网站中,都涉及到用同一个flash来显示大量不同的内容(图片,视频或产品信息等),这就需要向这个flash传递参数。常见的传参方法有三种,但都会受到ac_runactivecontent.js的不良影响。
1 externalinterface: 这是困扰我最久的一个问题。据adobe的描述,这是最好的传参方法,能都非常自由和直接地在as和js之间互相传递参数或者互相调用函数。但我在使用adobe的示例文件时发现,在ie中as无法得到js的返回值(externalinterface在ie中的bug),经过不断的尝试才发现是ac_runactivecontent.js在捣鬼,只要把它和html中对应代码以及<noscript></noscript>删除就一切正常了。
请看示例:
player8,as2: http://www.adamstudio.cn/lab/var/test/test_v8.html
player9,as3: http://www.adamstudio.cn/lab/var/test/test_v9.html
如果带有激活activex控件的那段js代码,ie中就无法得到返回值,请看:
http://www.adamstudio.cn/lab/var/test/test_error.html
所有源文件:http://www.adamstudio.cn/lab/var/test/test.rar
2 flashvars:
3 url传递参数
后两种方法受ac_runactivecontent.js的影响更大,因为这两种方法都是在<noscript></noscript>之间加入代码,而在js能运行的浏览器当中(绝大多数浏览器都能运行js),这些代码根本就不会运行。所以无论在firefox或者ie中都不起任何作用!
也就是说常用的三种在html与as之间传递参数的方法均受到激活activex控件的那段代码的影响。所以要想在html和flash之间传递参数,就必须摒弃flash自带的激活activex控件的方案!

替代方案:swfobject 请参考swfobject解决html与flash之间传递参数问题