AS3 MOUSE_LEAVE problem - actionscript-3

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;
}

Related

Stopping user drawing by double click? As3

I'm making this game in flash in which I want the user to draw straight lines (to create an unclosed shape) and I want to stop drawing the lines by double clicking.
My drawing board is a movie clip (not the stage).
I've put the double click event listener on the board and also added the doubleClickEnabled = true to the board.
However, no matter what I do, the board won't recognise my double click.
The click event gets triggered when there is some clickable entity at the event location. In other words, by for example, "double clicking" on a "transparent" region in your "drawing board", the associated event handler will not be called.
As a solution to the issue, however, you may utilize the stage object, since it occupies the entire display area; thus receives the mouse events anyways. The idea is to let the stage's event handler to inform the drawing-board's counterpart about the event occurrence:
board.doubleClickEnabled = true;
board.addEventListener(MouseEvent.DOUBLE_CLICK, onBoardDBLClick);
stage.doubleClickEnabled = true;
stage.addEventListener(MouseEvent.DOUBLE_CLICK, onStageDBLClick);
function onStageDBLClick(e:MouseEvent):void {
trace("STAGE double clicked.");
// if the location is inside the "board", then inform the "board" about the event!
if (board.getBounds(stage).contains(e.stageX, e.stageY)) {
onBoardDBLClick(e);
}
}
function onBoardDBLClick(e:MouseEvent):void {
trace("The Double-click logic of the board.");
e.stopPropagation();
}

Touch events in game object

In my Starling game, the player sprite is controlled by clicking the screen where you want to go. Since (AFAIK) you can't have touch events that happen outside a sprite activate handlers in the sprite, I put the handlers in the game object. Here's a basic idea of how it goes:
To create my listener, I do this within my game object:
this.addEventListener(TouchEvent.TOUCH, onTouch);
But onTouch is never called (I even tried putting a trace() in there).
Am I missing something here?
Well, you can make events that happen outside of a sprite to trigger the sprite's handlers, for this, you attach listeners not to the sprite, but to some other object, usually stage. Check if the stage is available, though. The best way to handle stage present is a listener to ADDED_TO_STAGE event. You put that into your handler object's constructor, and put all stage-aware code into that listener.
public function Handler() {
if (stage) init(null);
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
// entry point. This is where should stage-aware code start
stage.addEventListener(TouchEvent.TOUCH, onTouch);
// at this point stage is populated and valid, thus we can use stage reference
// without fear of null pointer.
}

Checking if Mouse Click was not in a MovieClip

I have number of movieClips on stage, with each having it's own Event Listener. Once Click/Touch the event is called each movie clip does something. For example one movieClip makes about 6 other movie clips visible.
What I want to do is, when the user Touch/Click somewhere else on stage, where there is no movieClip I want to know, so I can perform some actions such as make some movieClips invisible.
P.S the reason why I say Touch/Click is I'm developing this app for Android, however to make testing easier I'm currently testing everything in PC with MouseEvent, rather than TouchEvent. Once I get all the features working, I will switch over to TouchEvent and test it in mobile.
Many Thanks,
Mike
Add event listener to the stage. And in the event handlers of your inner movieclips use event.stopPropagation function to prevent bubble event to the container.
I would just do a check, it's simple and quick and doesn't require adding code to alter propagation.
import flash.events.MouseEvent;
stage.addEventListener(MouseEvent.CLICK, onClick, false, 0, true);
function onClick(e:MouseEvent):void
{
if(e.target == stage)
{
trace("click click");
}
}

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).

stage Event.ENTER_FRAME vs. CREATION_COMPLETE

I've got an AS3 project that I'm building in FlexBuilder.
In my main class's constructor, I've got this:
stage.addEventListener(Event.ENTER_FRAME, stage_enterFrameHandler);
And then the event handler function:
private var tempCounter:uint = 0;
private function stage_enterFrameHandler(event:Event):void
{
stage.removeEventListener(Event.ENTER_FRAME, stage_enterFrameHandler);
tempCounter += 1;
trace(tempCounter);
}
When I run in debug mode, tempCounter writes out once, as 1. Why is this? I though the whole point of Event.ENTER_FRAME is that it keeps firing.
The documentation says:
If the playhead is not moving, or if there is only one frame, this event is dispatched continuously in conjunction with the frame rate. This event is dispatched simultaneously to all display objects listening for this event.
So why would I not see that counter incrementing about 30x a second (which is what I have the frame rate set to)?
EDIT NOTE:
OK, well, doh, I've figured it out. It's because I immediately remove the eventlistener. The ENTER_FRAME event does keep firing... The only reason the code is done this way (code I inherited) is, I suppose, that CREATION_COMPLETE isn't available if you aren't using the flex framework.
The answer is simple as soon as enter in your enter frame you are removing the listener so the next time the enter frame event occured there is no one to react to it.
remove the line
stage.removeEventListener(Event.ENTER_FRAME, stage_enterFrameHandler);