Access of Undefined Property "loader" - actionscript-3

So I'm working on a project in flash, and recently decided that I wanted to switch my test file to become the main class inside my project. The file is called ColorClass.as, and the associated .fla file is ColorClass.fla. They are located in the same directory, and the Document class of ColorClass.fla is ColorClass. I am using a loader inside ColorClass.as to load an external SWF as follows:
public var loader:Loader = new Loader();
addChild(loader); //adding loader
loader.load(new URLRequest("../Resource/flash/WheelClasses.swf"));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,wheelsLoaded);
I am trying to create a test file, color_Test.as (and an associated color_Test.fla) that loads ColorClass.swf and gets the class definition to be used in the test file.
However, when I try and compile ColorClass.as/.fla and create a .swf file, I am receiving multiple instances of
Access of undefined property loader.
and
Call to a possibly undefined method addChild.
These errors are occurring completely independent of color_Test. Am I going about something the wrong way here? I'm just trying to compile ColorClass.as/.fla, which I could do so before trying to change it to become another class.

In an AS3 class, all functional code needs to be contained in a function.
So, aside from the first line (which is a variable declaration), the rest are just floating in the class not wrapped in a function:
public var loader:Loader = new Loader(); //THIS LINE IS FINE
//THESE THREE LINES NEED TO LIVE IN A FUNCTION
addChild(loader);
loader.load(new URLRequest("../Resource/flash/WheelClasses.swf"));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,wheelsLoaded);
If you want the code above to execute right away, place it in the constructor function (the function whose name matches the name of the class).
public function ColorClass {
addChild(loader); //adding loader
loader.load(new URLRequest("../Resource/flash/WheelClasses.swf"));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,wheelsLoaded);
}

Related

Access parent of Loader - how?

This should be simple, but I can't figure it out. I have:
myMovieClip = new MovieClip();
myMovieClip.myLoader = new Loader();
This goes for a number of MovieClips. Later, I need to be able to refer back to the parent MovieClip from the Loader itself (because it happens in an event triggered by the Loader finishing loading). "evt.target.loader.parent" doesn't work. Any ideas?
with loaders you'll be able to define complete and error events.
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, LoaderComplete);
loader.contentLoaderInfo.addEventListener(IOErrorEvent.IO_ERROR, LoaderError);
from those functions, if they are handled by the parent class you speak of you are already scoped to the parent object, so you can call all those methods in the callbacks you define.

why can't i declare as3 classes & package in fla file directly on timeline

I am learning actionscript 3. And If I want to create packages and classes i have to create another .as extension file. In which i have to put the package/class code. Which is fine but annoying, and frustrating mainly because i don't understand why it has to be done this way.
Why would code like this:
package {
public class a{
function a(){ trace('Hey'); }
}
}
won't work in fla file, but will work in separate .as file in the same folder.
The timeline and frames are the properties of MovieClip class instance, so when writing code in frames you add it to the main-application-class, which is automatically created by Flash IDE. I.e. you are operating with single class, which is generated by the editor.
There is no way to declare packages and classes in frame-script. You also can not declare more than one externally visible definition (class or function) within one .as file. These are compiler limitations.
Note that you may declare functions, and create instances of other classes, manipulate with display-list objects in frame-scripts, so your abilities are not severely limited.
There is also a way, that works on timeline, to extend class behavior using Object's prototype property:
MovieClip.prototype.summ = function ():void {
trace ('this function extends movieclip class');
}
var instance:MovieClip = new MovieClip();
instance.summ(); // will trace this function extends movieclip class

Loading and using SWF files

I'm new to AS3, and am trying to understand how externally loaded SWFs work in AS3. Since Flash 4/5, it was common to have one main SWF file in a Flash web project, and then load other SWF files into it, often for various "sections" of a website or web project. In the main file, we'd have masks animating the container movieclip(in which external sections/SWF files were loaded) and have animations and transitions play as the section finished loading and the loaded content was displayed.
In AS3, I've used the Loader class to load and display the external file, my main problem is in communicating with the loaded content, call it's functions, or call root functions from it.
In AS2, we could use someMovieClip.loadMovie("ExternalContent.swf") and the ExternalContent file would load inside someMovieClip. You could access functions on the "External.swf" main timeline using someMovieClip.function();. And inside the "ExternalContent.swf", we could use _root.function() to access functions in the main file ExternalContent was being loaded into. Doing this in AS3 seems bizarre and neurotic, and I feel like I'm missing something fairly basic here.
//Loading in ExternalContent.swf into the sprite
//ExternalContent has a movieclip called "boxes" on it's main timeline
//boxes has a boxesPrompt() function in it's timeline.
var sprite:Sprite = new Sprite();
addChild(sprite);
var loader:Loader = new Loader();
loader.load(new URLRequest("ExternalContent.swf"));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoaded);
function onLoaded(event:Event):void
{
sprite.addChild(event.target.content);
sprite.boxes.boxesPrompt();
//Flash gives the following compiler error at the above
//Scene 1, Layer 'Layer 1', Frame 1, Line 21 1119: Access of possibly undefined property boxes through a reference with static type flash.display:Sprite.
//But when I comment out sprite.boxes.boxesPrompt() and use this, it works:
event.target.content.boxes.boxesPrompt()
}
The boxesPrompt() function inside the "ExternalContent.swf" just traces it's parent, grand-parent, and great grand-parent - trace(this.parent.parent.parent);. And when I call that function inside the onLoaded event-handler using "event.target.content.boxes.boxesPrompt()", it shows that the Boxes object(which was on the main timeline of External.SWF), has a parent movieclip, a grand-parent sprite, and a great grand-parent object mainTimeline.
I thought re-parenting the loaded content into the sprite would allow me to access the loaded content as easily as loadMovie() used to be - accessing loaded content like it was present directly inside the clip it was loaded in. But that doesn't work at all.
So to rephrase, my question is:
How do I communicate from the main "loader" SWF file, with the content that's loaded in. I don't want to communicate using event.target.content.{etc} because then I'd only be able to address the loaded content inside the Loader's event.complete event handler.
How do I "re-parent" loaded content, so I can place it inside some movieclip/sprite on the main timeline of the loader file, rather than using some really long convoluted way.
How to communicate from inside the loaded content, to the main/loader file. Previously, we'd use _root.functionName() to do stuff like play some animation transitioning from the current externally loaded "section" to another section. How'd I go about doing that.
AS2 & AS3 is vastly different. But you will have to swallow the fact that AS3 has been developed as an improvement over AS2. So any transition you make, is also for the better.
For eg : The _root in AS2 allowed global objects & variables to accessed & changed anywhere, which is a bad practice & leads to non maintainable code in a project.
Having said that, let me address your questions:
If you are able to get access to the loaded content with
event.target.content... you should save it inside a,say class
variable & may access it later elsewhere in the class.
You must understand that you will be able to access the content only
after loading it, so have to wait for it to complete anyway &
event.complete handler is probably your best bet.
I doubt if you can pick random content from a loaded swf & re-parent it into the current swf.As explained you might not have a long convoluted way.
Accessing the parent could be done in many ways. You can use .parent or actually call a function from the parent swf passing its reference to the child.
var sprite;
addChild(sprite);
var loader:Loader = new Loader();
loader.load(new URLRequest("ExternalContent.swf"));
loader.contentLoaderInfo.addEventListener(Event.COMPLETE,onLoaded);
function onLoaded(event:Event):void
{
sprite = event.target.content;
//This should work
sprite.boxes.boxesPrompt();
}
See this example for more info.

Flash CS5 / AS3, after preloading main class constructor can't reference movieclips

I modified an Adobe Flash CS5 sample to create a swf with a preloader.
In my FLA I've two stopped frames:
In the first frame I only put this code (and a textfield showing percentage):
stop();
this.loaderInfo.addEventListener(ProgressEvent.PROGRESS, onLoading);
this.loaderInfo.addEventListener(Event.COMPLETE, onComplete);
function onLoading(evt:ProgressEvent):void {
var loaded:Number = evt.bytesLoaded / evt.bytesTotal;
percent_txt.text = (loaded*100).toFixed(0) + "%";
};
function onComplete(event:Event):void {
this.loaderInfo.removeEventListener(ProgressEvent.PROGRESS, onLoading);
this.loaderInfo.removeEventListener(Event.COMPLETE, onComplete);
gotoAndStop(2);
};
In the second frame I:
exported the Main class;
I have all the needed graphics assets on stage;
When I test the Adobe sample (it has no main class on frame 2, only a large image) anything works fine, but when I compile the modified version I get strange errors.
In the Main class constructor I reference three movieclips, eg. this way: myClip.alpha=0, but it seems now Flash can't see them anymore (they are null). Why?
How can I make this preloader work?
Thanks in advance.
When you say Main class, are you referring to a class you have set as the Document Class? If I'm following you correctly, the problem is likely that the Document Class is always instantiated on the first frame, so your instances on stage wouldn't yet exist.
It's not possible to have the Document Class wait to instantiate until later frames. You'll probably have to remove your class from the Document Class assignment in order to create your instance on frame 2. At that point, you can pass a reference to your movieclips or stage through to the constructor of your class.

AS3 Problem in loading external SWF into Loader

I have main application that loads external swf's through the Loader Component. But some swf's that are working well on their own don't load into the main app. When I tried to load one of that swf's from fla of main app it gave error that it's looking for some classes. By the name of this classes it looks like it were parts of loaded swf but as swf that is already compiled and working well why is it looking for this class when it's trying to be loaded by the main app?
I didn't find anything that would refer to this kind of issue. Any help will be highly appreciated.
It seems like you got an application domain collision. This can happen if you got conflicting class names in each SWF (e.g swf1 has a class named Main, swf2 has a class named Main as well).
To fix that, load the SWFs into a new application domain:
loader.load(new URLRequest("g.swf"), new LoaderContext(false, new ApplicationDomain(ApplicationDomain.currentDomain)));
If it's not that, you most likely have some code on the first frame of the movie that executes on initialisation of the SWF (See if you get Event.INIT before you get Event.COMPLETE).
This can be easily fixed by removing the code from the frame.
Just for checking I made fla file that contained only Loader component and code of loading:
var loader:Loader = new Loader();
addChild(loader);
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadingFunc);
loader.load(new URLRequest("g.swf"));
function loadingFunc(event:Event):void{
var li:LoaderInfo = event.target as LoaderInfo;
var mc:MovieClip = MovieClip(li.content)
}
This code is from the testing file.
But even this way it still looking for some class that seems to be one of external loaded swf.
The error is such:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at src::Dedo()
at src::Main()
I have no such classes in my main app. So it could be only classes from external swf.