How to access MC inside movieclip added from library? - actionscript-3

I have the following code and I followed the answer from this question, but it doesn't seem to be working for me. I'm not getting an error or getting a trace response.
Basically I need to access this test_mc inside the added child. Am I doing something wrong?
for (var i:int=0; i<30; i++) {
var mc:panelClass = new panelClass();
all_mc.addChild(mc);
mc.x = allWidth * i;
// Accessing the test mc
mc.test_mc.addEventListener(MouseEvent.CLICK, ctaOnClickHandler);
}
function ctaOnClickHandler(e:MouseEvent) {
trace("Clicked");
}

Kind of hard to answer this without know what panelClass is and how it is built. I'm assuming test_mc is a movieclip that's using all it's default properties and is on the display list of panelClass and since there are no errors it's been instantiated. The only think I can think of is there anything being displayed on top of test_mc inside panelClass?

Related

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.

Flex 4 image object returning as MovieClip object

I am working on a custom context menu in Flex4. The context menu itself works fine but I am looking for a way to tell if the ContextMenuEvent mouseTarget is an image. As it stands, the mouseTarget shows that it is a "[object MovieClip]". Which is strange because I have no movie clips in my application, only image containers. Any idea what is going on?
private function openContextMenu(e:ContextMenuEvent):void {
Alert.show(e.mouseTarget.toString());// shows [object MovieClip] when it should show [Object Image]
}
Thanks
You need to set mouseChildren on the Image to false, then the MouseEvent will refer to the Image:
if (event.target is Image) {
//do stuff
}
So after a few more hours of research I came up with the below attached to the contextMenu's item select event listener. I am sure there has to be a better way to do this, but until then...
for(var i:int = 0; i < getObjectsUnderPoint(new Point(this.mouseX, this.mouseY)).length; i++)
{
if(getObjectsUnderPoint(new Point(this.mouseX, this.mouseY))[i].parent.parent is Image)
{
//do what I need to do
}
}
Thanks NHubben for your input. It got me going down the right path of looking at children.
The component name Image has no relevance concerning what makes it up. The flex inheritance is: Image -- SWFLoader -- UIComponent -- FlexSprite -- [...] (from mx.controls.Image docs).
So what you need to do is understand what you actually have when you bring it into a AS3 environment. It seems like it gets wrapped up in a MovieClip to allow it be in the Flash's display list. It also looks like you have to go through a loader, but I'm not sure of that.
Run a test or two to find out what the object is actually made up of:
// not foolproof, and will break on some stuff,
// so you will have to fix this as needed:
private function loopDisplay(obj:Sprite):void
{
trace(obj.name + ": " + obj);
if (obj.numChildren > 0)
{
for (var i:int = 0; i < this.numChildren; i++)
{
loopDisplay(obj.getChildAt(i));
}
}
}
If you put this in a mouse down handler, then you can see what is actually there.
However, the event.target or event.currentTarget should also hold the menu item object, so you can also just loop into those objects and see what is in them.

Problem to move a MC on foreground

i've a problem to a set a different child index of a Movieclip. This is the code:
function processMusica():void
{
var loadStatus:int=0
var lastHeight:int=0
for (var m=0; m < myXML.BLADE[sup].child("brano").length(); m++)
{
var titolobrano:TextField=new TextField
bladearray[sup].contenitore.addChild(titolobrano)
titolobrano.text=myXML.BLADE[sup].brano[loadStatus].titolo
lastHeight=titolobrano.height
titolobrano.doubleClickEnabled=true
titolobrano.addEventListener(MouseEvent.DOUBLE_CLICK, riproducibrano)
loadStatus+=1
}
if (isPlaying==false)
{
var riproduzioneDetails:MovieClip=new MovieClip
riproduzioneDetails.name="riproduzioneDetails"
var artista:TextField=new TextField
artista.name="artista"
bladearray[sup].contenitore.addChild(riproduzioneDetails)
riproduzioneDetails.x=475
riproduzioneDetails.addChild(artista)
}
setChildIndex(bladearray[sup].contenitore.riproduzioneDetails, bladearray[sup].contenitore.numChildren-1) //<------ PROBLEM HERE!
I want to move "riproduzioneDetails" MC on foreground, but when i attempt to launch application, it give me this error: TypeError: Error #2007: Parameter child must be non-null
I can see two potential problems, but it is hard to say because all the variables are not declared in your code. There may be a problem with your test condition:
if (isPlaying==false)
{
...
}
If "isPlaying" is true, your object "riproduzioneDetails" is never created, so of course it will be null. You have to create your object outside the "if" condition, before testing "isPlaying".
Another potential problem is the way you access your object, with "bladearray[sup].contenitore.riproduzioneDetails". As you used the "addChild" method to store your object, there should logically be a kind of "getChild" method. For instance,
setChildIndex(bladearray[sup].contenitore.getChildByName("riproduzioneDetails"),bladearray[sup].contenitore.numChildren-1)
... may be better.

Removing an event listener as well as a sprite at the same time AS3

I’m having trouble removing the an event listener as well as the sprite at the same time. I currently get an error:
TypeError: Error #1009: Cannot access
a property or method of a null object
reference.
And if I comment out removeChild, I have no error but, obviously, the sprite remains on the screen. Any ideas how I can rid myself of that error?
//Bullet extends Sprite Class
bullet:Bullet = new Bullet();
mc.addChild(bullet);
bullet.addEventListener(Event.ENTER_FRAME, shoot);
function shoot(e:Event):void {
var shot:Bullet = e.currentTarget as Bullet;
//check shot is outside the frame
if (shot.x < 0 - shot.width || shot.x > stage.stageWidth || shot.y > 525)
{
//trying to remove the thing and it's listener
e.currentTarget.removeEventListener(e.type,arguments.callee);
e.currentTarget.parent.removeChild(shot);
}
else
{
shot.setInMotion();
}
}
Apart from a missing var before bullet:Bullet, I don't see anything wrong in the example code. You should set a breakpoint right after:
var shot:Bullet = e.currentTarget as Bullet;
And figure out why shot is null. I suspect there is something amiss in a piece of code outside of the little bit you're providing as the example. If the code is working with only the removeChild line commented out, it tells me that e.currentTarget is not null, but that it's also not a reference to an instance of type Bullet (i.e. the "as" cast is returning null).
Try reversing these lines
Maybe the reference to e.currentTarget is getting lost through the object references
e.currentTarget.removeEventListener(e.type,arguments.callee);
e.currentTarget.parent.removeChild(shot);
to
e.currentTarget.parent.removeChild(shot);
e.currentTarget.removeEventListener(e.type,arguments.callee);

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

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.