Transparent PNGs and Flash
December 10, 2012 12:13 PM   Subscribe

Flash CS5/actionscript 3 - how to click through transparent pngs?

I have 2 movie clips and inside each movie clip is a transparent png, the 2 movie clips overlap such that the non-transparent areas of the pngs are touching but do not overlap. Both movie clips are linked to the same actionscript class - so they have the same onclick event. In the areas where the bounding boxes overlap the top one receives the click event even if it is transparent in the area that is being clicked.

That's a simplified example of what's going on, in actuality there are 3 instances of the same movie clip, all in the same place. The movie clip has numerous transparent pngs imported from photoshop - 1 per frame and actionscript determines which frame to display at any given time. The pngs appear to be solid objects though, even if I 'break apart' the transparent areas still highlight when the object is selected and seem to be inseparable. Trace Bitmap allows only the solid area to be clickable but image quality is lost - including making straight edges curved, (some are quite complex shapes and they really do need that tiny bit of edge aliasing to look their best.

Is there a solution? I googled the problem but didn't find much help, most solutions relied on checking the alpha transparency of the pixel under the mouse and only doing x if it wasn't transparent but as far as I can tell the bottom one doesn't even receive the click event.
posted by missmagenta to Computers & Internet (10 answers total)
Wait, so these movie clips are all at the same x.y location on the stage, but are only suppose to be active depending on which frame of the animation you're on?

A really quick way to do this is to add: stage.addChild(instanceNameOfMovieClip) to the actions for each specific frame. So, each frame would have this code.

What this will do is take the movie clip and make it the top most layer. Every time you enter a frame (assuming you are entering with gotoAndPlay(2) and not gotoAndStop(2)) it will make that movie clip the topmost one.

If this is the same movieclip and same event listener in all the frames, then why not just have one single movie clip that spans across all the frames?
posted by royalsong at 12:31 PM on December 10, 2012

Maybe I should explain in more detail.

I have 5 rooms, each room has 3 walls. On my stage I have 3 instances of a movieclip that contains all the walls for all the rooms - so 15 frames in total. Each frame is labelled to denote the room and wall name eg. dining_room_back_wall. The pngs in the walls movieclip are aligned inside the movieclip relative to where the wall should appear when the walls and rooms movieclips are given the same coords.
When I select a room each of the three instances of walls moves to the frame of the wall it is to show - eg.

That all works fine but in this example the bounding box for the ceiling png overlaps with bounding boxes for the 2 walls because the bounding boxes are rectangular but the contents aren't.

This is an unfinished demo. Click on a wall then click on a colour, the wall you selected should change colour. If you click on the ceiling near the bottom it will select the back wall.
posted by missmagenta at 1:00 PM on December 10, 2012

Can you mask the images, or are they brought in dynamically?
posted by kaseijin at 1:22 PM on December 10, 2012

When I'm working with transparent pngs, I tend to break apart the image, outline the hit area directly on it with lines so as to separate the transparent area out, then delete that portion of the image. What Break Apart does is make a vector rectangle with the original image as a bitmap fill, so you're effectively drawing the wall's silhouette and texturing it with the image.

I'm not sure if I've explained that very well, but I could upload an example fla if it doesn't make sense.

Flash doesn't care about pixel alpha, so the only way to do this really is to disable mouse interactions for all of your images, check the pixels under any global clicks yourself, then work out which image should have been clicked on. There are probably some libraries to do this out there, as you've found, but for your app I think manually drawing some simple hit boxes would make more sense.
posted by lucidium at 1:24 PM on December 10, 2012

Ahh, I see.

So your best bet is to create new targets or hit boxes for this instead of using those pictures. You'd have to create targets as simple shapes in flash and not import it from photoshop. One for every wall and ceiling in every picture.

See my example:

This way when they click on the green shape, you can have it change to whichever colors the user picks.

If you know how the hit states work in button symbols, this is the same exact thing. You shouldn't have to change much of your code either, just update your names with the new hit boxes.
posted by royalsong at 1:25 PM on December 10, 2012

What I was going to propose is similar to what lucidum said -- but use a separate mask layer instead of break apart/delete.

I've found that file size takes a hit when using unnecessary transparency in your images. If you're manually tweaking the images in the IDE anyway, might as well bring them in as JPG's rather than PNG's.
posted by kaseijin at 1:44 PM on December 10, 2012

Using a separate mask as royalsong and kaseijin suggested would be a tiny bit more work but would definitely allow you to be more accurate (as you wouldn't be constrained by having the mask cover every visible bit of the image). That said, royalsong mentions buttons, which might be an even better choice:

If you convert the images to buttons, you can just draw your custom masks on their hit frames, and everything should work without you having to change any code.
posted by lucidium at 1:53 PM on December 10, 2012

Actually, ignore my comment about buttons. It only works if all of the different buttons are on the same timeline, it breaks if you have them wrapped in separate MovieClips (as I believe you have).
posted by lucidium at 1:59 PM on December 10, 2012

I chopped off just the overlapping bits and it works like a charm - its not perfect but good enough for these purposes.
The reason all the walls are in the same movie clip instead of in their own buttons was I needed them all to have the same class (because they have all the same behaviors) and it didn't seem to want to let me have multiple different objects with the same class.
posted by missmagenta at 2:05 PM on December 10, 2012

By the way, if you want to do something similar in the future, you can give multiple MovieClips the same Base Class so that they each have their own class, but share behaviour.
posted by lucidium at 6:41 AM on December 23, 2012

« Older What are other kinds of "magic" than the ones...   |   A haircut, short and sweet Newer »
This thread is closed to new comments.