how I can arrange the object on the stage AS3 - actionscript-3

I have a puzzle and 9 pictures, so when I Start Drag any picture i want it to come above of the all remaining.
How I can do it on Action Script 3.0?
this is for example:
import flash.events.Event;
Puz3_Level7A.addEventListener (MouseEvent.MOUSE_DOWN, StartPuz3);
function StartPuz3 (e:Event):void
{
Puz3_Level7A.startDrag();
}
Puz2_Level7A.addEventListener (MouseEvent.MOUSE_DOWN, StartPuz2);
function StartPuz2 (e:Event):void
{
Puz2_Level7A.startDrag();
}
Puz1_Level7A.addEventListener (MouseEvent.MOUSE_DOWN, StartPuz1);
function StartPuz1 (e:Event):void
{
Puz1_Level7A.startDrag();
}

Try following.
import flash.events.Event;
Puz3_Level7A.addEventListener (MouseEvent.MOUSE_DOWN, StartPuz3);
function StartPuz3 (e:Event):void
{
this.setChildIndex(Puz3_Level7A, this.numChildren - 1);
Puz3_Level7A.startDrag();
}
Puz2_Level7A.addEventListener (MouseEvent.MOUSE_DOWN, StartPuz2);
function StartPuz2 (e:Event):void
{
this.setChildIndex(Puz2_Level7A, this.numChildren - 1);
Puz2_Level7A.startDrag();
}
Puz1_Level7A.addEventListener (MouseEvent.MOUSE_DOWN, StartPuz1);
function StartPuz1 (e:Event):void
{
this.setChildIndex(Puz1_Level7A, this.numChildren - 1);
Puz1_Level7A.startDrag();
}
This code assume all the above sprites are children of same sprite.

you can just do
this.parent.addChild(this);
to put 'this' on the top of all parent's children

There are some perfectly good answers already, but in the interest of DRY (don't repeat yourself) and completeness, here is my take on this.
A clean way of doing this, including stopping the drag. No inline functions or unnecessarily repeated code.
//add the mouse down listener to all objects you want to be able to drag.
//if you have a lot, you could also do this in a loop to make it more concise.
Puz3_Level7A.addEventListener(MouseEvent.MOUSE_DOWN, dragPuzzlePiece, false, 0, true);
Puz2_Level7A.addEventListener(MouseEvent.MOUSE_DOWN, dragPuzzlePiece, false, 0, true);
Puz1_Level7A.addEventListener(MouseEvent.MOUSE_DOWN, dragPuzzlePiece, false, 0, true);
var currentPiece:Sprite; //a var to hold a reference to item last mouse downed (to use in the mouse up handler)
//the mouse down handler to drag a piece
function dragPuzzlePiece(e:Event):void
{
currentPiece = e.currentTarget as Sprite; //the event's current target is a reference to the item you added the listener to. We are casting it as a Sprite so the compiler knows what kind of object it is.
addChild(currentPiece); //this will bring it to the top.
//setChildIndex(currentPiece, numChildren-1); //this would do the same as above
//swapChildren(currentPiece, getChildAt(numChildren-1); //this would do the same as above
currentPiece.startDrag(); //start dragging the piece that was clicked
//now listen for the mouse up event to stop dragging the piece
//we listen on the stage, as sometimes dragging can lag when moving the mouse quickly and the mouse may not be over the item when you release the button
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
function mouseUpHandler(e:Event):void {
//remove the mouse up listener
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
//stop the drag:
if(currentPiece) currentPiece.stopDrag();
//do something with currentPiece now that the drag is done.
//like make sure the piece is in a valid spot
//check if the puzzle is complete now
puzzleDone(); //let's say you call this function at some point
}
function puzzleDone():void {
currentPiece = null; //clear this var so objects can be garbage collected
//!important
//when you use setChildIndex, or AddChild, or SwapChildren
//or anything that modifies the parentage of a object
//that object will no longer be removed by timeline keyframes
//it will stick around until it's parent is removed, or you explicitly remove it.
//to that end, you'll want to manually remove your puzzle pieces when done
removeChild(Puz3_Level7A);
removeChild(Puz2_Level7A);
removeChild(Puz1_Level7A);
//you can use some of patterns below for this as well.
}
In regards to adding the mouse down listeners to all your puzzle pieces, here are some other options to scale better if you have a whole lot of pieces:
If the pieces are all FlashPro instance names, you could do this:
//loop three times
for(var i:int=1;i<=3;i++){
//get the child dynamically from the name (
var piece:DisplayObject = getChildByName("Puz" + i + "_Level7A");
if(piece){
piece.addEventListener(MouseEvent.MOUSE_DOWN, dragPuzzlePiece, false, 0, true);
}
}
If your puzzle pieces are the sole children of a common parent (let's say this code is on the timeline of that parent), you could do this:
//loop backwards through all children of this
var i:int = this.numChildren;
while(i--){
this.getChildAt(i).addEventListener(MouseEvent.MOUSE_DOWN, dragPuzzlePiece, false, 0, true);
}
If you have your pieces in an array:
var allPieces:Array = [Puz3_Level7A, Puz2_Level7A, Puz3_Level7A];
for(var i:int=0;i<allPieces.length;i++){
allPieces[i].addEventListener(MouseEvent.MOUSE_DOWN, dragPuzzlePiece, false, 0, true);
}

I upvoted #SameerJain's answer, it will do what you want. Taking it a little further, you can reduce all your repeated code with a simple function that makes your puzzle pieces draggable:
function makeDraggable(target:Sprite):void {
target.addEventListener(MouseEvent.MOUSE_DOWN, dragStart);
}
function dragStart(e:MouseEvent):void {
var target:Sprite = e.currentTarget as Sprite;
target.startDrag();
setChildIndex(target, numChildren - 1);
stage.addEventListener(MouseEvent.MOUSE_UP, dragEnd);
}
function dragEnd(e:MouseEvent):void {
stopDrag();
stage.removeEventListener(MouseEvent.MOUSE_UP, dragEnd);
}
makeDraggable(Puz3_Level7A);
makeDraggable(Puz2_Level7A);
makeDraggable(Puz1_Level7A);

Related

AS3 shuffling movieclips

I've added the basic targets and applying drag and drop for my puzzle pieces, now Im having trouble making the shuffling aspect. As in, after the player completes or opens up the fla, each time will start the puzzle pieces in random places of the stage. I understand using arrays for shuffling somehow but Im not sure exactly how to achieve this. I've stored the instance of my 19 puzzle pieces inside the array but now I have no idea what to do with this array. Other tutorials were abit out of my league and leaves my head scratching.
Just started doing coding for flash professional so yeah, any help with the shuffling movie clips ie the puzzles pieces would be greatly appreciated.
Heres's my code, Im not posting the whole thing since from P1 to P19 is basically copy pasting:
import flash.events.Event;
stage.addEventListener(Event.ENTER_FRAME, EntFrame)
function EntFrame(e: Event) : void
{
P1.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag);
function fl_ClickToDrag(event:MouseEvent):void
{
P1.startDrag();
}
stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop);
function fl_ReleaseToDrop(event:MouseEvent):void
{
P1.stopDrag();
}
if (T1.hitTestObject(P1.Tar1))
{
P1.x = 313.15;
P1.y = 242.75;
}
P19.addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag_19);
function fl_ClickToDrag_19(event:MouseEvent):void
{
P19.startDrag();
}
stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop_19);
function fl_ReleaseToDrop_19(event:MouseEvent):void
{
P19.stopDrag();
}
if (T19.hitTestObject(P19.Tar19))
{
P19.x = 624.35;
P19.y = 455.60;
}
}
Here is what I hope is more holistic answer.
First, ditch those inline functions. Right now you make an ENTER_FRAME listener and inside that function you have inline function defined. This means every frame tick (which is tied to your frame rate, not the main timeline), those functions are going to get created again, and since you are adding them as handlers for listeners, they will stay in memory forever.
Here is a way you code this, showing ways to reduce redundancy and get rid of those memory leaks. This assumes the following:
You have 19 objects on the stage called T1 - T19, that represent the possible locations the pieces can go.
You have 19 pieces on the stage called P1 - P19, that, and the numbers correlate to the T locations as per the correct location of the piece.
//let's create a function to randomize the piece location
function seedPieces() {
//create an array consisting of the integers 1 - 19
var unusedSpaces:Vector.<int> = new Vector.<int>;
var i:int;
for (i = 1; i <= 19; i++) {
//populate that array
unusedSpaces.push(i);
}
var curLocation:DisplayObject; //helper var for the loop below
var curPiece:Sprite; //helper var for the loop below
//loop 19 times (from 1 - 19) - one iteration for each piece
for (i = 1; i <= 19; i++) {
curPiece = this["P" + i] as Sprite; //you can get the piece this way, or use an array if you've made one, like `pieces[i];`
trace(curPiece.name);
//splice removes and returns the item at the specified index (in this case a random number between 0 and arrays length less 1) - the second parameter is amount of items to remove (just 1 for this case)
curLocation = this["T" + unusedSpaces.splice(int(Math.random() * unusedSpaces.length), 1)] as DisplayObject;
trace(" ",curLocation.name);
//move the piece to the random location:
curPiece.x = curLocation.x;
curPiece.y = curLocation.y;
}
}
//NOW, as an aside, you should use a loop to add all your listeners for the sake of sanity - if you have them in an array, loop through that, or use the sloppy way like this:
for (var i:int = 1; i <= 19; i++) {
Sprite(this["P" + i]).addEventListener(MouseEvent.MOUSE_DOWN, fl_ClickToDrag);
}
//create a var to hold any piece that is currently being dragged, so you know which piece to stop drag on later
var currentDraggingItem:Sprite;
seedPieces();
function fl_ClickToDrag(event:MouseEvent):void
{
//assign this clicked item to the currentDraggingItem var
currentDraggingItem = event.currentTarget as Sprite;
//bring this one to the front
currentDraggingItem.parent.addChild(currentDraggingItem);
//you can use this one click handler for all pieces
//the piece that was actually clicked, is referenced by event.currentTarget
currentDraggingItem.startDrag();
//add the mouse up listener now that the mouse is currently DOWN
stage.addEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop);
//listen every frame while dragging
stage.addEventListener(Event.ENTER_FRAME, EntFrame);
}
function fl_ReleaseToDrop(event:MouseEvent):void
{
//if currentDraggingItem has a value, stop drag it
if (currentDraggingItem) {
currentDraggingItem.stopDrag();
//send to the back
currentDraggingItem.parent.addChildAt(currentDraggingItem,0);
}
//remove the mouse up and enter frame listener now that the mouse is UP
stage.removeEventListener(MouseEvent.MOUSE_UP, fl_ReleaseToDrop);
stage.removeEventListener(Event.ENTER_FRAME, EntFrame);
if(checkComplete()){
//game over, do something
}
}
function EntFrame(e: Event) : void
{
//this will snap the peice to the correct spot when the mouse is touching the correct spot
if(currentDraggingItem){
if (this[currentDraggingItem.name.replace("P","T")].hitTestPoint(mouseX,mouseY))
{
currentDraggingItem.x = this[currentDraggingItem.name.replace("P","T")].x;
currentDraggingItem.y = this[currentDraggingItem.name.replace("P","T")].y;
}
}
}
function checkComplete():Boolean {
//use a loop to go through all your pieces and check if they are in the right spot. Again, you could have them in an array, or do it the lazy way
for (var i:int = 1; i <= 19; i++) {
if (!this["T"+i].hitTestObject(this["P"+i]))
{
return false;
}
}
return true;
}
Well, in general you can shuffle with the following code:
var shuffledVector:Vector.<someClass> = new Vector.<someClass>;
while (originalVector.length > 0) {
shuffledVector.push(originalVector.splice(Math.random() * originalVector.length, 1)[0]);
}
Longer, explained version:
var shuffledVector:Vector.<someClass> = new Vector.<someClass>; //We will store our shuffled vector in here
var randomIndex:int; //Random index from the originalVector
var resultVector:Vector.<someClass>; //result from the originalVector.splice(...) function
var randomElement:someClass; //Random element from the originalVector
while (originalVector.length > 0) { //We will reduce the size of the originalVector until the originalVector is empty.
randomIndex = Math.random() * originalVector.length; //Calculate a random index within the range of the originalVector from 0 to originalVector.lenght-1 (note that the range decreases by one on every loop)
randomVector = originalVector.splice(randomIndex, 1); //Use splice to remove one element at the randomly choosen index, we will receive a vector with the removed element...
randomElement = randomVector[0]; //...so we need to access the element
shuffledVector.push(randomElement); //Add the randomly choosen element to our shuffled vector
}
I've written the code for a vector as i suggest to use a vector instead of an array, but the principle behind it is the same for an array.
In your case the originalVector is a vector filled with your P1-P19 Movieclips and someClass would be MovieClip. The originalVector is empty at the end and could be replaced with the shuffled one and of course it would make a lot more sense if you put the code in a seperate function like this:
function Shuffle(originalVector:Vector.<someClass>) : void {
var shuffledVector:Vector.<someClass> = new Vector.<someClass>;
while (originalVector.length > 0) {
shuffledVector.push(originalVector.splice(Math.random() * originalVector.length, 1)[0]);
}
originalVector = shuffledVector;
}
Offtopic, but important for further coding: Someone else already mentioned, that it is not good to add EventListeners on every frame, because it is absolutely unnecessary. You only need to add the Listeners once. Your code is very repetitive, you should use a function which accepts a MovieClip, x and y then call that function 19 times.
e.g.:
function setUpMovieClip(MC:MovieClip, x:int, y:int) : {
MC.addEventListener(MouseEvent.MOUSE_DOWN, clickToDrag);
//more code...
}
within the clickToDrag function you can access the MovieClip which was clicked via the event.target property:
function clickToDrag(e:MouseEvent) : {
e.target.startDrag();
//more code...
}
I hope you get the idea.

EventListener AS3 problems reset problems

Hey guys I am having a problem with Event Listeners in my AS3 file. I am trying to make this object that lasts for 83 frames to appear in a different location every time the parent (83 frame) movie clip resets. The problem is I have a function that places the object at a random y value which works great once. When it resets the ojbect appears on the same Y point. This is because I removeEventListener the function otherwise the object goes shooting off the screen when it loads. How do I call that event listener again without causing a loop that will shoot the object off screen?
Here is my code:
import flash.events.Event;
stop();
addEventListener(Event.ENTER_FRAME, SeaWeedPostion);
//stage.addEventListener(Event.ADDED_TO_STAGE, SeaWeedPostion);
function SeaWeedPostion(e:Event):void{
// if(newSeaWeed == 1) {
var randUint:uint = uint(Math.random() *500 + 50);
this.seaweedSet.y += randUint;
trace(randUint);
stopPos();
//}else{
//nothing
// }
}
function stopPos():void{
removeEventListener(Event.ENTER_FRAME, SeaWeedPostion);
//var newSeaWeed = 0;
}
function resetSeaWeed():void{
addEventListener(Event.ENTER_FRAME, SeaWeedPostion);
}
I have some // code in there from trying different things.
Anyone have any suggestions?
Thanks!
ENTER_FRAME event is triggered every frame, so rather than changing position on each frame maybe it's better to create a counter, count frames and if it reaches 82 change position of SeaWeed.
var counter:uint = 0;
Now add ENTER_FRAME listener
addEventListener(Event.ENTER_FRAME, onEnterFrame);
function SeaWeedPostion(e:Event):void {
counter++;
//Are we there yet?
if(counter < 83) {
//Nope, carry on
}
else {
//Yey!
changePosition();
counter = 0;
}
}
//Reset SeaWeed position when called
function changePosition() {
var randUint:uint = uint(Math.random() *500 + 50);
this.seaweedSet.y += randUint;
trace(randUint);
}

how to remove a child object by removeChild()?

I'm trying to make a custom animated/shooter, from this tutorial: http://flashadvanced.com/creating-small-shooting-game-as3/
By custom, I mean customized, ie, my own version of it.
In it's actionscript, there's a timer event listener with function: timerHandler()
This function adds and removes child "star" objects on the stage (which the user has to shoot at):
if(starAdded){
removeChild(star);
}
and :
addChild(star);
Code works great, but error occurs on scene 2.
The code works great, and I even added some code while learning via google and stackflow to this flash file. I added Scene 2 to it too, and had it called after 9 seconds of movie time. But when it goes to Scene 2, it still displays the star objects and I've been unable to remove these "star" object(s) from Scene 2.
Here's the code I added:
SCENE 1:
var my_timer = new Timer(5000,0); //in milliseconds
my_timer.addEventListener(TimerEvent.TIMER, catchTimer);
my_timer.start();
var myInt:int = getTimer() * 0.001;
var startTime:int = getTimer();
var currentTime:int = getTimer();
var timeRunning:int = (currentTime - startTime) * 0.001; // this is how many seconds the game has been running.
demo_txt.text = timeRunning.toString();
function catchTimer(e:TimerEvent)
{
gotoAndPlay(1, "Scene 2");
}
SCENE 2:
addEventListener(Event.ENTER_FRAME,myFunction);
function myFunction(event:Event) {
timer.stop();
timer.removeEventListener(TimerEvent.TIMER, timerHandler);
stage.removeChild(star);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, cursorMoveHandler);
my_timer.stop(); // you might need to cast this into Timer object
my_timer.removeEventListener(TimerEvent.TIMER, catchTimer);
Mouse.show();
}
stop();
=====================================================
I'm quite new as3, and have just created an account on StackOverflow... even though I've known and read many codes on it since quite some time.
Here's the Edited New Complete Code:
//importing tween classes
import fl.transitions.easing.*;
import fl.transitions.Tween;
//hiding the cursor
Mouse.hide();
//creating a new Star instance
var star:Star = new Star();
var game:Game = new Game();
//creating the timer
var timer:Timer = new Timer(1000);
//we create variables for random X and Y positions
var randomX:Number;
var randomY:Number;
var t:int = 0;
//variable for the alpha tween effect
var tween:Tween;
//we check if a star instance is already added to the stage
var starAdded:Boolean = false;
//we count the points
var points:int = 0;
//adding event handler on mouse move
stage.addEventListener(MouseEvent.MOUSE_MOVE, cursorMoveHandler);
//adding event handler to the timer
timer.addEventListener(TimerEvent.TIMER, timerHandler);
//starting the timer
timer.start();
addChild(game);
function cursorMoveHandler(e:Event):void{
//sight position matches the mouse position
game.Sight.x = mouseX;
game.Sight.y = mouseY;
}
function timerHandler(e:TimerEvent):void{
//first we need to remove the star from the stage if already added
if(starAdded){
removeChild(star);
}
//positioning the star on a random position
randomX = Math.random()*500;
randomY = Math.random()*300;
star.x = randomX;
star.y = randomY;
//adding the star to the stage
addChild(star);
//changing our boolean value to true
starAdded = true;
//adding a mouse click handler to the star
star.addEventListener(MouseEvent.CLICK, clickHandler);
//animating the star's appearance
tween = new Tween(star, "alpha", Strong.easeOut, 0, 1, 3, true);
t++;
if(t>=5) {
gotoAndPlay(5);
}
}
function clickHandler(e:Event):void{
//when we click/shoot a star we increment the points
points ++;
//showing the result in the text field
points_txt.text = points.toString();
}
And on Frame 5 :
//timer.stop();
//timer.removeEventListener(TimerEvent.TIMER, timerHandler);
// uncomment lines above if "timer" is something you've made
stage.removeChild(star);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, cursorMoveHandler);
timer.stop(); // you might need to cast this into Timer object
timer.removeEventListener(TimerEvent.TIMER, timerHandler);
Mouse.show();
stop();
There's no Scene 2 now, in this new .fla file...
Here's a screenshot of the library property of my flash file...: http://i.imgur.com/d2cPyOx.jpg
You'd better drop scenes altogether, they are pretty much deprecated in AS3. Instead, use Game object that contains all the cursor, stars and other stuff that's inside the game, and instead of going with gotoAndPlay() do removeChild(game); addChild(scoreboard); where "scoreboard" is another container class that will display your score.
Regarding your code, you stop having a valid handle to stage that actually contains that star of yours, because your have changed the scene. So do all of this before calling gotoAndPlay() in your catchTimer function.
function catchTimer(e:TimerEvent)
{
//timer.stop();
//timer.removeEventListener(TimerEvent.TIMER, timerHandler);
// uncomment lines above if "timer" is something you've made
stage.removeChild(star);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, cursorMoveHandler);
my_timer.stop(); // you might need to cast this into Timer object
my_timer.removeEventListener(TimerEvent.TIMER, catchTimer);
Mouse.show();
gotoAndPlay(1, "Scene 2");
}
And the code for Scene 2 will consist of a single stop() - until you'll add something there. Also, there should be no event listeners, especially enter-frame, without a code to remove that listener! You add an enter-frame listener on Scene 2 and never remove it, while you need that code to only run once.
Use getChildAt.
function catchTimer(e:TimerEvent)
{
var childCount:int = this.numChildren - 1;
var i:int;
var tempObj:DisplayObject;
for (i = 0; i < childCount; i++)
{
tempObj = this.getChildAt(i);
this.removeChild(tempObj);
}
gotoAndPlay(1, "Scene 2");
}
This will remove all the children you added on scene 1 before going to scene 2.

Click event outside MovieClip in AS3

Is there any way to detect if the user click outside a MovieClip?
For instance, I need to detect it to close a previously opened menu (like Menu bar style: File, Edition, Tools, Help, etc).
How can I detect this kind of event? Thanks!
Add a listener to stage and check if stage is the target of the event.
Example of code here:
http://wonderfl.net/c/eFao
package
{
import flash.display.Sprite;
import flash.events.MouseEvent;
public class FlashTest extends Sprite
{
private var _menu : Sprite;
public function FlashTest()
{
_menu = new Sprite();
_menu.x = 100;
_menu.y = 100;
_menu.alpha = 0.5;
with(_menu.graphics)
{
beginFill(0xFF0000, 1);
drawRect(0, 0, 300, 300);
endFill();
}
addChild(_menu);
_menu.addEventListener(MouseEvent.CLICK, onClickHandler);
stage.addEventListener(MouseEvent.CLICK, onClickHandler);
}
private function onClickHandler(event : MouseEvent) : void
{
switch(event.target)
{
case _menu:
_menu.alpha = 0.5;
break;
case stage:
_menu.alpha = 1;
break;
}
}
}
}
You can add a listener to the click event of the root element:
MovieClip(root).addEventListener(MouseEvent.CLICK, clickObject);
then in the function clickObject, you can check to see what you are clicking.
function clickObject(e:Event):void
{
var hoverArray:Array = MovieClip(root).getObjectsUnderPoint(new Point(stage.mouseX, stage.mouseY));
var hoverOverObject:* = hoverArray[hoverArray.length - 1];
}
hoverOverObject references the element that you are clicking on. Often this will be the shape within the movie clip, so you'll need to look at it's parent then compare it to your movie clip. If the click wasn't on the drop down movie clip, trigger the close.
var container:MovieClip = new MovieClip();
var mc:MovieClip = new MovieClip();
with(mc.graphics){
beginFill(0xff0000,1);
drawCircle(0,0,30);
endFill();
}
mc.name = "my_mc";
container.addChild(mc);
addChild(container);
stage.addEventListener(MouseEvent.CLICK, action);
function action (e:MouseEvent):void
{
if(e.target.name != "my_mc"){
if(container.numChildren != 0)
{
container.removeChild(container.getChildByName("my_mc"));
}
}
}
Use capture phase:
button.addEventListener(MouseEvent.CLICK, button_mouseClickHandler);
button.stage.addEventListener(MouseEvent.CLICK, stage_mouseClickHandler, true);
//...
private function button_mouseClickHandler(event:MouseEvent):void
{
trace("Button CLICK");
}
private function stage_mouseClickHandler(event:MouseEvent):void
{
if (event.target == button)
return;
trace("Button CLICK_OUTSIDE");
}
Note that using stopPropagation() is good for one object, but failed for several. This approach works good for me.
Use a stage and a sprite (menu) click listener with the sprite listener executing first and apply the stopPropagation() method to the click handler of the sprite. Like this:
menu.addEventListener(MouseEvent.CLICK, handleMenuClick);
stage.addEventListener(MouseEvent.CLICK, handleStageClick);
private function handleMenuClick(e:MouseEvent):void{
// stop the event from propagating up to the stage
// so handleStageClick is never executed.
e.stopPropagation();
// note that stopPropagation() still allows the event
// to propagate to all children so if there are children
// within the menu overlay that need to respond to click
// events that still works.
}
private function handleStageClick(e:MouseEvent):void{
// put hide or destroy code here
}
The idea is that a mouse click anywhere creates a single MouseEvent.CLICK event that bubbles from the stage, down through all children to the target, then back up through the parents of the target to the stage. Here we interrupt this cycle when the target is the menu overlay by not allowing the event to propagate back up to the parent stage, ensuring that the handleStageClick() method is never invoked. The nice thing about this approach is that it is completely general. The stage can have many children underneath the overlay and the overlay can have its own children that can respond to clicks and it all works.

mouse up event not working properly

can anyone please help me on this.
attached is the fla which has a part of code i am working on for a project.
with help of mouse you can draw a circle on the image, but for some reasons the mouse up event does not work. it works fine when the eventlisteners is attached to the stage, but does not work when its attached to the movieclip.
also how can i restrict the circle to be drawn only inside the movieclip which is a rectangle.
here is the code
const CANVAS:Sprite = new Sprite();
var _dragging:Boolean = false;
var _corner:Point;
var _corner2:Point;
menFront.addEventListener(MouseEvent.MOUSE_DOWN, setAnchor);
menFront.addEventListener(MouseEvent.MOUSE_UP, completeRect);
function setAnchor(e:MouseEvent):void{
trace("mouse down");
if(!_dragging){
CANVAS.graphics.clear();
_corner = new Point(e.stageX, e.stageY);
_dragging = true;
menFront.addEventListener(MouseEvent.MOUSE_MOVE, liveDrag);
}
}
function completeRect(e:MouseEvent):void{
trace("mouse up");
if(_dragging){
_dragging = false;
menFront.removeEventListener(MouseEvent.MOUSE_MOVE, liveDrag);
CANVAS.graphics.lineStyle(0, 0, 0);
CANVAS.graphics.beginFill(0x222222,.5)
_corner2 = new Point(e.stageX, e.stageY);
trace(Point.distance(_corner,_corner2).toFixed(2));
CANVAS.graphics.drawCircle(_corner.x, _corner.y, Point.distance(_corner,_corner2));
addChild(CANVAS);
}
}
function liveDrag(e:MouseEvent):void{
CANVAS.graphics.clear();
CANVAS.graphics.lineStyle(0, 0x999999);
_corner2 = new Point(e.stageX, e.stageY);
//trace(Point.distance(_corner,_corner2).toFixed(2));
CANVAS.graphics.drawCircle(_corner.x, _corner.y, Point.distance(_corner,_corner2));
addChild(CANVAS);
}
If you add the MouseEvent.MOUSE_UP to the object that you are dragging, the event will only fire if the item is underneath the mouse at the moment the MOUSE_UP happens, but since you're updating the item with MOUSE_MOVE, that's a race-condition between when the MOUSE_UP happens and when the MOUSE_MOVE happens.
To avoid such problems you want to guarantee that you receive the MOUSE_UP whenever MOUSE_UP fires, during your live-update cycle. To do that, add the event listener to the stage just when it's needed, something like this:
menFront.addEventListener(MouseEvent.MOUSE_DOWN, setAnchor);
function setAnchor(event:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_UP, completeRect);
// your other functionality
}
function completeRect(event:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_UP, completeRect);
// your other functionality
}
so that your completeRect doesn't get called inadvertently if you're clicking elsewhere.
Hope This Helps