[英]ActionScript / Flash - Loading External, Programatically Created SWF?
i've never had to do any cross scripting until now and i'm running into a (probably really stupid) error right at the start. 到目前为止我从来没有做过任何交叉脚本,而且我在开始时遇到了(可能是非常愚蠢的)错误。
External SWF: i've created a new ActionScript 3.0 project in Flash Professional CS5. 外部SWF:我在Flash Professional CS5中创建了一个新的ActionScript 3.0项目。 on the first frame i've added the following script: 在第一帧我添加了以下脚本:
//Square.fla frame script
import flash.display.Shape;
import flash.events.Event;
var s:Shape = new Shape();
s.graphics.beginFill(0x0000FF, 1.0);
s.graphics.drawRect(-100, -100, 200, 200);
s.graphics.endFill();
s.x = stage.stageWidth / 2;
s.y = stage.stageHeight / 2;
addChild(s);
addEventListener(Event.ENTER_FRAME, enterFrameEventHandler);
function enterFrameEventHandler(evt:Event):void
{
s.rotation += 2;
}
save, compile, done. 保存,编译,完成。 this works fine as a stand alone swf, which simply displays a rotating blue square at center stage. 这可以作为一个独立的swf工作,它只是在中心舞台上显示一个旋转的蓝色方块。
Main SWF: i've created a new ActionScript 3.0 file in Flash Professional CS5, which has a document class called CrossScriptTest : 主要SWF:我在Flash Professional CS5中创建了一个新的ActionScript 3.0文件,该文件有一个名为CrossScriptTest的文档类:
//CrossScriptTest.as
package
{
//Imports
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.display.Sprite
import flash.display.Loader;
import flash.events.IOErrorEvent;
import flash.net.URLRequest;
import flash.events.Event;
//Class
[SWF(width = "1000", height = "500", backgroundColor = "0x444444")]
public class CrossScriptTest extends Sprite
{
//Constants
private static const SQUARE_SWF_URL:String = "Square.swf";
//Variables
private var SWFLoader:Loader;
//Constructor
public function CrossScriptTest()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.frameRate = 60;
init();
}
//Initialize
private function init():void
{
SWFLoader = new Loader();
SWFLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, IOErrorEventHandler);
SWFLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompleteEventHandler);
SWFLoader.load(new URLRequest(SQUARE_SWF_URL));
}
//IOError Event Handler
private function IOErrorEventHandler(evt:IOErrorEvent):void
{
trace(evt);
}
//Loader Complete Event Handler
private function loaderCompleteEventHandler(evt:Event):void
{
evt.currentTarget.removeEventListener(IOErrorEvent.IO_ERROR, IOErrorEventHandler);
evt.currentTarget.removeEventListener(Event.COMPLETE, loaderCompleteEventHandler);
var squareSWF:Sprite = Sprite(evt.currentTarget.content);
addChild(squareSWF);
}
}
}
Error: i receive the following error: 错误:我收到以下错误:
TypeError: Error #1009: Cannot access a property or method of a null object reference. TypeError:错误#1009:无法访问空对象引用的属性或方法。 at Square_fla::MainTimeline/frame1() 在Square_fla :: MainTimeline / frame1()
perhaps i'm misunderstanding the nature of cross scripting or loading external swf files, but i can only seem to make this work if i've manually drawn display objects on the stage and not if the external swf's display objects are generated by code. 也许我误解了交叉脚本或加载外部swf文件的本质,但是如果我在舞台上手动绘制显示对象而不是外部swf的显示对象是由代码生成的话,我似乎只能使这个工作。
is it not possible to load external swfs that are programatically created and add them to the display list of a main swf? 是不是可以加载以编程方式创建的外部swfs并将它们添加到主swf的显示列表中?
the solution is always so obvious after the fact. 事后,解决方案总是如此明显。 the solution is, of course, to assign an Event.ADDED_TO_STAGE
event listener in the constructor or initialize method of the external swf's document class. 当然,解决方案是在外部swf文档类的构造函数或初始化方法中分配Event.ADDED_TO_STAGE
事件侦听器。
in my defense this was overlooked since it is not required nor common when creating a standard (internal?) document class. 在我的辩护中,这被忽略了,因为在创建标准(内部?)文档类时不需要也不常见。
Main SWF's Document Class: 主SWF的文件类别:
package
{
//Imports
import flash.display.StageScaleMode;
import flash.display.StageAlign;
import flash.display.Sprite
import flash.display.Loader;
import flash.events.IOErrorEvent;
import flash.net.URLRequest;
import flash.events.Event;
//Class
[SWF(width = "1000", height = "500", backgroundColor = "0x444444")]
public class CrossScriptTest extends Sprite
{
//Constants
private static const SQUARE_SWF_URL:String = "Square.swf";
//Variables
private var swfLoader:Loader;
//Constructor
public function CrossScriptTest()
{
stage.scaleMode = StageScaleMode.NO_SCALE;
stage.align = StageAlign.TOP_LEFT;
stage.frameRate = 60;
init();
}
//Initialize
private function init():void
{
swfLoader = new Loader();
swfLoader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, IOErrorEventHandler);
swfLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaderCompleteEventHandler);
swfLoader.load(new URLRequest(SQUARE_SWF_URL));
}
//IOError Event Handler
private function IOErrorEventHandler(evt:IOErrorEvent):void
{
trace(evt);
}
//Loader Complete Event Handler
private function loaderCompleteEventHandler(evt:Event):void
{
evt.currentTarget.removeEventListener(IOErrorEvent.IO_ERROR, IOErrorEventHandler);
evt.currentTarget.removeEventListener(Event.COMPLETE, loaderCompleteEventHandler);
addChild(evt.currentTarget.content);
}
}
}
External SWF's Document Class: 外部SWF的文件类别:
package
{
//Imports
import flash.display.Sprite;
import flash.display.Shape;
import flash.events.Event;
//Class
public class Square extends Sprite
{
//Constructor
public function Square()
{
init();
}
//Initialize
private function init():void
{
addEventListener(Event.ADDED_TO_STAGE, addedToStageEventHandler);
}
//Added To Stage Event Handler
private function addedToStageEventHandler(evt:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, addedToStageEventHandler);
var s:Shape = new Shape();
s.graphics.beginFill(0x0000FF, 1.0);
s.graphics.drawRect(-100, -100, 200, 200);
s.graphics.endFill();
s.x = stage.stageWidth / 2;
s.y = stage.stageHeight / 2;
addChild(s);
s.addEventListener(Event.ENTER_FRAME, enterFrameEventHandler);
}
//Enter Frame Event Handler
function enterFrameEventHandler(evt:Event):void
{
Shape(evt.currentTarget).rotation += 2;
}
}
}
Yes it can be done, but the way you are doing it doesn't seem right. 是的,它可以做到,但你这样做的方式似乎并不正确。 You could simply use a loader: 你可以简单地使用一个加载器:
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener("complete", loader_complete);
loader.load(new URLRequest("yourfile.swf"));
function loader_complete(event:*):void {
var loadedObject:* = event.target;
// Access the properties of the loaded SWF here
}
Edit: 编辑:
In general, try not to use frame scripts, especially when loading SWFs within SWFs, because the way they work is not always obvious. 通常,尽量不要使用框架脚本,尤其是在SWF中加载SWF时,因为它们的工作方式并不总是很明显。 For instance, I don't know what the root is in your script - is it the root of your SWF or that of the parent SWF? 例如,我不知道你的脚本中的root是什么 - 它是你的SWF的根还是父SWF的根? (I don't know because, to avoid this kind of problem, I never use frame scripts). (我不知道因为,为了避免这种问题,我从不使用框架脚本)。 To avoid that, you can simply use a document class and put all your code in there. 为避免这种情况,您只需使用文档类并将所有代码放在那里。
Maybe try something like that and see if it works: 也许尝试类似的东西,看看它是否有效:
package some.unique.path {
import flash.display.MovieClip;
import flash.display.Shape;
import flash.events.Event;
public class YourClass extends MovieClip {
public function YourClass():void {
var s:Shape = new Shape();
s.graphics.beginFill(0x0000FF, 1.0);
s.graphics.drawRect(-100, -100, 200, 200);
s.graphics.endFill();
s.x = stage.stageWidth / 2;
s.y = stage.stageHeight / 2;
addChild(s);
addEventListener(Event.ENTER_FRAME, enterFrameEventHandler);
}
function enterFrameEventHandler(evt:Event):void
{
s.rotation += 2;
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.