AS#3 target ignoring parent movieClip - actionscript-3

I changed the question as its seems to be a problem with target not registering children mc/ or nested MovieClips.
var box:Box = new Box();
ground.push(box);
levelPlane.addEventListener(MouseEvent.MOUSE_DOWN, onOver);
box.x = box.width /2* (x + y);
box.y = box.height/2 * (x - y);
levelPlane.addChild(box);
function onOver(e:MouseEvent):void{
var tree1:Tree1 = new Tree1();
addChild(tree1)
trace(e.target.x);
tree.x = e.target.x;
}
How Do i target the movieclips(BOX) inside of the main MovieClip(levelPlane)?
imagine i have nested 10 boxes inside a MovieClip Called "levelPlane" i want to click on any of the boxes to add another Mc on the box i clicked x,y location.

If I understand correctly, you are trying to place the newly created movie clip on top of the other, but they are not within the same coordinate space. The target's coordinates must be translated to tree1's coordinate space, for both of them to have the same position:
var tree1:Tree1 = new Tree1();
addChild(tree1);
var global:Point = e.target.parent.localToGlobal(new Point (e.target.x, e.target.y));
var local:Point = globalToLocal(global);
tree1.x = local.x;
tree1.y = local.y;

The Event.currentTarget property refers to the current object processing the event, i.e., the listener object. If you want reference to the object which dispatched the event, use e.target

Related

as3 - How to access child's child?

I dispatched an event for a bullet to spawn on the page. However the bullet should be located in the area where the page's child child should be. There is a Page One MovieClip, which has a child named player and the player's child is gun. So I'm trying to keep the location and rotation of the bullet the same as the player's gun. So I need to access Page One's child's child. The player and the turret are using instance names and not variables.
I tried this code, but the bullet spawns in the page but will not spawn itself on the turret's location. This event is located in the PageOne class.
function fire(e:Event)
{
var b:Bullet = new Bullet();
b.rotation = player.turret.rotation;
b.x = player.turret.x + player.turret.width * Math.cos(player.turret.rotation / 180 * Math.PI);
b.y = player.turret.y + player.turret.width * Math.sin(player.turret.rotation / 180 * Math.PI);
addChild(b);
}
You can access to the turret child. The problem is that you need to convert the coords inside the turret MovieClip to the coords inside the PageOne MovieClip:
var b: Bullet = new Bullet();
var turretpoint:Point = new Point(player.turret.width, 0);
var pagepoint: Point = this.globalToLocal(player.turret.localToGlobal(turretpoint));
b.rotation = (player.scaleX > 0) ? player.turret.rotation : 180 - player.turret.rotation;
b.x = pagepoint.x;
b.y = pagepoint.y;
addChild(b);

Preventing the bounding box of transparent Bitmap Sprite from triggering mouse events

I thought I had solved my mouseEvent problem for Sprites containing a Bitmap with an alpha channel but I've encountered a new issue shown in the image below: the bounding box of the "Eurasia" map Sprite is triggering a `MouseEvent.Roll_Out" for the "Africa" Sprite.
My setup: Each map piece is a Sprite with a child Bitmap (PNG with alpha) and a "hitArea" Sprite derived from the Bitmap. The relevant code is below. This works great – except in the case where there are bounding box overlaps. The eventListeners I attach to each Sprite use MouseEvent.ROLL_OVER and MouseEvent.ROLL_OUT but I have also tried MouseEvent.MOUSE_OVER and MouseEvent.MOUSE_OUT.
I've tried attaching eventlisteners to the "hitArea" Sprite and various other things but I can't get the bounding box to be ignored. Are there any settings I may have missed – or a workaround?
Code:
buttonImage = new Bitmap(upImageData);
buttonImage.smoothing = true;
this.addChild(buttonImage);
hitSprite = createHitArea(upImageData, 4);
this.addChild(hitSprite);
hitSprite.visible = false;
hitSprite.mouseEnabled = false;
this.hitArea = hitSprite;
public function createHitArea(bitmapData:BitmapData, grainSize:uint=1):Sprite
{
var _hitarea:Sprite = new Sprite();
_hitarea.graphics.beginFill(0x000000, 1.0);
for(var x:uint=0;x<bitmapData.width;x+=grainSize) {
for(var y:uint=grainSize;y<bitmapData.height;y+=grainSize) {
if(x<=bitmapData.width && y<=bitmapData.height && bitmapData.getPixel(x,y)!=0) {
_hitarea.graphics.drawRect(x,y,grainSize,grainSize);
}
}
}
_hitarea.graphics.endFill();
_hitarea.cacheAsBitmap = true;
return _hitarea;
}
If using a vector mask is not a viable option (it should work if you changed your hitSpite into a Shape and then made it the mask of the map piece sprite - also you'd have to add it as a sibling of the map piece and not a child), then the way most people do this is checking if the pixel under the mouse is transparent or not.
Here is an example:
Let's say all your map pieces are the sole children of a Sprite referenced in a var called container. Let's also make the assumption for the example, that your map pieces are all Sprites that have the png Bitmap as the bottom most child.
You need to add the click listener to the container (instead of each individual map piece):
container.addEventListener(MouseEvent.CLICK,click);
function click(e:MouseEvent):void {
var child:Sprite; //a helper var to store the current iterations child below in the while loop
var target:Sprite; //the item that we determined was clicked
//iterate through all children of container (backwards, so we process the top most layer first)
var i:int = container.numChildren;
while(i--){
child = container.getChildAt(i) as Sprite; //populate the child var
//now we check if the mouse is over this child by a simple hit test point
//we also then check if the pixel under the mouse is transparent (a value of 0)
if(child.hitTestPoint(e.stageX, e.stageY) && Bitmap(child.getChildAt(0)).bitmapData.getPixel32(child.x + e.localX,child.y + e.localY)){
target = child;
break; //break out of the loop since we found a child that meets the criteria
}
}
trace(target);
//now do something with target
}

as3 accessing Children from dynamicly added moiveclip

I am adding moiveClips and putting their position accordingly. I am placing all the dynamically added clips in one new movie clip and then centering that on stage. As a test, I see I can control the alpha in the main container but I can not access the children. How can I assess each flagButton separately? There would be several in this loop example below.
var flagButton:MovieClip;
var flagArray:Array = new Array;
var flagDisplayButtons:MovieClip = new MovieClip();
function displayFlagButtons()
{
for( var i = 0; flagArray.length > i; i++)
{
var flagButton:MovieClip = new roundButton();
flagButton.x = (flagButton.width + 10) * i;
flagButton.y = stage.stageHeight - flagButton.height;
addChild(flagButton);
flagDisplayButtons.addChild(flagButton);
}
addChild(flagDisplayButtons);
// Works
flagDisplayButtons.x = stage.stageWidth/2 - flagDisplayButtons.width/2;
// Does not see flagButton
flagDisplayButtons.flagButton.alpha = .5;
}
GETS ERROR:
TypeError: Error #1010: A term is undefined and has no properties.
In your example code, you have created a bunch of button instances, and one by one you have added them to the display list of flagDisplayButtons. They are on that display list in the order that you placed them.
first instance is at index 0
second instance is at index 1
third instance is at index 2
and so on.
So if you want to access the third button you added, you could do this :
var flagButton:RoundButton = flagDisplayButtons.getChildAt(2) as RoundButton;
Now that you have created variable to reference that button, you can do any of these :
flagButton.alpha = .5;
flagButton.x = 100;
flagButton.y = 200;
You need to use getChildAt or getChildByName to get the children of a DisplayObjectContainer
IE:
flagDisplayButtons.getChildAt(0).alpha = 0.5;

AS3 Calling a child's index during a for each

I have a function that uses a mouse click event to create a child of a symbol at the mouse's coordinates. The instance is then pushed to an array.
I am now trying to make a new function that allows you to drag/drop a child when the mouse is within 10 pixels of it. When the child is dropped, I want it to rotate to face the next child in the array. I am currently communicating with each child in the array using a for each loop.
The bit I'm having trouble with is getting the index value of the child being dropped and setting it to a variable.
For reference, ins_trailPoint is the variable that creates the child and tPoint is the name of the array containing the children. child is the variable trying to acquire the index value of the dropped child.
function movePoint(Event:MouseEvent):void {
for each (var ins_trailPoint in tPoint) {
var child:int = event.target.parent.getChildIndex(event.target);
var px:Number = mouseX - ins_trailPoint.x;
var py:Number = mouseY - ins_trailPoint.y;
var dist = Math.sqrt(px*px + py*py);
if (dist<10) {
stage.removeEventListener(MouseEvent.CLICK, addPoint);
stage.addEventListener(MouseEvent.MOUSE_UP, dropPoint);
ins_trailPoint.startDrag();
function dropPoint(event:MouseEvent):void {
ins_trailPoint.stopDrag();
var dx:Number = tPoint[child+1].x - ins_trailPoint.x;
var dy:Number = tPoint[child+1].y - ins_trailPoint.y;
var radians:Number = Math.atan2(dy,dx);
ins_trailPoint.rotation = radians * 180/Math.PI;
The parameter of movePoint() is called Event with a capital letter, but you try tu use event in lower case.

AS3 Can't access MC on Stage

I have 54 MC's on stage, generated dynamically. Now I want to get their x and y positions when rolling over but I am having problems getting the path correct e.g.
function copyFlightCellData():void {
var r; var s;
var cellData:Array = new Array ();
for (r = 0; r < 54; r++){
//var copyCellData = new MovieClip();
cellData[r] = Object(root).mc85.name; //["mc"+r+r];
trace("$$$$$$$$$$$$$$$$$$$$$" + cellData[r]);
}
}
I used the list objects in debug and they are listed in _level0 e.g.
Movie Clip: Frame=1 Target="_level0.mc85"
Not sure why I can't access their properties.
This is the code that created the MC's
// Create copies of flightCell for board grid
var my_mc = new flightCell();
my_mc.name = "mc" + i + j;
trace("^^^^^^^^^^^^^^****************" + my_mc.name);
addChild(my_mc);
Answer is pretty simple, use the DisplayObjectContainer object's, in this case root, getChildByName() method, for example:
var sprite1:Sprite = new Sprite();
sprite1.name = "sprite1";
addChild(sprite1);
trace((root as DisplayObjectContainer).getChildByName("sprite1").name); // output : sprite1
It's probably a better idea to store the movieclips you have on your stage in an array to begin with.
To access it by name you have to assign a name to them when you create them.
mc85.name = "mc85";
As an alternative that I recommend, you can use getChildAt(index) : http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObjectContainer.html?filter_flash=cs5&filter_flashplayer=10.2&filter_air=2.6#getChildAt()
Also, I highly recomend you to create an empty movieclip or sprite and add all of this mcs to them instead of the root.