我已经四处寻找并发现了类似的问题,但答案(接受的,甚至!)要么是hacky,要么与实际问题没什么关系,要么只是在我尝试时不工作它们。
我正在尝试从Flash CS3中的Actionscript 3中的文档类引用当前帧中舞台上的对象。在这个例子中,我试图获得一个带有实例名称“question_txt”的动态文本字段,但是还有一些按钮和其他东西,我需要把它们放到事件监听器上等等。
我在发布设置中选中了“自动声明舞台实例”,因此引用应该在那里 - 事实上,如果我尝试在类中声明它们,我会收到与名称冲突的错误 - 但是当我尝试引用这些对象时(我现在尝试过几种方式!)我总是得到空。
package {
import flash.display.MovieClip;
import flash.display.SimpleButton;
import flash.display.Stage;
import flash.text.TextField;
import flash.net.navigateToURL;
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.events.Event;
public class DecisionTree extends MovieClip {
private var tree_xml:XML;
private var current_node:String;
public function DecisionTree():void {
trace("Constructor");
tree_xml = new XML();
tree_xml.ignoreWhitepace = true;
loader = new URLLoader();
loader.addEventListener(Event.COMPLETE,
function(e:Event):void {
tree_xml = new XML(e.target.data);
goToNode('main');
});
loader.load(new URLRequest("decision_tree.xml"));
}
private function goToNode(name:String):void {
trace("goToNode " + name);
current_node = name;
node_xml = tree_xml.node.(attribute('name') == name)[0];
node_frame = parseInt(node_xml.attribute('frame'));
node_question = node_xml.question.text();
gotoAndPlay(node_frame); // will goto frame 35 where the stuff is
// ARRRRRGH EVERYTHING'S COMING UP NULL!!!
// TypeError: Error #1009: Cannot access a property or method of a null object reference.
question_txt.text = node_question;
//q = question_txt as TextField;
//q.text = node_question;
//qtxt = stage.getChildByName('question_txt') as TextField;
//qtxt.text = node_question;
}
}
}
答案 0 :(得分:4)
简单的事实是你不能依赖它来工作:
gotoAndStop(2);
thing_on_frame_2.foo(); // no guarantee this will work.
有可能你看到的其他答案看起来很hacky,因为是但是没有更好的解决方法。在你调用gotoAndFoo()之后,播放头实际上不会保证在第2帧,并且如果它不能保证放在那里的对象将在你被实例化时被实例化试图访问它们。这在AS2中过去是合法且有效的,但在AS3中它不再是。
通常,您可以执行以下操作之一来解决此问题:
可选地,如果您只关心监听按钮点击,那么不是直接将监听器添加到按钮,而是可以将监听器添加到按钮的最顶层容器,然后检查调度按钮的实例名称。在决定如何处理该事件之前的事件。我喜欢这种方法,因为它更容易跟踪什么是听众而不是听众。
Hacky与否,这就是它的完成方式。
编辑更多信息:
我知道如果您追踪当前帧,则返回的数字将是您刚刚指示播放头移动到的数字。问题是,无法保证fla中舞台上的对象在您在代码中请求它们时将会或不会被实例化。这就是你使用framescript的原因,因为保证对象在那时被实例化。
关于是否有可以听取的事件的问题,保证在施工后发送,答案是“也许。您定位的是什么版本的Flash Player?”最常见的帧事件是ENTER_FRAME,因为它是从一开始就支持的帧事件。随着时间的推移,我们已经获得了EXIT_FRAME,FRAME_CONSTRUCTED等所有在不同时间发送的东西。 FRAME_CONSTRUCTED是你想要监听的那个,但是为你需要它的一个瞬间添加一个FRAME_CONSTRUCTED监听器然后立即将它删除它并不是很麻烦或实际,当然如果你被强制则不会编译在CS3中工作(并将使FP9崩溃)。
我支持使用addFrameScript作为执行此操作的最佳方式。它很长一段时间没有记录(事实上它可能仍然是),但它是闪存编译器在内部将您在时间轴上写入的脚本附加到影片剪辑的“帧”的方式。
答案 1 :(得分:0)
U无法访问除脚本/代码本身之外的其他帧上的元素。在这种情况下,主类位于第一帧。所以基本上最好的指南是你将所有元素放在1. frame上,然后在需要时隐藏/显示它们。
但是如果你出于任何原因不能这样做,我的建议是,在任何框架上,有元素在主文档中设置一些变量,指向该元素。
例如:
在第2帧上。你有“question_txt”元素,并在该帧上放置代码:
MovieClip(root).question_txt = question_txt
并在主类中输入变量question_txt:TextField:
public var question_txt:TextField;
依此类推,适用于每一个框架和每个元素。 U也可以将它们存储在数组或字典中或者类似的东西中,只要你可以更改引用
答案 2 :(得分:0)
我倾向于避免使用文档类,并在舞台上使用基类放置一个空符号,然后将该类视为文档类。
答案 3 :(得分:0)
一个对象需要存在于舞台上一个整帧,然后才能通过代码与它进行任何有意义的交互。这总是如此。如有疑问,请等待一帧。