[as3][翻译]使用display对象[II]
[摘要]本文主要包括以下内容:贯穿display链、设置舞台属性
一、贯穿display链
正如你前面所看到的,display链是一个树形结构。位于最顶端的是Stage,它可以包含多个display对象。这些display对象中,如果它们本身是display对象容器的话,那么它们也可以包含其他的display对象或者display对象容器。

DisplayObjectContainer类中有用于贯穿display链的方法和属性。比如,考虑下面的代码,它把两个display对象:titile和pict,添加到容器对象中(DisplayObjectContainer类的子类Sprite类的一个实例):
- var container:Sprite = new Sprite();
- var title:TextField = new TextField();
- title.text = "Hello";
- var pict:Loader = new Loader();
- var url:URLRequest = new URLRequest("banana.jpg");
- pict.load(url);
- pict.name = "banana loader";
- container.addChild(title);
- container.addChild(pict);
getChildAt()方法返回display链中指定索引位置处的子对象。
- trace(container.getChildAt(0) is TextField); // true
访问子对象的另外一种方法是利用子对象的名字。每个display对象都有一个名字,如果你没有明确的赋予它名字,FlashPlayer会给它一个默认的名字,就像”instance1″。比如,下面的代码展示了如何利用getChildByName()方法访问一个叫”banana loader”的display对象:
- trace(container.getChildByName("banana loader") is Loader); // true
getChildByName()方法比getChildAt()方法效率低。
diplay对象容器中又可以包含其他display对象容器,因此你可以把整个display链当作树来遍历。比如,在前面的代码中,一旦pict Loader对象的load操作完成了,pict对象就有了个bitmap子display对象。要访问这个bitmap子对象,你可以这样写:
- pict.getChildAt(0)
也可以这样写
- container.getChildAt(0).getChildAt(0)
因为
- container.getChildAt(0) == pict
下面的代码输出了一个display对象容器中的display链:
- function traceDisplayList(container:DisplayObjectContainer, indentString:String = ""):void
- {
- var child:DisplayObject;
- for (var i:uint=0; i < container.numChildren; i++)
- {
- child = container.getChildAt(i);
- trace(indentString, child, child.name);
- if (container.getChildAt(i) is DisplayObjectContainer)
- {
- traceDisplayList(DisplayObjectContainer(child), indentString + " ")
- }
- }
- }
二、设置Stage属性
Stage类覆盖了很多DisplayObject类的属性和方法。如果你调用这些被覆盖的属性和方法,FlashPlayer抛出一个异常。比如,Stage对象没有x、y属性,因为在应用程序中,它被当作主容器,位置是固定的。而x和y属性反映的是display对象在它的容器中的相对位置,但是Stage不包含在其他任何display对象容器中。
注意:
对于那些和第一个SWF文件不在相同的安全沙箱中的display对象来说,Stage类的一些属性和方法是不可用的。更多信息查看Stage安全。
1、设置帧速
Stage类的framerate属性用来设置加载到应用程序中的所有SWF文件的帧速。
2、控制Stage缩放
当FlashPlayer屏幕改变大小时,Flash Player自动调整Stage的内容。Stage类的scaleMode属性决定了Stage的内容如何调整。该属性可以设置成不同的、定义在flash.display.StageScaleMode类中的常量值。
对于StageScaleMode.EXACT_FIT、StageScaleMode.SHOW_ALL和 StageScaleMode.NO_BORDER这3种scaleMode值,FlashPlayer会把Stage上的所有内容填充到边界内。这3者的不同在于它们以什么样的方式完成缩放:
StageScaleMode.EXACT_FIT按比例缩放SWF。
StageScaleMode.SHOW_ALL确定是否显示边,比如当一个宽屏影片放到标准电视上播放时会显示黑边。
StageScaleMode.NO_BORDER确定内容能否部分裁剪。
对应的,如果scaleMode被设置成StageScaleMode.NO_SCALE,当用户调整FlashPlayer窗口大小时,舞台内容将保持它们的大小。只有在这种缩放模式下,Stage类的width和height属性才能用来确定Flash Player窗口的真实像素尺度。(在其他缩放模式下,stageWidth和stageHeight属性总是反映SWF的原始宽度和高度)。另外,当scaleMode被设置成StageScaleMode.NO_SCALE并且SWF被改变了尺寸,Stage类的resize事件会被触发,你可以监听这个事件以做适当的调整。
因此,把scaleMode设置成StageScaleMode.NO_SCALE可以是你更好的控制舞台内容的调整以适应窗口的大小改变。比如,在一个SWF文件中有一个video和一个控制条,在舞台大小改变时,你可能只想让video窗口随着舞台改变大小而让控制条保持原来大小。下面的代码演示了这个效果:
- // videoScreen is a display object (e.g. a Video instance) containing a
- // video; it is positioned at the top-left corner of the Stage, and
- // it should resize when the SWF resizes.
- // controlBar is a display object (e.g. a Sprite) containing several
- // buttons; it should stay positioned at the bottom-left corner of the
- // Stage (below videoScreen) and it should not resize when the SWF
- // resizes.
- import flash.display.Stage;
- import flash.display.StageAlign;
- import flash.display.StageScaleMode;
- import flash.events.Event;
- var swfStage:Stage = videoScreen.stage;
- swfStage.scaleMode = StageScaleMode.NO_SCALE;
- swfStage.align = StageAlign.TOP_LEFT;
- function resizeDisplay(event:Event):void
- {
- var swfWidth:int = swfStage.stageWidth;
- var swfHeight:int = swfStage.stageHeight;
- // Resize the video window.
- var newVideoHeight:Number = swfHeight - controlBar.height;
- videoScreen.height = newVideoHeight;
- videoScreen.scaleX = videoScreen.scaleY;
- // Reposition the control bar.
- controlBar.y = newVideoHeight;
- }
- swfStage.addEventListener(Event.RESIZE, resizeDisplay);
3、使用全屏模式
全屏模式允许你把一个SWF填充用户的整个显示器,没有边、没有菜单条等等。Stage类的displayState属性用来控制全屏模式开关。displayState属性可以被设置成flash.display.StageDisplayState类中几个常量之一。如果想打开全屏模式,就把displayState设置成StageDisplayState.FULL_SCREEN:
- // mySprite is a Sprite instance, already added to the display list
- mySprite.stage.displayState = StageDisplayState.FULL_SCREEN;
退出全屏模式就把displayState设置成StageDisplayState.NORMAL:
- mySprite.stage.displayState = StageDisplayState.NORMAL;
另外,用户可以通过切换窗口或者使用下面的几个组合键退出全屏模式:Esc键(适用于所有平台)、Ctrl-W(Windows)、Command-W(Mac)或者Alt-F4(Windows)。
在全屏模式下,缩放行为跟在普通模式下是一致的;缩放是由Stage类的scaleMode属性控制的。同样的,如果scaleMode被设置成了StageScaleMode.NO_SCALE,Stage的stageWidth和stageHeight属性都是反映SWF占用的屏幕大小(全屏模式下,就是整个屏幕)。
你可以侦听Stage类的fullScreen事件以便在全屏模式打开或关闭时作出反映。
比如,你可能想在进入或退出全屏模式时从屏幕上添加或移除对象,如下代码所示:
- import flash.events.FullScreenEvent;
- function fullScreenRedraw(event:FullScreenEvent):void
- {
- if (event.fullScreen)
- {
- // Remove input text fields.
- // Add a button that closes full-screen mode.
- }
- else
- {
- // Re-add input text fields.
- // Remove the button that closes full-screen mode.
- }
- }
- mySprite.stage.addEventListener(FullScreenEvent.FULL_SCREEN, fullScreenRedraw);
在这段代码中,fullScreen事件对象是flash.events.FullScreenEvent类的实例,它包含一个fullScreen属性用来指示full-fullscreen模式是打开还是关闭。
在ActionScript中使用全屏模式时,需要注意下面几点:
- 只有响应鼠标点击(包括右击)或者按键时才能用ActionScript初始化全屏模式
- 如果用户有多个监视器,SWF只会填充其中的一个监视器。FlashPlayer先确定哪个监视器中包含的SWF的内容多,然后在那个监视器设置全屏模式。
- 对于内嵌到HTML页面中的SWF文件,嵌入FlashPlayer的HTML代码中必须包含一个param标签,并嵌入名为allowFullScreen值为true的属性,想下面这样:
HTML Code:
- <object>
- ...
- <param name="allowFullScreen" value="true" />
- <embed ... allowfullscreen="true" />
- </object>
如果你使用JavaScript生成SWF嵌入标签,你必须改变JavaScript以添加allowFullScreen param标签和属性。比如,如果你的HTML页面使用AC_FL_RunContent()函数(Flex Builder和Flash生成的HTML页面都使用它),你必须像下面这样添加allowFullScreen参数:
JavaScript Code:- AC_FL_RunContent(
- ...
- 'allowFullScreen','true',
- ...
- ); //end AC code
这不适用于运行在单独FlashPlayer播放器中的SWF文件。
- 全屏模式下禁止所有键盘相关的ActionScript,比如按键事件和文本框实例的文本。控制关闭全屏模式的快捷键除外。
另外还有一些安全相关的限制,如果想了解,请查看安全沙箱。

Leave a Reply