[FONT=Arial]Hi everyone. I’ve gotten a lot of good help here so far and hope to return the favour someday.[/FONT]
[FONT=Arial]I’m an intermediate AS2 coder starting to use better OOP practices. I have searched for the answer to this but have not found anything, perhaps because everyone else learned it a long time ago.[/FONT]
[FONT=Arial]It appears that classes which extend an MC which is contained inside a different MC do not run their constructor immediately after the containing MC is instantiated. Also this MC’s methods are not immediately available. As a result I need to wait a bit, by using onLoad or another frame. I can live with it but it feels kludgy.[/FONT]
[FONT=Arial]Here is an illustration which I have made as slim as possible:[/FONT]
[FONT=Arial]LIBRARY:[/FONT]
[FONT=Arial]–Symbol with ID “ball”, linked to AS2 class “Ball”.[/FONT]
[FONT=Arial]–Symbol with ID “box”, linked to AS2 class “Box”. This symbol contains an instance of “ball” which I dragged in there and gave an instance name “ball_0”.[/FONT]
[FONT=Arial]–Symbol with ID “launcher”, linked to AS2 class “Launcher”.[/FONT]
[FONT=Arial]STAGE:[/FONT]
[FONT=Arial]–Dragged onto stage’s frame 1 the symbol “launcher”.[/FONT]
[FONT=Arial]–Nothing else on stage.[/FONT]
[FONT=Arial]CLASSES:[/FONT]
dynamic class Launcher extends MovieClip {
function Launcher() {
trace("Launcher constructor");
init()
}
function init(Void) {
instance = this.attachMovie("box", "box_0", 0);
trace("Box has been attached");
trace("The ball's _x is: "+instance.ball_0._x);
trace("Setting A directly");
instance.ball_0.testPropA = "Launcher init() put this here";
trace("Ball testPropA is: "+instance.ball_0.testPropA);
trace("Setting B with method, immediately");
instance.ball_0.setB();
trace("Ball testPropB is: "+instance.ball_0.testPropB);
}
}
dynamic class Box extends MovieClip {
function Box() {
trace("Box constructor");
}
}
dynamic class Ball extends MovieClip {
function Ball() {
trace("Ball constructor");
}
function setB(Void) {
trace("Running setB");
this.testPropB = "Ball setB() put this here"
}
function onLoad(Void) {
trace("Ball onLoad");
trace("Setting B with method after onLoad");
this.setB();
trace("Now ball testPropB is: "+this.testPropB);
}
}
[FONT=Arial]OUTPUT:[/FONT]
[FONT=Arial]Launcher constructor[/FONT]
[FONT=Arial]Box constructor[/FONT]
[FONT=Arial]Box has been attached[/FONT]
[FONT=Arial]The ball’s _x is: 68.55[/FONT]
[FONT=Arial]Setting A directly[/FONT]
[FONT=Arial]Ball testPropA is: Launcher init() put this here[/FONT]
[FONT=Arial]Setting B with method, immediately[/FONT]
[FONT=Arial]Ball testPropB is: undefined <----------------------problem is here[/FONT]
[FONT=Arial]Ball constructor[/FONT]
[FONT=Arial]Ball onLoad[/FONT]
[FONT=Arial]Setting B with method after onLoad[/FONT]
[FONT=Arial]Running setB[/FONT]
[FONT=Arial]Now ball testPropB is: Ball setB() put this here[/FONT]
[FONT=Arial]VISUAL RESULT:[/FONT]
[FONT=Arial]See the ball in the box, as expected.[/FONT]
[FONT=Arial]OTHER NOTES:[/FONT]
[FONT=Arial]If I comment out the init() in Launcher’s constructor and instead put into frame1 this code, I get the same result:[/FONT]
[FONT=Arial]this.launcher_0.init();[/FONT]
[FONT=Arial]QUESTIONS:[/FONT]
[FONT=Arial]How can I fix this so that setB would work in the above example? I have found two workarounds but I wonder if there is another which feels less kludgy.[/FONT]
[FONT=Arial]Solution A): As seen in the example, put into Ball an onLoad function (or maybe just its constructor) which then runs any initialization functions. As a result I need to store in the object some properties which the object can find in itself and use for initialization.[/FONT]
[FONT=Arial]Solution B): Put the method call on a timeline frame after the frame in which the attachMovie is done.[/FONT]
[FONT=Arial]At the heart of this question is, why can I set the ball’s properties (as seen with setA) but not be able to call its methods successfully? On one hand, I can see that the thread is busy with the box’s initialization and can’t be expected to run ball’s constructor right away, even though ball has been instanced. But on the other hand, I am actually calling a method of an instance which is obviously there, so shouldn’t it have the common decency to do as I ask? ;)[/FONT]
[FONT=Arial]Bonus question is, is the fact that this does not work a bug in Flash AS2 or is it perfectly to be expected due to some CS common sense which I lack?[/FONT]
[FONT=Arial]Another bonus question is, is this a harebrained way to use Flash AS2 classes—linking symbols to AS2 classes which extend MovieClip (or which are subclasses of classes which themselves extend MovieClip), and using attachMovie to instance all of these MCs except the one “Launcher” which is the only thing on the .fla’s stage? It’s a cornerstone of my architecture so I’d like to know if this is utterly daft.[/FONT]
[FONT=Arial]Thanks very much for any enlightenment.[/FONT]