Adobe Air - Dispatch event with parameter - actionscript-3

How to pass the addChild(event.target.loader) through a dispatch event from the class to the main timeline?
package scraps
{
...
public class FileScrap extends Scrap
{
...
private function loadImage(event:Event):void{
addChild(event.target.loader);
}
Thanks

You can create a custom event class that extends flash.events.Event and have the DisplayObject that gets loaded sent as a property of that event. In that case FileScrap will need to inherit from EventDispatcher or implement IEventDispatcher.
You could also just dispatch a generic event called IMAGE_LOADED or something like that, and have the main class poll a public method in scraps to get the image whenever it receives the event.

Related

Error when overriding constructor of extended class

I found a quite strange problem while making two classes in AS3. Let's call them ParentClass and ChildClass. In order to make both of them you need a Sprite object, then the ParentClass makes it visible in the stage. ChildClass inherits the ParentClass, too.
ParentClass.as:
package myStudio.basic {
import flash.display.MovieClip;
import flash.display.Sprite;
public dynamic class ParentClass extends MovieClip {
public function ParentClass(mc:Sprite=null) {
addChild(mc);
}
}
}
ChildClass.as:
package myStudio.containers {
import myStudio.basic.ParentClass;
import flash.display.MovieClip;
import flash.display.Sprite;
public class ChildClass extends ParentClass {
public function ChildClass(mc:Sprite=null) {
addChild(mc);
}
}
}
Then, I write this code on Frame 1, Layer Actions of the FLA file:
var mc:MovieClip = new childMC;
var vig:ChildClass = new ChildClass(mc);
addChild(vig);
However, I got run-time error #2007:
TypeError: Error #2007: The value of the parameter child must not be null.
at flash.display::DisplayObjectContainer/addChild()
at myStudio.basic::ParentClass()
at myStudio.containers::ChildClass()
at myStudioComicAnimator_fla::MainTimeline/frame1()
I tried overriding the ChildClass constructor function, but it still doesn't work.
So here's my question: Is there another workaround to solve this problem?
The reason for that is that you are not calling super. You can check what's happening in the error stack (down to top):
you instantiate ChildClass, and you pass the previously created childMC to the constructor
ChildClass extends ParentClass, so when instantiated it always calls the constructor
the constructor of ParentClass tries to add something as a child
The problem is that you cannot add null as a child. But because the constructor is called internally, there is no param that is being passed to it. so mc variable is always null. But as we said - null cannot be added.
Use the super by yourself:
public function ChildClass(mc:Sprite=null) {
super(mc);
}
This way the ParentClass will get reference to the mc object and will be able to add it.
Another option is not to use addChild in the ParentClass, but only in ChildClass. Then it doesn't matter if you pass anything to super, or even if you are calling super at all.
Edit: I forgot to say that this is not a bug, but a standard behavior and works exactly like it should work. The reason for this is that each class can have a whole different override of the constructor. It can take more or less parameters, so the chain for calling parent's constructor is your job to handle.

Select a extern class to start with

my problem is pretty hard to describe and to google for <_< so ill give it a try here.
ihave my main.as, char.as, enemy.as, classes
my main was the stage of course.... it worked pretty well, but now that my main is extern too, it wont be called anymore...
it calls: char, enemy(which is a sub class of char) and then the empty stage but it never calls my main.as which should be called first...
also it never calls any constructors...how can i tell flash to start with my main.as?
i hope you got it, the code is probably to much to post here :P
If get you right.. you have to put super() calls to extended classes.
So for example in enemy class constructor:
public class enemy extends char {
function enemy() {
super(); // calls "char" class constructor
}
}
and if you have params in your constructors:
public class enemy extends char {
function enemy(param1: String, param2:String) {
super(param1, param2); // calls "char" class constructor
}
}
Overriding methods:
override public function doSome():void {
super.doSome(); // call parent class
}
and to make flash start with your main class - select your FLA file stage in flash (professional) and from the right side panel (properties) set Class to your main class (for example: com.myApp.Main).

Call custom method as Display Object AS3

I have a class which extends MovieClip. This class has an update() function which needs to be called every new frame with the deltaTime in the arguments. This works if the class has been declared but not if it has just been added to the display list.
Code in the main class:
package packageFoo{
import flash.display.MovieClip;
import packageFoo.customMovieclip;
public class Main extends MovieClip{
public function Main():void{
var testMc:customMovieClip = new customMovieClip();
addChild(testMc);
testMc.update(dt);
}
}
}
This outputs the correct values where as if I just added it without referencing it:
package packageFoo{
import flash.display.MovieClip;
import packageFoo.customMovieclip;
public class Main extends MovieClip{
public function Main():void{
addChild(new customMovieclip());
this.getChildAt(0).update(dt);
}
}
}
This makes the compile time error: 1061: Call to a possibly undefined method update through a reference with static type flash.display:DisplayObject.
I can't really reference the 'customMovieclip's because I am wanting multiple ones.
It looks like this.getChildAt(0) is not customMovieClip. This can arise if your Main has pre-places components at design time. To check, do trace(this.numChildren) as the first line of Main() constructor. And also, to address any subclass methods properly, you need to typecast your DisplayObject returned by getChildAt() to a proper type.
(this.getChildAt(0) as customMovieClip).update(dt);
Still, using a class-wide variable is better if you want to address that custom MC in more than one function of main class.
If you're trying to avoid a reference to the custom class in the document class, you can call it like this:
this.getChildAt(0)["update"](dt);

super() in Flash Builder. WHY?

Every time I start a new actionscript class in Flash Builder it starts off the constructor with a line
super()
I have never seen this before, and it seems to have no purpose. Deleting it results in the exact same movie.
Why is it inserted into my new class and what does it do?
super() calls the constructor from the class that you're inheriting (extending).
If your inherited (base) class has no required parameters in it's constructor, you can omit it all together and flash will automatically call it before your constructor code.
You can call other functions (that are public or protected) from your base class by using the super keyword:
super.myBaseClassMethod(); //would call the method 'myBaseClassMethod' from your base class even if you had an overriden method with in this class
EXAMPLE:
package {
public class BaseClass {
public function BaseClass(){
trace("Base Class Constructed");
}
public function someBaseMethod():void {
trace("some method called from base");
}
}
}
package {
public class MyClass extends BaseClass { //this class is extending the class above
public function MyClass():void {
trace("My Class constructed");
super();
someBaseMethod();
super.someBaseMethod();
}
override public function someBaseMethod():void {
trace("Override");
}
}
}
So if you do this:
var tmp:MyClass = new MyClass();
You will get:
"My Class constructed"
"Base Class Constructed"
"override"
"some method called from base"
If you omit super(), it will be:
"Base Class Constructed"
"My Class constructed"
"override"
"some method called from base"
As a part of inheritance, super invokes the superclass or parent version of a method or constructor.
Invokes the superclass or parent version of a method or constructor.
When used within the body of a class constructor, the super()
statement invokes the superclass version of the constructor. The call
to the superclass constructor must have the correct number of
arguments. Note that the superclass constructor is always called,
whether or not you call it explicitly. If you do not explicitly call
it, a call with no arguments is automatically inserted before the
first statement in the subclass constructor body. This means that if
you define a constructor function in a subclass, and the superclass
constructor takes one or more arguments, you must explicitly call the
superclass constructor with the correct number of arguments or an
error will occur. The call to the superclass constructor, however,
does not need to be the first statement in your subclass constructor,
as was required in ActionScript 2.0.
When used in the body of an instance method, super can be used with
the dot (.) operator to invoke the superclass version of a method and
can optionally pass arguments (arg1 ... argN) to the superclass
method. This is useful for creating subclass methods that not only add
additional behavior to superclass methods, but also invoke the
superclass methods to perform their original behavior.
You cannot use the super statement in a static method.
In ActionScript, classes can extend other base classes not marked as final.
For example, MovieClip inheritance is as follows:
Sprite > DisplayObjectContainer > InteractiveObject > DisplayObject > EventDispatcher > Object
By invoking super(), you control when parent constructors are called.
package
{
import flash.display.MovieClip;
public class ExampleMovieClip extends MovieClip
{
public function ExampleMovieClip()
{
super(); // MovieClip's constructor is called
}
}
}

Do custom Event type identifiers in as3 need to be unique?

Say I have two classes which extend Event:
public class CustomEventOne extends Event
{
public static const EVENT_TYPE_ONE:String = "click";
//... rest of custom event
and
public class CustomEventTwo extends Event
{
public static const EVENT_TYPE_TWO:String = "click";
//... rest of custom event
Is it ok that they both declare an event type using the same string "click"?
Or do event type identifiers need to be unique throughout the application?
You can definitely run into collisions with this. This will be very evident if you use bubbling, or listen for both events on the same object. At the core, the event listeners are listening for a string. There is no strong typing, just a if(string==type) check (this is over simple, but essentially what is happening).
it would be proper to name these event types:
public static const EVENT_TYPE_ONE:String = "eventTypeOne";
If you make use of any [Event(name="eventTypeOne", type="com.me.events.CustomEvent")] this syntax is essential.
If your code listens for a CustomEventOne event on an object by calling addEventListener with CustomEventOne.EVENT_TYPE_ONE, that event handler will get called when the object dispatches either CustomEventOne.EVENT_TYPE_ONE or CustomEventTwo.EVENT_TYPE_TWO as both are essentially "click". As Joel stated, objects listen for event types which are plain strings.