accessing functions between two (2) movieclip inside a nested movieclip AS3 - actionscript-3

ok im a noob for AS3 since i just started, i have two (2) movieclips inside a movieclip, the main mc is called main_mc then the two movieclips inside named trigger_mc and move_mc, trigger_mc has the instance name of start_ani, then inside the timeline of main_mc i have this code:
import flash.events.MouseEvent;
start_ani.addEventListener(MouseEvent.CLICK, correctans);
function correctans(e:MouseEvent):void {
move_mc.animate();
}
then i created a motion as actionscript 3.0 using move_mc then i inserted the code inside the timeline of the move_mc itself, and i made a function for that motion called animate, my problem is how do i access a function between two movieclips which both are inside another movieclip, i know this method is not programming wise, but i kinda need to learn this, pls help me, i badly need this, thank you in advance.

Parent is a property, not a function - you don't need ():
this.parent.move_mc.animate();
Also, you didn't mention the instance name of the move_mc movieclip, but access like the above requires the instance name to be move_mc - the movieclip symbol name doesn't matter in actionscript.
Update 1: To clarify, you said: trigger_mc has the instance name of start_ani
Good, then this code will work:
start_ani.addEventListener(MouseEvent.CLICK, correctans);
But you didn't say: move_mc has the instance name of ???
So we don't know if this code will work:
function correctans(e:MouseEvent):void {
???.animate();
}
Fill in those ??? for one.
Update 2: do you know if the click handler is being fired? Why not add a trace statement?
function correctans(e:MouseEvent):void {
trace("got click event!");
???.animate();
}
Because for a CLICK event, you need:
start_ani.buttonMode = true;
Though as you say, this isn't good programming practice because this assumes those two movieclips are siblings of the same parent. It's not extensible. If they're not, your code could throw errors. Just keep that in mind.

Related

AddChild with GetChildByName

Complete AS3 noob here - I've tried Googling this, but I can't seem to find what I'm looking for (I stumbled across this, http://ub4.underblob.com/as3-naming-elements-dynamically/, but it doesn't weem to work for me).
I'm trying to dynamically add a Movieclip inside another Movieclip through an external AS3 class
Something like this:
var bullet:Bullet = new Bullet(x, y, "right");
var stageBackground:MovieClip = (stage.getChildByName("back") as MovieClip);
stageBackground.addChild(bullet);
However, while this compiles correctly, at run time, I get error #1009 - Cannot access a property or method of a null object reference.
The debug panel tells me the problem is with this line:
stageBackground.addChild(bullet);
But I can't seem to figure out what's wrong with it. I've tried recasting stageBackground as a Sprite, but that didn't change anything. I know the MovieClip back exists - when I reference it through near identical code in my document class, it works perfectly.
You are accessing stage here to find your container, which is very likely the problem.
You are probably thinking that the stage property refers to "the stage" in Adobe Flash authoring environment.
That's not true.
If you placed a MovieClip on "the stage" in the Flash IDE, it ends up on the main time line, this however, is not the thing the stage property is referencing. stage is the topmost DisplayObjectContainer in the display list. It only exists at runtime. It more or less represents the FlashPlayer window, the runtime environment that executes your .swf file.
In short: you are simply looking for your back MovieClip in the wrong place.
The property of a container that represents the main timeline is root.
Do not use root either.
As you can see, your code becomes dependent on the display list
structure of your application. You are already struggling to find the
container that you are looking for. If you change the structure, your code breaks. Even changing the name of the container (for example to something like "background") will wreak havoc.
Instead, use Events.
You are in another class and you want to fire a bullet.
So you create that bullet same as you do now:
var bullet:Bullet = new Bullet(x, y, "right");
Next, dispatch an Event to notify the rest of your code that a bullet was created and it should be placed in the appropriate container:
dispatchEvent(new BulletEvent(BulletEvent.CREATED, bullet));
(Create a custom event class BulletEvent that extends Event, with the apropriate setter and getter for a Bullet object)
Register a listener on the object of your class that creates the bullets, you will catch this event and place the bullet in the container:
var object:YourClass = new YourClass();
object.addEventListener(BulletEvent.CREATED, addBulletToContainer);
function addBulletToContainer(e:BulletEvent):void
{
// adding the bullet to the container
back.addChild(e.bullet);
}
This code would be placed in the parent of your back MovieClip.
The Flash IDE automatically creates variables behind the scenes that have the same names as the instance names. That's why the variable back is available here.
Using events here allows you to literally fire the bullet into your code with somebody else taking care of it, where it's easy to figure out the container it belongs into.

How do I edit a variable declared in the root contained within the frame of a movie clip?

So I have a main scene called Game. In that scene, I have a movieclip called Shop. Inside that movieclip called shop, I have another movie clip called upgradeweapon2. Inside upgradeweapon2, I have a button called "upgradeweaponpb".
I am working in actionscript, in the frame of the movie clip upgradeweapon2. I am trying to edit a variable called "weaponlvl" that was declared in Game. A picture to show what I mean:
http://gyazo.com/96b04ab89ea4a589bee560d53d165b03.png
I am getting the following error: Access of undefined property weaponlvl.
Please tell me there is a way around this... I know weaponlvl is defined in the root scene, game, but is there a way to make the declaration valid across levels of MovieClips, or at least a way to transfer the values accross?
Here is the code I am trying to add:
stop();
upgradepb.addEventListener(MouseEvent.CLICK, upgradeweapon5);
function upgradeweapon5(event:MouseEvent):void{
weaponlvl++;
}
EDIT: Alright I simplified my code, It's just a movieclip, not two layers. But still the same error. Any idea what I can do?
weaponlvl is on the frame of upgradeweapon2.upgradeweaponpb; it is not on the root layer, so therefore in action script it will not make sense. You have two options:
Get weaponlvl through MovieClip(root).weaponlvl or this.parent.parent (which is also the root).

Using a MovieClip as a parameter in AS3

I'm having problems attaching MovieClips to different instances of a class. I'm kinda new to ActionScript 3, honestly, so this question might be a bit noobish. I did the research, though, but haven't found the kind of answer that I expected.
function AddNewElement(clip:MovieClip, array:Array, name:String, firstValue:int, secondValue:int):Element
As you may be able to guess, this is the function I made to create instances of a class in a dynamic way and add them to an array. I'm having problems with the very first parameter, though. How do I pass a MovieClip from my library to this function?
I saw a lot of answers to problems similar to this one stating that each MovieClip should be a class on its own, but since I have like forty MCs and I want to use them all for more or less the same thing I feel that it kills the purpose of classes, really.
How should I approach this?
First you need to give your library symbols unique class names from the linkage section while exporting or later from the "properties" option. You will see this input when you check the "Export for ActionScript" option there. Then you will need to instantiate your library symbol (with the new keyword) and cast it to MovieClip to pass to this function. So
AddNewElement(new LibrarySymbolClass() as MovieClip,[],'etc',0,0);
AddNewElement(MovieClip(new LibrarySymbolClass()),[],'etc',0,0);
will both let you do what you want.
However, since not all your library elements need to extend the MovieClip class, you would better pick DisplayObject instead of MovieClip. So a better version of your function would be
import flash.display.DisplayObject;
function AddNewElement(clip:DisplayObject, ...):* {
// some code here
return clip;
}
var clip:LibrarySymbolClass = AddNewElement(new LibrarySymbolClass() as DisplayObject,[],'etc',0,0);
trace(clip);
Using asterisk in the return value type will let it return the object with its right type (as [object LibrarySymbolClass] in this example).
Why not to create the movie clips on runtime, aka. creating them in the runtime execution context then instantiating each of them at the moment when you invoke the class. If each of the MC's is different, then either you create a MC class for each of them, giving them a name which end up in a ascending number, then using a for loop you put them in an array like so:
var mc_num:int = 40 // the number of MovieClips
var arr:Array = new Array();
for (var i:int=0; i < mc_num; i++) {
arr.push("myMovieClip" + String(i));
}
..then making reference to each of them by using the array index. I skip the part where you associate the images to MovieClips.
After that you invoke the desired MC as below:
var mc_1:MovieClip = arr[1] as MovieClip;
stage.addChild(mc_1);
When you create a MovieClip in Flash it gives you certain options, one of those options is for Flash to create a class for that MovieClip. That being said if you have that option applied to all forty movie clips then you create something like a master movie clip class and have each movie clip class extend the master movie clip class. The only thing is that you would have to create a .as file for each of your 40 movie clips and add extends MasterMovieClip to the class declaration. For example:
public class MasterMovieClip extends MovieClip {
// All of the variables and methods pertaining to each movie clip go here
}
Then each individual movie clip would resemble this class.
public class IndividualMovieClip_1 extends MasterMovieClip {
// Just include a constructor, even though you don't have to
}
Now all of your individual movie clips will have the same methods and variables, as long as said methods and variables are public, not private.
With this method you would have to create all 40 classes, however there might be a way in Flash when creating a new movie clip to set which class the movie clip extends and then you wouldn't have to create 40 different classes.
Update:
I re-read your question and thought of something else, that option I talked about in the first sentence, the one about Flash giving the option to create a class. Well if a class is not given then Flash will dynamically create a class at run-time. I think when it dynamically creates a class it does not maintain the same name as the library movie clip, so when your trying to pass the static name of your movie clip to your function, it has no clue what your talking about and throws a runtime error.

In flash with as3.0, I have to call a function on the main stage from a movieClip

I have to call a function that is defined on the main stage of my project, and I have to call it from a MovieClip, what can I do?
I'm using flash cs5.5 and AS3.0
There are multiple ways to access the MainTimeline from objects on the stage. Probably the most reliable is 'root', but there is also 'parent' (but only if you MovieClip is a direct child of the main timeline).
// root should always work
Object(root).myFunc();
// parent will only work if your movieclip is a direct child of the main timeline
Object(parent).myFunc();
Note that you have to cast these are generic Objects (or MovieClip would work) because they return typed classes that don't have a 'myFunc' function in them.
You'll need this code on your main timeline:
function myFunc():void {
trace("My function got called!");
}
When I read your question it sounds as though you have a function defined in an action frame of your main timeline.
My answer may be out of reach for your current project, and ToddBFisher's answer is perfectly right. That said - I'm going to answer the question differently.
Instead of defining a function on the main timeline, set up a document class, define your functions there, and access the class's functions in your code. Keep as much code off your timelines as possible.
Downloadable files for Document Class example: http://www.isgoodstuff.com/2008/06/06/actionscript-30-documentclass-in-plain-english/
Setting up an AS3 class: http://www.adobe.com/devnet/flash/quickstart/creating_class_as3.html
Assuming your movie clip is a direct child of your main stage, in you movie clip you can do:
MovieClip(parent).theFunctionToCall();
if your MovieClip has a class, just add it to your main class using like:
var m:MovieClip = new MovieClip();
**addChild(m);
then you can get access into it's public function like typing:
m."functon name";

Recreating stage layout in as3

I have 27 MovieClips in my Library which are all images. At the moment they are positioned on the stage as instances of their parent and then made to function in the first frame of my actions layer. I want to recreate this layout solely in code so there is nothing on the stage. How do I do this?
Thanks in advance.
Sam
Right click on a movieclip in the library, then go to Properties.
Tick "Export for ActionScript", then check the name where it says "Class". Hit OK.
Let's say this name was "Symbol1".
Then type this script:
var symbol1:MovieClip = new Symbol1();
addChild(symbol1);
var symbol1 means you created a variable, MovieClip is the type. This MovieClip variable is a "new " Symbol1 (this was the name in the library, Properties, Class.
Then add this to the stage:
addChild(symbol1)
If you want to position it on the stage, set the coordinates of the variable:
symbol1.x = 10;
symbol1.y = 10;
puts it to (10, 10).
Depending on how many objects you have you can type this code for each one of them (don't forget to Export them for actionscript in Library->Properties).
If you have tons of movieclips and you don't want to type evertyhing, but would rather write some dynamic code, give us a hint on your library structure and how you named your objects.
Hope this helps.