Actionscript 3 - Making one MovieClip the hitArea of another - actionscript-3

Suppose I have a rectangle whose instance name is
rectangle
and suppose I have a square right beside the rectangle and the squares instance name is
square
. Now, I want the rectangle to hitArea to be it's own area as well as the square's area. So, if I have these three event listeners:
rectangle.addEventListener(MouseEvent.CLICK, rectangleClick);
rectangle.addEventListener(MouseEvent.MOUSE_OVER, rectangleHover);
rectangle.addEventListener(MouseEvent.MOUSE_OUT, rectangleOut);
How do I make it so that when I hover over, hover out of and click the rectangle OR square, the rectangle event listeners get called?
Note: the event listeners have
event.target
and
event.currentTarget
so I cannot do a simple
square.addEventListener(MouseEvent.CLICK, rectangleClick);
since I need the rectangle to be the
event.target
.

Since your listeners are referencing the Rectangle only, just identify it by its instance name and NOT event.target. Now you can apply the same addEventListner() method to the Square, and the Rectangle will be acted upon, in either case, by the listener function.

Related

AS3: How can I implement a perfect ROLL_OVER(or MOUSE_OVER) event listener on curved movieclips

I've a problem with ROLL_OVER event listener. When I enter the empty area withing the movieclip with mouse cursor, ROLL_OVER event triggers. But I want that event trigger only when mouse cursor is on the colored area.
To Make it more clear: Think about " O " letter, when mouse cursor is between the empty area of O letter (inside of O) , event shouldn't trigger. It should trigger only when mouse curser is on the black area.
How can I implement this?
Thanks
-Ozan
PROBLEM IS SOLVED THANKS TO #Ethan Kennerly
I just want to add a few things to help people have problem same as me. In my situation I tried to make continents glow when my mouse is over them. I used the ROLL_OVER/MOUSE_OVER eventlistener to check if my mouse is over them or not. But with the data given by Ethan Kennerly I produced another way.
In Ethan Kennerly's solution, if your mouse enters the area of continent from a transparent area , it doesn't get blur effect because ROLL_OVER and MOUSE_OVER event listeners only trigger once per enters so I used MOUSE_MOVE event listener on each continent movieclips.
And for this statement:
if (isPixelTransparent(DisplayObject(event.currentTarget), new Point(stage.mouseX, stage.mouseY)) {
return;
}
add whatever is in the "ROLL_OUT or MOUSE_OUT" eventlistener function, add all of them inside this statement. But don't remove ROLL_OUT or MOUSE_OUT functions.
It sounds like the movie clip contains a shape that has transparent pixels. Transparent pixels respond to mouse over and roll over. If you could draw vector graphics that have no shapes with transparent pixels, the mouse would ignore the empty space in the movie clip's bounding box.
Yet it sounds like you need to use transparent pixels and you want the mouse to ignore them, so you could guard, like this:
private function onRollOver(event:MouseEvent):void
{
if (isPixelTransparent(DisplayObject(event.currentTarget), new Point(stage.mouseX, stage.mouseY)) {
return;
}
// respond to roll over.
}
To detect transparency, Miguel Santirso rendered the pixels and translated the coordinate space here: http://sourcecookbook.com/en/recipes/97/check-if-a-pixel-is-transparent-in-a-displayobject (Except line 38 looks on my computer like "rect" got rendered as "ct"). You could optimize that code by only drawing the pixel in question, instead of the whole image, and checking if that pixel value (getPixel32) is 0, instead of calling a hitTest. I would optimize Miguel's code like this:
public static function isPixelTransparent(objectOnStage:DisplayObject, globalPoint:Point):Boolean
{
var local:Point = objectOnStage.globalToLocal(globalPoint);
var matrix:Matrix = new Matrix();
matrix.translate(-local.x, -local.y);
var data:BitmapData = new BitmapData(1, 1, true, 0x00000000);
data.draw(object, matrix);
return 0x00000000 == data.getPixel32(0, 0);
}
By the way, if all your movie clips would have the same hit test shape, you could create a separate transparent shape that listens to the roll over. I use a transparent shape to define a custom hit test shape that is a consistent and simple shape (like a circle) when the image is a more complicate shape (like an X or an O with nothing in the middle). The custom hit test shape is a Sprite with a transparent shape. The sprite listens to the roll over. A separate mouse listener shape is also useful if your movie clip, on later frames, creates new shapes that alter the silhouette of the movie clip.
The easiest solution would be using the Interactive PNG class by Moses.
http://blog.mosessupposes.com/?p=40
Normally the clear areas of a PNG are treated as solid, which can be especially frustrating when dealing with a lot of images that overlap each other because they tend to block mouse interactions on the clips below them.
This utility fixes that so that mouse events don't occur until you
bump against a solid pixel, or a pixel of any transparency value
besides totally clear. InteractivePNG lets you set an alphaTolerance
level to determine what transparency level will register as a hit.

AS3 addChild() drawing on top of my movieClip on CLICK

So basically my issue is when I click on my movieClip I want it to spawn this animation I did over the protonCore. Essentially to show that when you click the protonCore you generate 1 proton. However the problem with this when spamming your CLICK, is that when it adds this child on every click, it draws on top of the movieClip and prevents hit detection while the addedChild "fuseSpark" is added to the stage. Is there a way to make it so when I add this child it doesn't affect the hitBox of the clickable movieClip?
function protonGenerator(e:MouseEvent):void
{
var fuseSpark:MovieClip = new MC_FX_fuse;
stage.addChild(fuseSpark);
fuseSpark.x = stage_protonCore.x;
fuseSpark.y = stage_protonCore.y;
}
An easy solution would be to disable the mouse for those children when you create them:
fuseSpark.mouseEnabled = false;
That is, ofcourse, only if you don't care if the user can click those elements.

How to click through a Rectangle (like mouseChildren = true)

I have this problem, I use this image pan class: http://www.lextalkington.com/blog/2009/08/auto-pan-class-for-panning-an-image-on-mouse-movement/
but the problem is that the objects/sprites/movieclips that are in it have to be clickable, only problem is that the mouseChildren adn mouseEnabled properties can't be applied to a Rectangle object.
Anyone has an idea on how to be able to click through this so I can acces my objects in the panned item? (if that makes any sense...)
This class is using a Rectangle as the scrollRect for the image. The scrollRect only specifies the visible area of the image. It is not the thing you want to detect mouse clicks on.
Instead, you can listen for a mouse click on the image itself.
From the code you linked to, the image is a DisplayObject variable named _clip.
In the constructor for that image panning class, you can add your mouse listener:
_clip.addEventListener(MouseEvent.CLICK, onImageClick);
Then define the event handler:
private function onImageClick(event:Event):void
{
// do something
}
By the way, since _clip is a DisplayObject, it doesn't have mouseChildren or mouseEnabled properties (those are defined in subclasses of DisplayObject).
_clip.mouseEnable = false;
this should work, considering tha _clip will be clicked through

Make bitmap partially invisible AS3

I am trying to make a object (movie clip containing textfields and bitmaps) and I need to make it partially transparent at times (like making half of it disappear). How is it possible?
// only things inside the rect will be visible
DisplayObject.scrollRect = new Rectangle(...);
A MovieClip is also a DisplayObject.

Dynamically adding tween to n MC's

Here's what I'm aiming for. I'm querying the Rotten Tomatoes API for Upcoming Movies. For each movie returned, I'm creating an instance of MovieIcon (MC). I'm then adding this MC as a child of a Container MovieClip that's already on the scene. Each time, I'm incrementing the xPosition of each MovieIcon MC such that, they're positioned next to each other.
My container MC has a mask applied to it, therefore any child objects that are positioned beyond the size of the mask, they're are hidden from view.
How can I dynamically add a tween/easing animation between all these MovieIcon MC's so that when I hover over the Container MC, it 'scrolls' left or right, depending on the mouse motion?
Thanks in advance.
First I would recommend using a tweening library.
TweenLite and Tweener are good options
http://www.greensock.com/tweenlite/
http://code.google.com/p/tweener/
Both of these include docs that will help you get everything set up in your project.
Then you should be able to add a ROLL_OVER event to each of your MovieIcon MC's
MovieIcon.addEventListener(MouseEvent.ROLL_OVER, handleRollOver);
Inside your handler you can use the event.target property to get a handle on the over MovieIcon.
Assuming your using TweenLite you can go and add your tween to that target
private function handleRollOver(e:MouseEvent):void{
TweenLite.to(e.target, duration, {x: new x value, any other prop: any other val})
}