In an usual flash movie, the document has many scenes. I can add and create scenes as I need (Say I have startingScene, middleScene, and endingScene).
Then, I can assign a Document Class to my movie. The Document Class (say I declare a Main.as class and link it), since it inherits from MovieClip, has a scene attribute.
What's the actual relationship between the Main instance which would be the document, and the current scenes?
Is Main class owner of all scenes? Is a Main instance created for each scene? Who's the owner of the scene list?
The Document Class is presenting everything you have in the stage so if you have your scene defined in the timeline you can call
this.gotoAndPlay(0, "Scene 2");
Where this is your Main Class Which is something like this
package
{
import flash.display.MovieClip;
public class Main extends MovieClip
{
// instance variables go here
public function Main()
{
this.gotoAndPlay(0, "Scene 2");
}
// other functions can go here
}
}
So Main Class is owning the timeline and the stage you have defined in Adobe Flash professional for example if you have a button called myButton in the stage it is part of the Main Class so you can do
myButton.addEventListener(MouseEvent.CLICK, clickHandler);
function clickHandler( event:MouseEvent ):void
{
//button clicked
}
Related
I have an as3 script that will scrub the timeline of a movieclip on the stage.
This scrubs the timeline and displays the frame by frame animation but does not execute any actionscript placed on key frames within that movieclip. Users can scrub backwards or forward. I would like to load the script as well as unload depending on the direction the user scrubs. Can this be done?
What you can do is to make new class and extend MovieClip, Inside of that class you can create public methods that you can call from timeline:
public class MyMC extends MovieClip {
public function myMC() {
// constructor
}
public function load():void{
// Do something
}
public function unload():void{
// Do something
}
}
Than if you used "interface" to to add movie clip, click on movie clip and change instance from MovieClip to your class MyMC. Give it also a name (variable name) for example my_mc Than you can call your function from action on timeline
my_mc.load();
my_mc.unload();
Or if you are using just actions to create movie clip you can do like this:
var my_mc:MyMC = new MyMC();
my_mc.load();
my_mc.unload();
In the game that I am making, you choose a shape, and then on the next screen choose a color. The shape selector works fine and loads one of 6 'shape' movie clips into the next stage of the game. On this stage, I have buttons to control color. Im trying to make the buttons change the color of the movieclip by launching a custom event. This would then be detected by a listener within the class for each movieclip.
So far this is my code:
The screen that contains the color change button:
package {
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class ColorSelector extends MovieClip
{
public function ColorSelector()
{
charcoal.addEventListener (MouseEvent.CLICK, onClickCharcoal );
}
public function onClickCharcoal (mouseEvent:MouseEvent): void
{
dispatchEvent (new ColorEvent (ColorEvent.CHARCOAL) );
trace ("click")
}}
The custom event class:
package
{
import flash.events.Event;
public class ColorEvent extends Event
{
public static const CHARCOAL:String = "charcoal";
public function ColorEvent( type: String )
{
super ( type );
}
}}
The movieclip being acted upon:
package {
import flash.display.MovieClip;
public class Gobbert extends MovieClip {
public function Gobbert()
{
this.addEventListener (ColorEvent.CHARCOAL, makeCharcoal)
}
public function makeCharcoal (colorEvent: ColorEvent) :void
{
this.alpha = .5
}
}
It seems to me like the event is not getting through to the class with the listener. I could really use a fresh pair of eyes to help me figure out whats going on. The program doesn't give me any error, just doesn't do much else either. Thanks in advance!
You are missing the bubbles parameter on the constructor. If omitted it defaults to false. The call to super on the custom event should be:
super(type, bubbles, cancelable);
You will want to pass bubbles in as true via addEventListener function call or hard code inside the custom event constructor.
Also make sure the target (instance of Gobbert) movie clip is on the event bubbling path which means the ColorSelector has to be a child of the display list of Gobbert. If your display list is not set up this way you may want to rethink your approach and have the event propagate from the selector to a common parent and then set the color on Gobbert through that common parent.
If I have an instance named "btnExit" which I added manually to the Main Timeline, I can refer to it from my Document Class simply by typing its name, eg.
package{
public class Engine extends MovieClip{
public function Engine(){
trace(btnExit.x);
}
}
}
But now I have an instance that is nested in another movieclip, and I want to access it from a class (not a Document Class).
Let's say I have "Menu" movieclip on my library.
Then I manually drag a "ButtonExit" button to the "Menu" movieclip timeline, I named the instance "btnExit", so "btnExit" is the child of "Menu" movieclip.
The "Menu" movieclip will be added dynamically by code to the main timeline.
Now I want to access the "btnExit" from "Menu" class file, so I write these codes.
The Document Class:
package{
public class Engine extends MovieClip{
public var menu:Menu;
public function Engine(){
menu = new Menu();
addChild(menu);
}
}
}
The Other Class:
package{
public class Menu extends MovieClip{
public function Menu(){
trace(btnExit.x);
}
}
}
But I got error #1009 (null object reference) for unable to access btnExit;
Can anybody help me, pleaseee?
Make sure that the instance of ButtonExit exists on every frame of the menu timeline and that it's instance named appropriately on every frame or write an if statement to only run your code if the Button is currently on the correct frame.
Every frame when the menu clip animates it's going to re instantiate everything on the frame, so if your second/third/fourth/etc frame doesn't have a clip named btnExit it's going to throw an error when the constructor is called for that frame.
Alright, so I'm trying to figure out when a child is added to a movieclip "x", and handling/detouring this operation from within this "x" movieclip.
I tried overriding addChild and addChildAt at with no prevail. The movieclips that are placed on the stage via flash still don't trigger addChild or addChildAt. However, tracing this.numChildren shows '2' correctly.
Any hints?
You can add an event listener for the "added" event for the x movie clip.
x.addEventListener(Event.ADDED, addHandler);
function addHandler(e:Event){
// your code here
}
This link may explain it better:
AS3.0 – Event.ADDED and Event.ADDED_TO_STAGE
The documentation is also a good resource:
flash.events.Event
You can override the default methods of a movieclip by doing the following:
Create a class to extend a movieclip:
package {
import flash.display.*;
public class SuperMovieClip extends MovieClip {
public function SuperMovieClip() {
// constructor code
super();
}
override public function addChild(child:DisplayObject):DisplayObject {
trace("Hello, I am overriding add child");
// still perform the default behavior but you can do what ever you want.
return super.addChild(child);
}
}
}
Then in Flash create a new movieclip, and make sure it is marked as Enable for ActionScript. The Class should be any name you want, but the base class needs to be SuperMovieClip (or the name you chose for your extended class) See image:
Now when any stage clip is created of this base type (regardless if it's in the IDE or through code) it will be of type SuperMovieClip and anytime addChild is called it will override the original function.
For example, I placed an instance of this mc from library onto the stage at design time and compiled it using the following code on the timeline:
import flash.display.Sprite;
stage_mc.addChild(new Sprite());
And it output Hello, I am overriding add child
I'd like to access the stage of the main timeline from w/i a class that extends a movieclip. Basically, I have a button in the main timeline that makes a HUD appear. The HUD is an extended MovieClip class. When people click on a button in the HUD, I'd like to remove the object from the stage of the main MovieClip.
#curro: I think your confusion may come from the fact that I am running this code from a class definition file. Clicking on a button w/i this object should remove it from the DisplayList of the MainTimeline. Here's the code from the class definition file:
package classes {
import flash.display.Stage;
import flash.display.MovieClip;
import flash.events.MouseEvent;
public class Answers extends MovieClip {
public function Answers(){
listen();
}//constructor
//initiatlize variables
public var answersArray:Array = new Array();
private function listen():void {
submit_btn.addEventListener(MouseEvent.CLICK, function(e:MouseEvent){
answersArray.push(answer_txt.text);
e.currentTarget.parent.parent.stage.removeChild(this);
});//listen
}//listen
}//class Definition
}//package
trace(e.currentTarget.parent.parent) gets me the MainTimeline, and trace(e.currentTarget.parent.parent.stage) appears to return the main stage, but I cannot use removeChild w/o getting an error that I am trying to coerce the stage to be a DisplayObject (which it ought to be).
What's on the stage of the MainTimeline: A single button that, when clicked, adds an instance of the Answers class to the stage.
What's part of the Answers class that's not in the code?
I first created Answers as a MovieClip object in the main library. It has 3 parts:
a TextField named "answer_txt"
a "clear_btn" that clears the answer_txt
a "submit_btn" that submits the text of answer_txt and then removes the entire Answers object from the MainTimeline (at least, that's what I want it to do).
your class definition is really weird. Looks like a mixture of as2 and as3.
Try with this:
package
{
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.text.*;
import fl.controls.Button;
public class Answers extends MovieClip
{
public var answersArray:Array = new Array();
public function Answers()
{
submit_btn.addEventListener(MouseEvent.CLICK, remove);
}
private function remove(e:MouseEvent)
{
answersArray.push(answer_txt.text);
this.parent.removeChild(this);
}
}
}
This works on my computer. Your code doesn't. I think it has something to do with the listen method. The class isn't still instatiated and you are making it work.
Hey, I can't make head or tail from the code. Where does submit_btn come from? Is it a property of the class? What about answer_txt?
You don't need to access e.currentTarget... to remove "this" simply:
this.parent.removeChild(this);
If you add that movieclip to the stage then you can access the stage from that class as simple as in the document class
stage
Otherwise you can't access stage from that class. But you can access it by sending the stage as argument when instantiate the class.