我有一个完整的浏览器窗口AS3 Flash CS4父swf,它加载第三方子swf,高度/宽度较小并适当定位(即居中)。无论我尝试使用什么加载技术,我都会遇到儿童swf中的放置和方向问题,这会导致儿童失望。
在一个示例情况下,孩子将加载辅助显示对象(可能是动画片段),但尝试将其附加到舞台上。如果我允许它在加载期间通过SecurityDomain访问舞台,它会将其定位在父swf的0,0而不是0f的子swf(已经适当地位置/居中)。
另一方面,孩子在负荷期间的定位是合适的,但是孩子在X,Y位置的参考阶段内的位置被孩子swf居中的量(即孩子的装载者)所抵消。 swf是居中的,它的X是200,而子swf中的一个对象应该是100,50,实际上是300,50)。
普通线程似乎是子swfs,无论是否允许访问舞台,都使用父级的stage或player属性而不是加载器中的属性。
如何隔离儿童swf,使其仅使用自己的子环境进行定位和定位而不是父母的?
我尝试过内置的Loader和UILoader,Greensock的SWFLoader,Flex的SWFLoader,甚至还可以通过TextField中的文本加载它。
似乎AIR的HTMLLoader可以工作(因为HTMLLoader中的SWF对象显然使用他们自己的舞台对象),但是这个应用程序已在浏览器中可用。
理想情况下,我仍然希望能够与孩子沟通,但此时确保孩子顺利跑步更为重要。
这似乎是一种常见的做法,但是左右碰到阻塞问题让我觉得我正在以错误的方式接近这个问题。
我最后的办法是用JS框架替换父swf,但前提是绝对必要。
对此流程任何部分的解决方案的建议表示赞赏。
答案 0 :(得分:2)
希望没有反对我自己的问题的“规则”...
正如评论中提到的那样,似乎没有办法限制加载的swf访问阶段变量,例如定位/方向(mouseX& mouseY)。最好的解决方案是限制对舞台的访问,以便加载的swfs无法添加到舞台上。这是通过包含LoaderContext对象和Loader.load调用来完成的,该调用定义了一个单独的ApplicationDomain。
var url:URLRequest = new URLRequest(/*...SWF URL...*/);
var context:LoaderContext = new LoaderContext(false,new ApplicationDomain());
var ldr:Loader = new Loader();
ldr.load(url,context);
这将在加载的swf中保持一个单独的根。
如果Loader对象远离父/主swf中的(0,0),则可能需要与加载的swf作者协调以包装stage.mouseX& stage.mouseY与DisplayObject.globalToLocal反映未知偏移量(来自加载的swf内)。
var localMousePt:Point = this.globalToLocal(new Point(stage.mouseX,stage.mouseY));
它很糟糕,但从安全角度来看它是有道理的。我发现Flash开发人员通常不会考虑可能加载SWF的上下文,因此认为使用stage(而不是root)没有任何问题。最佳做法应该是始终使用root来添加和定位对象,因为您永远不知道根可能放在显示列表中的位置以及它们与舞台之间可能有多少父。
答案 1 :(得分:0)
这是一个丑陋的黑客攻击,但你总是可以为舞台添加一个Event.ADDED
的监听器,检查需要调整的显示对象(当然,如果它们被命名,这种方法效果最好,但是您可以使用其他标准),然后手动更改其坐标。
private function onAdded( ev:Event ) : void {
if ( ev.target.name == "whatever")
modifyCoordinates( ev.target as DisplayObject );
}
private function modifyCoordinates( target:DisplayObject ) : void {
// displace to match parent clip
}
//...
stage.addEventListener( Event.ADDED, onAdded );
如果无法区分由加载的剪辑生成的显示对象,则可以自行过滤掉您正在添加到舞台的那些:如果只有应用程序的根MovieClip在舞台上,然后是一切作为孩子添加,它应该不是一个问题。
我还会尝试联系作者,或者反编译第三方文件 - 如果其中任何一个有效,您至少可以了解事情是如何完成的,因此您无需猜测应用更改的位置。或许您甚至可以修改并重新编译它们。