actionscript 3, removeEventListener not working properly - actionscript-3

I've made this game with event listener (coordinates) on mouse position when a click occurs (to move the character).
I've another event listener for drag and drop (to combine items) that works pretty well.
function stageDown (event:MouseEvent):void
{
stage.removeEventListener(MouseEvent.CLICK, coordinates);
MovieClip(getChildByName(event.target.name).toString()).startDrag();
MovieClip(getChildByName(event.target.name).toString()).addEventListener(MouseEvent.MOUSE_UP,stageUp);
...stuff..
}
function stageUp(event:MouseEvent):void
{
stopDrag();
...stuff...
stage.addEventListener(MouseEvent.CLICK, coordinates);
}
In the function stageDown I remove the event listener for the movement(coordinates), than I add it again at the end of the function stageUp (when you release the mouse button and the drag is complete)
But is not working, when I release the drag the character start moving, can't understand why

I don't fully understand the why (something to do with how Click events are tracked I suppose) but it is the 'normal' behavior.
Here is how I've handled this in the past. Basically you can add a higher priority click listener to the object you are dragging and cancel the event there: (see code comments)
//Assuming you have something like this in your code/////////
stage.addEventListener(MouseEvent.CLICK, coordinates);
function coordinates(event:MouseEvent):void {
trace("STAGE CLICK"); //whatever you do here
} ///////////////////////////////////////////////////////////
//add your mouse down listener to your object
someObject.addEventListener(MouseEvent.MOUSE_DOWN, stageDown);
//ALSO add a click listener to your object, and add it with higher priority than your stage mouse click listener
someObject.addEventListener(MouseEvent.CLICK, itemClick, false, 999);
function itemClick(event:MouseEvent):void {
//stop the event from reaching the lower priority stage mouse click handler
event.stopImmediatePropagation();
trace("Item CLICK");
}
function stageDown (event:MouseEvent):void
{
Sprite(event.currentTarget).startDrag();
//listen for the mouse up on the stage as sometimes when dragging very fast there is slight delay and the object may not be under the mouse
stage.addEventListener(MouseEvent.MOUSE_UP,stageUp, true);
//if you don't care about mouse up on stage, then you can just forget the mouse up listener and handler altogether and just stop drag on the itemClick function.
}
function stageUp(event:MouseEvent):void
{
//remove the stage mouse up listener
stage.removeEventListener(MouseEvent.MOUSE_UP,stageUp, true);
trace("UP");
stopDrag();
}

Related

Actionscript 3: Run function when mouse down is pressed, everyewhere else than on a listener?

I have an event listener for CLICK on a movie clip. It is very difficult to make a transparent listener behind the movie clip, because of how the stage is arranged. Is there a way I can run a function when you click anywhere else but the listener?
fash.addEventListener(MouseEvent.CLICK, fashRun);
See this API
stage.addEventListener(MouseEvent.CLICK, onClick);
function onClick(e:MouseEvent):void
{
if (!fash.hitTestPoint(stage.mouseX, stage.mouseY, true))
{
//todo
}
}

Getting Mouse Position on Event

I have two events; mouse up and down. I get the initial position of the mouse when left button down. Then I plan to get the last position of the mouse when button released. So if there is a horizontal movement I can easily recognise. However it is problematic. Since I add listener to a movie clip, it obtain mouse x in bounds of that movie clip. What I mean is if you release button outside of the movie clip it does not work because event attached to it. Are there any turnarounds here?
m_c.addEventListener(MouseEvent.MOUSE_DOWN, StartPoint);
m_c.addEventListener(MouseEvent.MOUSE_UP, EndPoint);
function StartPoint(event:MouseEvent):void
{
initX = stage.mouseX;
}
function EndPoint(event:MouseEvent):void
{
lastX = stage.mouseX;
trace("drop ", lastX);
if(lastX < initX)
{
trace("goes left");
.
.
.
}
}
you need to addListener to stage, preferable in listener of MOUSE_DOWN
function StartPoint(event: MouseEvent) : void {
stage.addEventListener(MouseEvent.MOUSE_UP, EndPoint);
// another code
}

Can any one explain this code how i use this in my application

I have a problem similar like this question but i'm not able to get understand this answer code, Can any one explain this code.
private function attachListeners():void
{
this.addEventListener(MouseEvent.MOUSE_DOWN, selfMouseDownHandler, false,0,true);
this.addEventListener(MoveEvent.MOVE, selfMoveHandler, false,0,true);
}
private function selfMoveHandler(event:MoveEvent):void
{
redrawConnectedLinks();
}
private function selfMouseDownHandler(event:MouseEvent):void
{
stage.addEventListener(MouseEvent.MOUSE_UP, stageMouseUpHandler, false,0,true);
stage.addEventListener(MouseEvent.MOUSE_MOVE, stageMouseMoveHandler, false,0,true);
}
private function stageMouseUpHandler(event:MouseEvent):void
{
stage.removeEventListener(MouseEvent.MOUSE_UP, stageMouseUpHandler, false);
stage.removeEventListener(MouseEvent.MOUSE_MOVE, stageMouseMoveHandler, false);
}
private function stageMouseMoveHandler(event:MouseEvent):void
{
dispatchEvent(new MoveEvent(MoveEvent.MOVE));
}
Please suggest me how to use this in flex application.
This code is tracking mouse movement by Flash's MouseEvent.MOUSE_UP, MouseEvent.MOUSE_MOVE and MouseEvent.MOUSE_DOWN.
Along with those events, the code is using a custom Event: MoveEvent.MOVE.
Any time, a MoveEvent.MOVE is being dispatched, the app would redraw the connectors. So, a listener to MoveEvent.MOVE is being added once and for all at the beginning.
Also, to track a drag, this code waits for MOUSE_DOWN and then keep on dispatching MoveEvent.MOVE for each MouseEvent.MOUSE_MOVE until a MOUSE_UP event occurs.
Now, let me associate the above explanation to the lines of code:
private function attachListeners():void
{
/*Wait for mouse down event to initiate mouse move and mouse up tracking*/
this.addEventListener(MouseEvent.MOUSE_DOWN, selfMouseDownHandler, false,0,true);
/*Always track MoveEvent.MOVE and start redrawing connectors whenever it's dispatched*/
this.addEventListener(MoveEvent.MOVE, selfMoveHandler, false,0,true);
}
private function selfMoveHandler(event:MoveEvent):void
{
/*Redraw connectors when the custom event MoveEvent.MOVE is received*/
redrawConnectedLinks();
}
private function selfMouseDownHandler(event:MouseEvent):void
{
/*Wait for mouse up event on receiving a mouse down*/
stage.addEventListener(MouseEvent.MOUSE_UP, stageMouseUpHandler, false,0,true);
/*Track mouse movement once mouse is down*/
stage.addEventListener(MouseEvent.MOUSE_MOVE, stageMouseMoveHandler, false,0,true);
}
private function stageMouseUpHandler(event:MouseEvent):void
{
/*Once mouse up happens stop tracking mouse up... */
stage.removeEventListener(MouseEvent.MOUSE_UP, stageMouseUpHandler, false);
/*Don't track mouse movement once mouse button gets released*/
stage.removeEventListener(MouseEvent.MOUSE_MOVE, stageMouseMoveHandler, false);
}
private function stageMouseMoveHandler(event:MouseEvent):void
{
/*dispatch MoveEvent.MOVE when mouse is moved.
If you read the above setup again, this should get dispatched on mouse moves
happening after a mouse down and before a mouse up
*/
dispatchEvent(new MoveEvent(MoveEvent.MOVE));
}
HTH.
Explanation of custom events as asked in the comment by OP
Custom events are useful to add custom message passing semantics. e.g. in this case, mouse drag is a detected by a series of mouse events, and once those events happen a custom event is dispatched to notify the connectors should be redrawn. Similarly, you might have a refresh button and clicking on it might dispatch the same event to force redraw.

Need to move this Object in one direction

I am trying to move this seatBelt object just on the horizontal plane. I have posted what I did so far. it's not really working out because it seems like once I press the button the seat belt is only able to move towards the right side and MOUSE_UP doesn't work. can somebody guide me on how to go about doing this?
seatBelt.addEventListener (MouseEvent.MOUSE_DOWN, prsing);
seatBelt.addEventListener (MouseEvent.MOUSE_UP, lfting);
seatBelt.addEventListener (MouseEvent.MOUSE_MOVE, mving);
function prsing (e:MouseEvent){
posX= seatBelt.x ;
posY = seatBelt.y ;
mouseclick = 1;
}
function mving (e:MouseEvent) {
if (mouseclick == 1) {
seatBelt.x = mouseX ;
}
}
function lfting (e:MouseEvent){
seatBelt.x = posX;
seatBelt.y = posY;
mouseclick =0;
}
So your intended functionality is to be able to drag the seatBelt along the x-axis and on release for it to go back to its original position?
You need to change the MOUSE_UP and MOUSE_MOVE to listen to the stage rather than the seatBelt. This is because it is possible for you to release the button when it is no longer over the seatBelt and so the function never gets called. The stage however will receive the event.
stage.addEventListener(MouseEvent.MOUSE_UP, lifting);
stage.addEventListener(MouseEvent.MOUSE_MOVE, moving);
I am not sure where you are declaring the mouseX variable but if you are after dragging functionality alter the listener to:
function moving (e:MouseEvent) {
if (mouseclick == 1) {
seatBelt.x = e.stageX;
}
}
What you have mostly looks okay code-wise, except what I think is happening is that you are "mousing up" on the stage/somewhere off the seatBelt object. I'm guessing this as to make the object move you have it reacting to mouse moving...to which I am guessing you are moving the mouse all over the stage and off the seatbelt object at which point you are then releasing the mouse.
To check if this is the case, try releasing the mouse over your seatBelt object to see if your MOUSE_UP event does get triggered.
I'm guessing the behaviour you want is that you want to have the object stop moving at any point regardless of where the mouse is released. To do this, try adding the MOUSE_UP event listener to the stage:
this.stage.addEventListener (MouseEvent.MOUSE_UP, lfting);
Though, since you may not always want this listener to be active, perhaps only add it when the mouse is pressed down over the object by adding and removing the listener only as needed.
I've edited your code a bit to show what I mean and taken out the "mouseclick" boolean as it wouldn't really be needed to keep track of the mouse down/up event anymore:
seatBelt.addEventListener(MouseEvent.MOUSE_DOWN, prsing);
function prsing(e:MouseEvent){
posX= seatBelt.x ;
posY = seatBelt.y ;
this.stage.addEventListener(MouseEvent.MOUSE_MOVE, mving);
this.stage.addEventListener(MouseEvent.MOUSE_UP, lfting);
}
function mving(e:MouseEvent) {
seatBelt.x = mouseX;
}
function lfting(e:MouseEvent){
seatBelt.x = posX;
seatBelt.y = posY;
this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, mving);
this.stage.removeEventListener(MouseEvent.MOUSE_UP, lfting);
}
You can use the Sprite.startDrag method to do what you need. No MOUSE_MOVE listener is needed. Lookup the params if you need to: Sprite. I like to only have only one of the MOUSE_DOWN or MOUSE_UP listeners active at a time.
seatBelt.addEventListener (MouseEvent.MOUSE_DOWN, prsing);
function prsing (e:MouseEvent){
seatBelt.startDrag(false, new Rectangle(0,seatBelt.y,stage.width,seatBelt.y));
seatBelt.removeEventListener (MouseEvent.MOUSE_DOWN, prsing);
seatBelt.addEventListener (MouseEvent.MOUSE_UP, lfting);
}
function lfting (e:MouseEvent){
seatBelt.stopDrag();
seatBelt.addEventListener (MouseEvent.MOUSE_DOWN, prsing);
seatBelt.removeEventListener (MouseEvent.MOUSE_UP, lfting);
}

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