ActionScript 3 name property is not returning the right name...? - actionscript-3

I experienced a problem with the name property in as3, I created this "dot" movieclip and I exported to a class,
then I anonymously created a bunch of dots using a loop. I assigned numbers as name to each dots
private function callDots(num:Number):void
{
for (var i = 0; i < subImagesTotal[num]; i++)
{
var d:Dot = new Dot();
d.x = i*23;
d.y = 0;
d.name = i;
dotContainer.addChild(d]);
}
}
so far so good, I checked that if I trace the name here, I will get the number I want.
However, it's not giving me the numbers if I trace it in other functions.
I added all of my dots to "dotContainer", and if I click on one of the dots, it will call this function
private function callFullSub(e:MouseEvent):void
{
var full_loader:Loader = new Loader();
var temp:XMLList = subImages[sub];
var full_url = temp[e.target.name].#IMG;
full_loader.load(new URLRequest(full_url));
full_loader.contentLoaderInfo.addEventListener(Event.INIT, fullLoaded);
}
e.target.name is suppose to be numbers like 1 or 2, but it's giving me "instance66" "instance70" and I
have no idea why. Because I did the same thing with loaders before and it totally worked.
Any ideas? Thanks.
christine

The e.target returns the inner most object clicked on, this could be a TextField, another MovieClip or posibly a shape (I'm not 100% of the last one) inside the "Dot".
To prevent this you could try to set the mouseChildren property to false on the Dot's when you add them. This should insure that nothing inside the dots can dispatch the click event, and thus the Dot's should do it.
Perhaps you could also in the event handler verify the target type with code like this:
private function callFullSub(e:MouseEvent):void
{
if(!e.target is Dot)
throw new Error("target in callFullSub is not Dot but: " + e.target.toString());
//The rest of you code here
}

The answer is [e.currentTarget.name] I perform this all the time!
Should return "Dot1" "Dot2", etc.
If the value you wish to return is a number or other data type other than a string (name of object) use [e.currentTarget.name.substr(3,1).toString()]
Should return 1, 2, etc.
Navee

I tried to reproduce your problem first with Flex using runtime created movieClips and then with Flash using Dot movieClip symbols exported for ActionScript. Neither application exhibited the problem.
You may already know names like "instance66" "instance70" are default enumerated instance names. So, whatever is dispatching the MouseEvent is NOT the dot instance. Perhaps you are unintentionally assigning callFullSub to the wrong targets, maybe your containers? Try assigning it to dot instance right after you create them, like this:
private function callDots(num:Number):void
{
for (var i = 0; i < subImagesTotal[num]; i++)
{
var d:Dot = new Dot();
d.x = i*23;
d.y = 0;
d.name = i;
d.addEventListener(MouseEvent.CLICK, callFullSub);
dotContainer.addChild(d]);
}
}
Be sure to temporarily comment out your original assignment.

Try this might work,..
d.name = i.toString();

You have not shown enough of your code for me to be able to give you a DEFINATE answer, I will however say this.
//After you create each loader you need to set its mouseEnabled
//property to false if you do not want it to be the target of
//Mouse Events, which may be superseding the actual intended target;
var full_loader:Loader = new Loader();
full_loader.mouseEnabled = false;
//Also you could name the loaders and see if what comes back when you click is the same.
ALSO! Add this to your Mouse Event handler for CLICK or MOUSE_DOWN:
trace(e.target is Loader); //If traces true you have an answer
I believe that the mouse events are being dispatched by the Loaders.
please provide more of your code, the code where the Loader.contentLoaderInfo's COMPLETE handler fires. I assume this is where you adding the loaders to the display list as I cannot see that now.

Related

Unable to reference MovieClip inside Button AS3

I have this annoying issue that I hope someone might be able to help me with.
I have a mute button that I created and I have another movieclip inside of that button. All I want it to do is when I toggle the mute the movieclip inside will go to the according frame.
However, every time I try to call the movieclip inside of the button, this error comes up:
Access of possibly undefined property mcMuteToggle through a reference with static type flash.display:SimpleButton.
The instance name for the movieclip within is "mcMuteToggle".
Why not make movieClips that act like buttons?? Since I dont think actual button (simpleButton) types can deal with sub-MovieClips (especially if they too have code). Even if possible don't do it, I can predict a mess whereby Button does things it shouldn't do depending on what code you have in those MClips.
Try an alternate button method, just for a test... You didnt show any test code to work with so I will make assumptions..
1) Make a shape (rectangle?) and convert to MovieClip (or if all coded, then addchild shape to new MovieClip). Let's assume you called it mc_testBtn.
2) Make that MC clickable by coding mc_testBtn.buttonMode = true;
3) Add your mcMuteToggle inside the mc_testBtn
(or by code: mc_testBtn.addChild(mcMuteToggle);
Now you can try something like..
mc_testBtn.addEventListener (MouseEvent.CLICK, toggle_Mute );
function toggle_Mute (evt:MouseEvent) : void
{
if ( whatever condition )
{
mc_testBtn.mcMuteToggle.gotoAndStop(2); //go frame 2
}
else
{
mc_testBtn.mcMuteToggle.gotoAndStop(1); //go frame 1
}
}
This is likely due to strict mode. You can either disable it in the ActionScript settings dialog, access it with a different syntax myButton['mcMuteToggle'], or make a class for the symbol that includes a property mcMuteToggle.
You can also check to make sure the symbol is actually on the stage and that clip is actually in the button:
if('myButton' in root) {
// ...
}
if('mcMuteToggle' in myButton) {
// ...
}
i think u just overwrite that codes. You u can use something like this:
var soundOpen:Boolean = true;
var mySound:Sound = new Sound(new URLRequest("Whatever your sound is"));
var mySc:SoundChannel = new SoundChannel();
var mySt:SoundTransform = new SoundTransform();
mySc = mySound.play();
mcMuteToggle.addEventListener(MouseEvent.CLICK, muteOpenSound);
function muteOpenSound(e:MouseEvent):void
{
if(soundOpen == true)
{
mcMuteToggle.gotoAndStop(2);
/*on frame 2 u need to hold ur soundClose buton so ppl can see :)*/
soundOpen = false;
mySt.volume = 0;
mySc.soundTransfrom = st;
}
else
{
mcMuteToggle.gotoAndStop(1);
soundOpen = true;
mySt.volume = 1;
mySc.soundTransfrom = st;
}
}
This is working for me everytime. Hope u can use it well ;)

Can i create a function to tell a button to open a movie clip of the same name

I am new to the actionscript side of flash,
I am working on a map that has say 20 popups(movieclips) and the countries are the buttons, i have just been informed i need to add 60 more.
Below is an example of the code i have been using
english_movie.visible=french_movie.visible=turkish_movie.visible=false
english_btn.addEventListener(MouseEvent.CLICK, englishButtonClick);
french_btn.addEventListener(MouseEvent.CLICK, frenchButtonClick);
turkish_btn.addEventListener(MouseEvent.CLICK, turkishButtonClick)
function englishButtonClick(event:MouseEvent):void {
english_movie.visible=true;
english_movie.play();
french_movie.visible=turkish_movie.visible=false
}
function frenchButtonClick(event:MouseEvent):void {
french_movie.visible=true;
french_movie.play();
english_movie.visible=turkish_movie.visible=false
}
function turkishButtonClick(event:MouseEvent):void {
turkish_movie.visible=true;
turkish_movie.play();
english_movie.visible=french_movie.visible=false
}
Im thinking there must be an easier way to do this than replicating the code over and over.
Any help would be much appreciated.
Here's how to simplify the whole thing with code: Each btn object is
related to one movie object. This can be achieved with a Dictionary.
var btnToMovieAssociation:Dictionary = new Dictionary();
btnToMovieAssociation[english_btn] = english_movie; // repeat this line for every btn/movie pair
Now you have to generalise your click handler. The key difference
between each function (apart from making one certain movie visible)
is that they all make certain other movies invisible. But actually,
it's sufficient to only make the previously visible movie invisble.
To do this, create a variable that keeps track of the current visible
movie.
var currentMovie:MovieClip = english_movie;
Initialising the variable with english_movie has no effect on the
program. you can pick any other of the movies. It will make things
easier in the following code if this variable is initialised.
Now your function does effectively this:
make movie of clicked button visible
play this movie
make last movie invisible
Here's the cool part. You only add one listener. Look up if something
is in the dictionary for the clicked thing and consider that the
movie you want to show next.
addEventListener(MouseEvent.CLICK, buttonClick);
function buttonClick(event:MouseEvent):void
{
var movie:MovieClip = btnToMovieAssociation[event.target]
if (movie == null)
return; // nothing in the dictionary, it wasn't a button that was clicked.
movie.visible=true;
movie.play();
currentMovie.visible = false;
currentMovie = movie;
}
There are problems with this solution:
You still have to declare every pair, which is still tedious and prone to erro. (you have to type every name twice)
If your buttons are made up of several objects, event.target might point to them instead of the button as a whole. But with only
the btns in the dictionary and not all their individual parts,
nothing would be found in the dictionary. This can be circumvented by
setting mouseChildren = false; on every btn.
i posted this question else where and got this response
var tl:MovieClip=this;
var mc:MovieClip;
var i:int;
var buttonA:Array=[english_btn,french_btn,turkish_btn];
for(i=0;i<buttonA.length;i++){
buttonA[i].addEventListener(MouseEvent.CLICK,buttonF);
tl[buttonA[i].name.split("_")[0]+"_movie"].visible = false;
}
function buttonF(e:MouseEvent):void{
for(i=0;i<buttonA.length;i++){
tl[buttonA[i].name.split("_")[0]+"_movie"].visible = false;
}
tl[e.currentTarget.name.split("_")[0]+"_movie"].visible=true;
}
Which works great.

AS3 .name attribute not working for a library symbol

I'm having a symbol in the library that's exported for ActionScript to be added later.
A Loop is adding them sequentially, but I want to add a Mouse Event Listener to them and have them call another function when clicked, so I tried linking a .name attribute to them, but it is not working though the e.target.name , only working inside the loop :( , and I tried lots of things. What should I do ?? Thank you :)
function CreateMenuPagesButtons(): void {
for (var i: uint = 0; i < totalPages; i++) {
var menu_btn: MenuButton = new MenuButton;
menu_btn.page_number.text = String(i + 1);
menu_btn.name = (i + 1).toString();
menu_btn.x = i * 50;
menu_btn.page_number.mouseEnabled = false;
MenuPagesButtons_Container.addChild(menu_btn);
}
stage.addChild(MenuPagesButtons_Container);
MenuPagesButtons_Container.addEventListener(MouseEvent.CLICK, movetoTargetMenuPage);
function movetoTargetMenuPage(e: MouseEvent): void {
var targetPage:String = e.target.name;
trace(targetPage);
The trace function if inside the loop, gives correct names: 1 , 2 , 3, while the other one at the last line in the code as shown, gives the name of the instance set through the properties tab.. and if no name is given there, it will give "Instance110" - "Instance115" - etc..
So I got it fixed :D :D :D
Let me tell you how in case someone else had the same problem.
the (e.target.name) was referring to the clicked single button inside the over all symbol, rather than referring to the symbol from top level, so I changed it to (e.target.parent.name) and it worked.. Yayyy :D Thanks All :)
This is so, because you add listener to MenuPagesButtons_Container, which means that e.target IS MenuPagesButtons_Container. If you want to get which button is clicked, you must add listeners to each button:
for (...) {
menu_btn.addEventListener(MouseEvent.CLICK, movetoTargetMenuPage);
Then it will work.

I can't seem to access automatically named objects (instance##) placed on the stage in AS3, am I missing something?

I have a movieclip in the library that is added to the stage dynamically in the document class's actionscript. This movieclip contains many many child images that were imported directly from photoshop at their original positions (which must be preserved).
I do not want to manually name every single image instance, as there are dozens upon dozens.
I have already gone through and manually converted the images to symbols, as apparently flash won't recognize the "bitmap" objects as children of a parent movieclip in AS3 (numChildren doesn't see the bitmaps, but it sees the symbols).
I have an array filled with references to the dozens of children, and I loop through it, checking if each one is under the mouse when clicked. However, somehow, it is not detecting when I click over the items unless I manually name the child symbols (I tested by manually naming a few of them -- those ones became click-sensitive.)
I have already done trace() debugging all throughout the code, verifying that my array is full of data, that the data is, in fact, the names of the instances (automatically named, IE instance45, instance46, instance47, etc.), verifying that the function is running on click, verifying that the code works properly if I manually name the symbols.
Can any one see what's going wrong, or what aspect of flash I am failing to understand?
Here is the code:
//check each animal to see if it was clicked on
private function check_animal_hits():void
{
var i:int = 0;
var animal:Object = this.animal_container;
for (i=0; i<animal.mussels.length; i++)
{
if (this.instance_under_cursor(animal.mussels[i].name))
{
var animal_data = new Object();
animal_data.animal = "mussel";
this.send_data(animal_data);
}
}
}
Here is the code for the instance_under_cursor() method:
// Used for finding out if a certain instance is underneath the cursor the instance name is a string
private function instance_under_cursor(instance_name)
{
var i:Number;
var pt:Point = new Point(mouseX,mouseY);
var objects:Array = stage.getObjectsUnderPoint(pt);
var buttons:Array = new Array ;
var o:DisplayObject;
var myMovieClip:MovieClip;
// add items under mouseclick to an array
for (i = 0; i < objects.length; i++)
{
o = objects[i];
while (! o.parent is MovieClip)
{
o = o.parent;
}
myMovieClip = o.parent as MovieClip;
buttons.push(myMovieClip.name);
}
if (buttons.indexOf(instance_name) >= 0)
{
return true;
}
return false;
}
Update:
I believe I have narrowed it down to a problem with getObjectsUnderPoint() not detecting the objects unless they are named manually.
That is the most bizarre way to find objects under mouse pointer... There is a built-in function that does exactly that. But, that aside, you shouldn't probably rely on instance names as they are irrelevant / can be changed / kept solely for historical reasons. The code that makes use of this property is a subject to refactoring.
However, what you have observed might be this: when you put images on the scene in Flash CS, Flash will try to optimize it by reducing them all to a shape with a bitmap fill. Once you convert them to symbols, it won't be able to do it (as it assumes you want to use them later), but it will create Bitmpas instead - Bitmap is not an interactive object - i.e. it doesn't register mouse events - no point in adding it into what's returned from getObjectsUnderPoint(). Obviously, what you want to do, is to make them something interactive - like Sprite for example. Thus, your testing for parent being a MovieClip misses the point - as the parent needs not be MovieClip (could be Sprite or SimpleButton or Loader).
But, if you could explain what did you need the instance_under_cursor function for, there may be a better way to do what it was meant to do.

AS3 Removechild Addchild issue/error

I have been looking for an answer for hours:
My program:
Step I) When I click on a button, it displays a bitmap through addchild;
Step II) When I click on another button, it should remove the bitmap through removechild;
Step I) works perfectly but step II) doesn't work.
You'll find below some parts of my code:
First, I declare:
public var ajoutcarte4:MovieClip;
Secondly, In the main function I wrote:
var ajoutcarte4:Bitmap = new Bitmap();
Then, in a sub function triggered by the first button, I add the Bitmap to the stage (fl_bitmap is a function returning a Bitmap item):
ajoutcarte4 = fl_bitmap(couleur4+figure4);
ajoutcarte4.x=445;
ajoutcarte4.y=370;
addChild(ajoutcarte4);
So far so good but when I want to remove the child through another sub function triggered by a second button:
removeChild(ajoutcarte4);
It doesn't work because ajoutecarte4 is apparently null... Error 2007 when i get red of my condition...
change this
public var ajoutcarte4:MovieClip;
to
public var ajoutcarte4:Bitmap;
Then take out this line completely
var ajoutcarte4:Bitmap = new Bitmap();
And lastely
// add this like with this code
ajoutcarte4 = new bitMap()
ajoutcarte4 = fl_bitmap(couleur4+figure4);
ajoutcarte4.x=445;
ajoutcarte4.y=370;
addChild(ajoutcarte4);
You've declared a field ajoutcarte4 of type MovieClip, but then in your function, you declare a local variable ajoutcarte4 of type Bitmap, which is then added to the stage.
In the second function, you try to remove the field MovieClip, which has never been instantiated - and thus produces the error.
Change your declaration to this:
public var ajoutcarte4:Bitmap;
and call:
ajoutcarte4 = new Bitmap();
(without the var). Then it all should work correctly.