I have two classes; my Main class and a class called BlockPlace. I want to use my Main class to run BlockPlace, but for some reason it isn’t working. I’ve tried changing both codes, but it only results in errors. I know for a fact that the code works because I tested it in the timeline. Should I restructure the entire thing or is there a different solution? Here are my classes:
Main Class:
package
{
import flash.display.*;
import source.map.*;
public class Main extends MovieClip{
public function Main()
{
BlockPlace();
}
}
}
BlockPlace:
package source.map{
import flash.display.MovieClip;
import flash.display.Stage;
public class BlockPlace extends MovieClip{
public function BlockPlace(){
var db:MovieClip = new dbox();
stage.addChild(db);
db.x = stage.stageWidth / 2;
db.y = stage.stageHeight / 2;
}
}
}
You’ve got a couple of problems that I can see, which might explain the behavior you are seeing.
First, you are calling this like is a function, not a constructor.
If you want to statically reference this function, then you want to change things up a bit:
And then invoke it using:
Notice that the class no longer extends MovieClip, and the method is marked as static, meaning it can be referenced directly from the class, without a instance of the class. Also notice that the functions signature has changed. It now accepts one argument — the stage — that gets passed in from the outside.
Using this approach, you give the reference to the stage from your
Maininstance into this utility function to do some work. This is probably the most straight-forward solution to your problem.Conversely, if you want to keep this as a class that extends MovieClip — there are some implications of what that means — then you need to instantiate an instance of the class:
Then, you need to get it on the sage:
But you’ve still got a bit of a chicken/egg problem with the stage. When you instantiate the class, in its constructor you are referencing the
stageproperty. At this point of its construction however, it hasn’t been added to anyDisplayObjectContainerswho are attached the stage. So thestageproperty will benull. As such, you can’t add anything to the stage or get thestageHeightorstageWidth.You’ll need to wait until that has happened — which wont happen until
addChild(blockPlace)gets evaulated.So you need to re-think your architecture a bit, you can either move the logic into another function that will get explicitly called by you once you are sure that its has been attached to the stage. Something like:
And then consumed using something like :
A more idiomatic approach however would be to use events to wait until the MovieClip has been added to the stage, and then perform some work. For example:
Notice that the constructor now sets up an event listener which says, “When I get added to the stage, go do the work that’s in this other function called
stageAvailable.”There are some minor caveats that you have to be aware of, it is possible for display objects to be constructed directly on the stage — the flash IDE does this. so the event will not fire for those items, because by the time the event gets attached, its already on the stage, and thus will not fire. The most defensive way to write it is this:
In the constructor, it checks to see if there is a stage, and if so then it immediately calls the function. If not, then it sets up a listener to wait until that happens. Then in the handler, if it was called because of an event, then clean up after itself and remove the listener.