一些容易混淆的AS3问题,肯定让你有收获

先说的最基础的:今天看到Aone发现一个switch扩展应用,一下仿佛自已好傻,一直以为switch没什么太大用处,原来是我们学艺不精啊。 switch可以这么写:[color=#800000]var d:int=0switch(true){ case aone(d): trace(“测试测试啊~都闪开点~被trace到了不负责啊~”) break}function aone(d:int):Boolean{ return d<100?true:false}或者直接省略var d:int=0switch(true){ case d<100: trace(“测试测试啊~都闪开点~被trace到了不负责啊~”) break}case 可以用条件语句,还可以用方法,switch()里的参数也可以换成函数的。正式开始今天的一问一答:舞台与时间轴问答舞台和时间轴的真相正如相对论一样 是不引起注意的,但真相带给我们的收获是巨大的。为了使得教程更加面向原因,这里采用问答形式慢慢揭开面纱。本着辩证的思想,在每个观点的背后尽量用实际 的代码去求证。当然,还是按照从浅到深的顺序开始。问:flash中的主时间轴是舞台吗?答:否,时间轴不是舞台。舞台是播放器。舞台可能是安装到程序中 的flashPlayer.exe播放器,也可能是网页中的控件,还可以其它语言如vb,vc,中的控件。主时间轴是播放器播放的swf文件,也是常说的 文档类。而舞台是Stage类。问:什么是文档类?答:文档类基于MovieClip。是与主时间轴绑定的类。我们可以自定义类与它绑定,如果不指定则自 动生成MainTimeline类。证明:新建一个swf,在第一帧输入:trace(this is MovieClip),向上转型成功,返回true。问:MainTimeline做了什么事情?答MainTimeline类自动导入了flash核心 类库,以flash开头的包都被导入了。核心类库的swc文件名为:playerglobals.swc。可以在flash的安装目录下搜索到。 MainTimeline还自动生成对舞台上的对象引用并初始化。证明:我们在文档类中建立一个空类:复制内容到剪贴板 代码:package{ import flash.display.Sprite; public class Document extends Sprite { }}然后在时间轴第一帧输入var shape:Shape=new Shape();报错,原本可以直接使用的Shape没有定义。附:as3不建议在时间轴上写代码,因为那是脚本编程方式,但在时间轴上非常适用调试代 码,因为省去了导入,构造函数等等繁琐的事情。问:全局坐标指的主时间轴坐标还是舞台坐标?答:指舞台坐标。证明:在舞台上画一个方块,起名为mc。在第 一帧上输入如下代码:复制内容到剪贴板 代码:mc.addEventListener(MouseEvent.CLICK,clickHandle);function clickHandle(evtObj:MouseEvent):void{ var point=new Point(evtObj.localX,evtObj.localY); trace(p); p=mc.localToGlobal(p); trace(p); trace(evtObj.stageX,evtObj.stageY);}对照可以分发现转换后的坐标就是舞台坐标。问:主时间轴,也就是文档类的坐标 跟舞台有什么不同?答:文档类与舞台是显示列表中的两个顶级容器,舞台是文档类对象的容器。文档类的坐标相对于文档类对象,舞台坐标相对于舞台。当文档类 对象和舞台原始坐标点不同时,区别就显现了。证明:在舞台左上角画个方块,坐标为(0,0)。在第一帧输入如下代码:x=10;y=10;可以看到方块位 置变了。这说明文档类对象不必非要跟舞台原坐标点重合。正式因为平时都是重合的,所以看不见差别。问:文档类大小也跟舞台大小不同吗?答:是的。舞台是可 以缩放的,当缩放舞台时可以不缩放文档对象,即使缩放文档对象也不一定拉伸到整个舞台。所以当然是不同的。证明:如图:问:舞台有哪些缩放方式:答:使用 Stage的scaleMode来控制缩放模式。scaleMode使用StageScaleMode类的静态常量表 示:StageScaleMode.NO_SCALEswf文件不随播放器窗口改变。会自动居中。StageScaleMode.SHOW_ALL以缩放 方式缩放swf文件,维持宽高比。StageScaleMode:NO_BORDER以裁剪方式缩放swf文件,维持宽高比。 StageScaleMode.EXACT_FIT拉伸swf文件,改变宽高比。注意:在调试模式下NO_SCALE是默认值。而在发布后 SHOW_ALL是默认值。附:由于可以选择缩放,我们在网页中可以使用两种方式让swf在网页中居中:1.使用缩放模式。使用网页代码让控件居中。2. 控件随着网页的大小而改变。采用noscale模式使内容居中。问:缩放看起来非常适合播放动画。但当制作应用程序时不必缩放,能否让swf不要自动居 中?答:可以。在NO_SCALE模式下可以使用align属性来确定对齐方式,align使用StageAlign类的静态常量表 示:StageAlign.TOP: 顶对齐StageAlign.BOTTOM: 底对齐StageAlign.LEFT: 左对齐StageAlign.RIGHT: 右对齐StageAlign.TOP_LEFT: 左上对齐StageAlign.TOP_RIGHT: 右上对齐StageAlign.BOTTOM_LEFT: 左下对齐。StageAlign.BOTTOM_RIGHT: 右下对齐。我们可以在播放器中导入多个swf采取不同的对齐方式。组合成一个应用程序。问:舞台的大小如何访问?答:舞台大小使用stageWidth和 stageHeight访问。不管采用哪种缩放模式,都是播放器或者控件的实际大小。问:鼠标事件中的stageX和stageY也是这样吗?答:不是, 当使用除NO_SCALE之外的模式缩放后,swf文件也被缩放了,舞台内部DPI发生了变化,stageX与stageY是新DPI下的舞台坐标。问: 舞台也继承DisplayObject,那么舞台的x,y和width,height又指的什么?答:舞台的x,y,width,height都是只读 的。由于播放器不允许我们改变在系统中的位置,所以x,y都为0。width和height属性也不是改变播放器的大小,而指向文档类的width和 height。证明:画一个方块,在第一帧输入如下代码:复制内容到剪贴板 代码:trace(root.width==stage.width,root.height==stage.height);//结果为 true,true。问:文档类的x,y是文档类在舞台上的坐标,那么文档类的width和height是文档类的宽和高吗?怎么root.width和 root.height结果与属性面板中设置的不同啊。答:root.width和root.height确实不是文档类的大小。属性面板中才是文档类的 大小。问:那么文档类的大小用什么来访问呢?答:文档类的大小使用文档类的loaderInfo属性访问,是loaderInfo.width和 loaderInfo.height。问:为什么我访问时提示:Error: Error #2099: 正在加载的对象因尚未完全加载而无法提供此信息?答:即使是文档类的loaderInfo属性也需要主swf文件加载完毕后才能访问,因此还是得在事件中 访问。证明:在第一帧输入如下代码:复制内容到剪贴板 代码:loaderInfo.addEventListener(Event.COMPLETE,mainSwfComplete);function mainSwfComplete(evtObj:Event):void{ trace(loaderInfo.width,loaderInfo.height);}看,现在可以访问了。不光是width和height,还有其 它属性也需要这样访问。所以最好在complete或init中访问loaderInfo的属性。问:那么文档类的width和height究竟表示什 么?答:问的好。文档类的width和height表示的是可视内容的大小。证明,在舞台上画两条线,如图:在帧上输 入:trace(width,height)。发现大小是这两条线确定的矩形范围。附:假设改变文档对象的背景色,也是改变可视内容范围的背景色。在帧上 添加代码:复制内容到剪贴板 代码:opaqueBackground=0xFF0000;问:那么改变文档类的width和height是改变了可视区域的大小吗?答:不完全是。 flash以播放器原点为坐标原点采取按比例延伸方式,也可以称作放射。原理如图:这张图显示了采用放射方式使宽度扩展两倍。上面一个方块中的每一个像素 的横坐标都由原位置延伸到2倍距离。得到的结果是宽度延伸了2倍,横坐标也成了原来的两倍。对于高度也是这样。改变宽度为原来的两倍等价于设置 scaleX=2。实际应用中由于同时改变了大小和坐标使得我们很不习惯。所以一般我们不改变文档类对象的大小。问:当使用了 opaqueBackgoundg改变主时间轴的背景色后,能响应鼠标点击事件吗?答:不能。不但背景色不能响应点击事件,就算画一个矢量图形,导入一张 位图,文档类对象也不能捕获鼠标事件。这是因为这些图形不是InteractiveObject的子类,不支持鼠标事件,不能成为事件目标,而系统也不选 择文档类对象作为事件目标。使得系统直接选择舞台为事件目标。证明:画几个矢量,再载入一副位图,在帧上添加代码:复制内容到剪贴板 代 码:addEventListener(MouseEvent.CLICK,clickHandle);stage.addEventListener(MouseEvent.CLICK,clickHandle);function clickHandle(evtObj:MouseEvent):void{ trace(evtObj.currentTarget);}dispatchEvent(new MouseEvent(MouseEvent.CLICK));点击矢量和位图,输出的只有stage而没有主时间轴。问:那么文档类对鼠标一点作用都不 起了吗?答:否,虽然系统不选择文档类对象作为事件目标,但文档类关于鼠标交互属性还是有作用的。这个属性就是mouseChildren。使用这个属性 能够禁用swf文件中的所有鼠标事件。证明:在舞台上分别放个按钮,输入文本,带超级链接的文本。在帧上输入:mouseChildren=false。 发现按钮没了反应,文本不能输入,超级链接也没用了。问:我看stage也有这个属性。把stage的mouseChildren设置为false岂不可 以禁止包括swf文件内的所有鼠标事件?答:确实如此。问:stage虽然是继承而来的,但很多成员都被禁用了。因为要禁止对播放器的修改,有些成员对播 放器也无意义,那么哪些成员被Stage类保留下来了呢?哪些又是新添加的成员呢?能详细说明吗?答:保留的方法:1.EventDispatcher的 所有方法,用于为舞台添加特属于舞台的事件。2.保留的容器方法。 addChildaddChildAtremoveChildAtsetChildIndexswapChildrenAtgetObjectUnderPoint3.Stage.invalidate() 方法:触发显示对象的render事件用于延迟技术。事件:由于处于显示列表的顶级,Stage的事件都不冒泡,也没有默认调用方法。事件对象是 Event。属性target值为Stage对象。fullScreen类型为flash.events.Event.FULL_SCREEN。进行全屏 切换时触发。事件对象可使用fullScreen属性,全屏为true。resize:类型为flash.events.Event.RESIZE。.当 scaleMode设置为NO_SCALE时改变swf文件尺寸时调用。用于作布局。mouseLeave:类型为 flash.events.Event.MOUSE_LEAVE。当鼠标离开播放器窗口时触发。属性:保留属性:numChildren:舞台中swf文 件的个数。mouseChildren:忽略所有swf文件的鼠标事件。下面是操作播放器的属性:focus:指定舞台中具有键盘焦点的对象。由于只能有 一个对象具有焦点。所以由舞台来处理焦点是合适的。frameRate:设置舞台的帧速。默认为属性面板中指定的帧速。stageFocusRect:是 否显示焦点矩形。一般用来调试。scaleMode:StageScale.Mode:StageScaleMode.NO_SCALEswf 文件不随播放器窗口改变。会自动居中。StageScaleMode.SHOW_ALL以缩放方式缩放swf文件,维持宽高比。 StageScaleMode:NO_BORDER以裁剪方式缩放swf文件,维持宽高比。StageScaleMode.EXACT_FIT拉伸swf 文件,改变宽高比。stageWidth和stageHeight:舞台的宽和高。只读属性。width和height:可视区域的宽高。 displayState:as3现在拥有全新的全屏概念。再不是原来的缩放方式而是全新的硬件支持。速度大幅度提高。并且可以在网页上使用全屏。但全屏 设置只被设计用来看电影,输入文本和键盘事件变得无效。displayStage使用StageDisplayStage.NORMAL和 StageDisplayState.FULL_SCREEN表示全屏值。使用全屏还要求flash控件属性allowFullScreen设为 true。align:使用StageAlign类的静态属性确定对齐方式:StageAlign.TOP: 顶对齐StageAlign.BOTTOM 底对齐StageAlign.LEFT 左对齐StageAlign.RIGHT 右对齐StageAlign.TOP_LEFT 左上对齐StageAlign.TOP_RIGHT 右上对齐StageAlign.BOTTOM_LEFT 左下对齐。StageAlign.BOTTOM_RIGHT 右下对齐。问:我对舞台的invalidate方法不太了解,延迟技术指什么?所谓延迟就是当需要频繁调用一段重负荷代码时,为了节约cpu资源,把这段 代码推迟到下一帧执行。需要使用这段代码的不直接通过调用而是使用一个方法声明请求延迟渲染,这如同把一个公共变量设置为true,当系统发现变量的改变 后就重新渲染舞台。stage的invalidate方法就是声明延迟渲染的方法。问:我看上面舞台保留的方法虽然没有DisplayObject的多, 但对于添加对象已经足够,一般在什么情况下需要对舞台添加对象呢?答:舞台可导入多个外部swf文件在同一个播放器中播放。但更有用的是从库中创建鼠标指 针,对话框等显示对象。它们被放置到最上层,且不必跟文档类搅和在一起。这使得文档类的设计跟鼠标、回话窗口分开。这些对话框等组件更容易作为公共组件框 架跟其它程序迅速匹配。问:现在对舞台与主时间轴的概念已经很清晰了。这两个对象被系统创建。我们只能通过DisplayObject中提供的stage 和root属性分别引用它们,可以随时访问是吧?答:不能随时访问,只有添加到显示列表中的对象才能引用它们。因为它们作为顶级显示容器,如果在显示列表 外也可以访问,那被删除的显示对象在后台依然可以影响前台显示,这样会导致混乱。问:主时间轴和stage也有这两个属性,它们指什么?答:主时间轴的 root指主时间轴,主时间轴的stage指舞台,舞台的root和stage都指舞台。问:还有什么限制吗?访问舞台还与安全模型有关。不受信任的域是 无法访问舞台的,因为它们获取了舞台后可以利用扫描方式盗取用户信息。问:原来访问舞台有这么多限制啊,那访问主时间轴应该没有什么限制吧?答:没有。 MovieClip的成员都可以使用。你甚至可以把buttonMode设置成true。让整个主时间轴成为一个大按钮。问:那我也可以使用滤镜渲染整个 swf文件了吧,使用flash不能这样呢。答:确实。但不要滥用,使用滤镜渲染主时间轴会作用于所有显示对象,也会渲染所有帧。这会消耗很多cpu资 源。证明:在舞台上绘制各种图形,文字,图片。在第一帧输入如下代码:复制内容到剪贴板 代码:var dropShadowropShadowFilter = new DropShadowFilter();var filtersArray:Array = new Array(dropShadow);this.filters = filtersArray;可以看到所有对象都被添加了阴影。[/color]



发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

(Spamcheck Enabled)