strange event time chronology in as3 - actionscript-3

I found something strange while I was coding today. I couldnot find explenation of what happend to me today.
I have created button and addEventListener to it.
private function drawButtons():void{
survivorModeBtn = new SurvivorModeBtn();
trace("I registered Event Listener with button here");
survivorModeBtn.addEventListener(MouseEvent.CLICK,onSurvivorModeBtnClick);
addChild(survivorModeBtn);
}
private function onSurvivorModeBtnClick(e:MouseEvent):void{
trace("I clicked on btn here");
//I will dispatch event here which runs second part of code
mainMenuViewEvent = new MainMenuViewEvent("onSurvivorModeIsClicked");
hideButtons();
dispatchEvent(mainMenuViewEvent);
}
Dispatched event will run those parts of code:
public function createClickToStart():void{
trace("here I register event listener MouseEvent.Click");
stage.addEventListener(MouseEvent.CLICK,onClick);
}
private function onClick(e:MouseEvent):void{
trace("onClick()");
}
When I run my program and Click on first button. I got this output in console:
I registered Event Listener with button here
I clicked on btn here
here I register event listener MouseEvent.Click
onClick()
I can t understand how can I see "onClick()" msg, if I clicked just on first button, and even in that time was not stage redistered with CLICK event.
Thank you for solution to my problem.

You have experienced what is called "bubbling" of an event. First, the "click" event is dispatched to the topmost object under cursor, then it raised upwards via parent references all the way to stage, if you don't force it to e.stopPropagation(). So, while the event was being parsed within survivorModeBtn, it has not yet reached stage, an in the meantime you ssign stage listener for this type of events. Then it bubbles up and hits stage, stage says "Wow, I have a MouseEvent.CLICK listener registered, let's call it right now!" and calls onClick() function, making you receive your last trace result.

Related

Flash ActionScript 3.0 button click over global MouseEvent.CLICK

I want do to the next one in flash with ActionScript 3.0:
Global event (if user click in any part of the screen by mouse):
addEventListener (MouseEvent.CLICK, nextc);
function nextc (event:MouseEvent): void
{nextFrame();}
Button event (if user click exact this button):
returnb54.addEventListener(MouseEvent.CLICK, returnb54a);
function returnb54a(event:MouseEvent):void
{prevFrame();}
But on the frame with this a global event and a button nothing happens when clicking the button.
Is there any way to prioritize button event over global?
Thank you.
I created a very simple application to test your question (I'm using the same names as you defined, to be easier to understand).
I have changed 3 points:
1-
this.stage.addEventListener (MouseEvent.CLICK, nextc);
2-
function returnb54a(event:MouseEvent):void
{
event.stopImmediatePropagation();
prevFrame();
}
3-
function nextc(event:MouseEvent): void
{
event.stopImmediatePropagation();
nextFrame();
}
The method: stopImmediatePropagation() prevents processing of any event listeners in the current node and any subsequent nodes in the event flow. This method takes effect immediately, and it affects event listeners in the current node. In contrast, the stopPropagation() method doesn't take effect until all the event listeners in the current node finish processing.
Try to implement these changes and see if will have the desired result.

Mouse Click vs Enter Frame Stage reference

I have a document class with some constructor code. I have two event listeners in the constructor. One of them is an enter frame listener and the other is a mouse click listener. The enter frame function moves a rectangle on the stage. The mouse event function removes it from the stage when its been clicked.
When I used the following:
addEventListener(MouseEvent.CLICK, checkTarget);
The rectangle didn't get removed. But when I used:
stage.addEventListener(MouseEvent.CLICK, checkTarget);
It worked fine. I kept the enter frame without referencing the stage and it worked.
addEventListener(Event.ENTER_FRAME,update);
Why did the mouse click need the reference to the stage and the enter frame didn't? Aren't they both added to the same thing at the same time?
mouse event needs something to work with but ENTER_FRAME is built to work with stage.
I would change the mouse event listener to listen to when you clicked at a mc just like that rectangle if I where you.

Navigation from frame 1 to frame 2 renders event listeners non-functional in flash/actionscript3

I am new to actionscript and flash, and I have been unable to find a good explanation for why I cannot get this pretty basic code to work. I am using flash cc with actionscript 3. I have two frames on my timeline, one labeled "startFrame" and another labeled "newFrame". In "startFrame", I have a button with the instance name "btnStart". There is an event listener that listens for a mouse click on btnStart and then calls a function that goes to the next frame. Here is the code for "startFrame":
stop();
//When "btnStart" button is clicked, call the beginSession function.
btnStart.addEventListener(MouseEvent.CLICK, beginSession);
function beginSession(event:MouseEvent):void
{
//Remove event listener??
//btnStart.removeEventListener(MouseEvent.CLICK, beginSession);
//Go to newFrame.
gotoAndStop("newFrame");
}
I thought initially I should remove the event listener in the function after it is called, but it doesn't seem to work whether I remove the event listener or not. Here I have it commented out. In the "newFrame" frame, I have an event listener that listens for a key press and then calls a function that returns the key and character codes for that given key. That code is here:
stop();
//show that newFrame has been reached.
trace("newFrame has been reached");
//Add event listener for a key press to the stage.
stage.addEventListener(KeyboardEvent.KEY_DOWN, reportKeyDown);
//function that returns the key pressed and the character code.
function reportKeyDown(event:KeyboardEvent):void
{
trace("Key Pressed: " + String.fromCharCode(event.charCode) + " (character code: " + event.keyCode + ")");
}
When I test the movie, the button press works and "newFrame" is reached (the "newFrame has been reached" trace is found in the output). But it does not seem that the event listener for the key press is working. However, if I create a project that only has "newFrame" by itself (no other frames in the timeline), it works just fine when I test the movie. Only after I add in the startFrame and the button navigation do the event listeners seem to no longer hear the key press event in the second frame. Also, I am not getting any compile errors. What am I missing here?
Disable keyboard shortcuts under view while testing the application.

AS3 MOUSE_LEAVE problem

I am coding a drag and drop application where I can grab an object and then place it over different object containers. When I am dragging the object (keeping the mouse button pressed) and I leave the stage, I can still control the object with the mouse...this is not what I want.
I would like to lose control of the object when the mouse leaves the stage.
I tried to remove the event listener for MOUSE_DOWN on a MOUSE_LEAVE event but nothing.
I also tried to dispatch a MOUSE_UP event on a MOUSE_LEAVE event but it does not work either...it works only if I manually release the mouse button.
Is there any way to override the MOUSE_DOWN event when the user moves the mouse away from the screen but he is still pressing the mouse button???
Any suggestion???
Thanks in advance
Is the stage actually listening to the MOUSE_LEAVE event? In any case , check this article, it may help:
http://www.kirupa.com/developer/flashcs3/detecting_when_mouse_leaves_movie.htm
Here's a couple tricky traps not to fall into :
One bizarre thing is that in Chrome + Firefox, the MOUSE_LEAVE event isn't dispatched for a WMODE of OPAQUE orTRANSPARENT. It just doesn't fire - mouse down or up.
With WINDOW it works fine. That one took me a long time to find out! grr... http://bugs.adobe.com/jira/browse/FP-892
Second, make sure you're using Event for the parameter type for your Event.MOUSE_LEAVE handler and not MouseEvent. If you try to handle MOUSE_LEAVE with e:MouseEvent you'll get an error that you may never see (unless you're using the debug flash player). It's a very easy mistake to make because you're probably pointing all your other handlers to the same method.
Here's what I do: (just call my main endDrag from mouseLeave(e:Event)
stage.addEventListener(MouseEvent.MOUSE_MOVE, drag);
stage.addEventListener(MouseEvent.MOUSE_UP, endDrag);
stage.addEventListener(Event.DEACTIVATE, endDrag);
stage.addEventListener(Event.MOUSE_LEAVE, mouseLeave);
private function mouseLeave(e:Event):void
{
endDrag(new MouseEvent("MOUSE_LEAVE"));
}
public function endDrag(evt:MouseEvent):void
{
/// handle end drag
}
I believe you are talking about the user leaving the flash content altogether with mouse clicked, and when he/she returns it continues the process right?
I suggest, you track the mouse x & y coordinates. Set a condition which triggers the mouse up event handler when the x or y is equal to the stage width or height respectively.
When you drag an object outside the flash movie, the object will fire a MOUSE_OUT event. You can listen to this event, use a variable to check if the object is being dragged, and, if so, dispatch a MOUSE_UP event.
some_object.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
some_object.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
some_object.addEventListener(MouseEvent.MOUSE_OUT, mouseOutHandler);
private function mouseOutHandler(e:MouseEvent):void
{
if (isDragging)
e.target.dispatchEvent(new MouseEvent(MouseEvent.MOUSE_UP));
}
private function mouseDownHandler(e:MouseEvent):void
{
e.target.startDrag();
isDragging = true;
}
private function mouseUpHandler(e:MouseEvent):void
{
e.target.stopDrag();
isDragging = false;
}

How do I get button up even when out of focus with actionscript 3.0?

I've been working on creating a button using a MovieClip. I'm using the following events:
this.addEventListener(MouseEvent.CLICK,OnClick);
this.addEventListener(MouseEvent.ROLL_OVER,OnButtonRollOver);
this.addEventListener(MouseEvent.ROLL_OUT,OnButtonRollOut);
this.addEventListener(MouseEvent.MOUSE_DOWN,OnMouseDown);
this.addEventListener(MouseEvent.MOUSE_UP,OnMouseUp);
Everything works fine with the exception of when I click the button and [without releasing the mouse button] I drag the mouse out of the button's focus and then I release the mouse button the OnMouseUp event is not called.
How can I fix this?
Thanks,
Y_Y.
Inside your OnMouseDown handler you can add the following to ensure you get the MouseEvent.MOUSE_UP event you desire:
private function OnMouseDown(e:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
}
private function onStageMouseUp(e:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_UP, onStageMouseUp);
// handle mouse up here
}
Of course this means you'll have to do some extra work to make sure handlers are being added/removed appropriately. You might also want to cache a reference to the target button in your OnMouseDown handler in the event the scenario you describe occurs and you still need to know which button was pressed (assuming your handlers are outside the scope of the button itself).