I've been fumbling with this issue for a bit. I've got a lovely little tooltip movieclip that follows the user's mouse for a few seconds before it removes itself. My problem is that if there is one already there I remove it, however, I cannot seem to remove the MOTION_FINISH event and it still fires and possibly deletes a new tooltip.
What I want is to essentially put in a line item such as var tween(smallhelp_panel).deleteAll();
I saw a tweenlight function killtweensof(mc); However I've used the tweens I've incorporated below throughout my 30k lines of AS3 code.
Here is my tooltip handler. I call it with a simple
Main_Warning("Please don't forget to save!",5);
My movieclip is a 'smallhelp_panel' and I check if it already exists and remove it. However, the alpha and MOTION_FINISH tweens still exist and cause issues with any new smallhelp_panels.
public function Main_Warning( the_text:String, myTimer:int = 4){
if(smallhelp_panel != null){
stage.removeChild( smallhelp_panel );
removeEventListener(Event.ENTER_FRAME, trackmouse);
smallhelp_panel = null;
}
smallhelp_panel = new small_help();
smallhelp_panel.name = "myWarning";
smallhelp_panel.x = mouseX - 50;
smallhelp_panel.y = mouseY + 15;
smallhelp_panel.helptext.text = the_text;
stage.addChild( smallhelp_panel );
addEventListener(Event.ENTER_FRAME, trackmouse);
var myTween:Tween;
myTween = new Tween(smallhelp_panel, "alpha", None.easeOut, 1, 0, myTimer, true);
tweenholder = myTween;
tweenArray.push(tweenholder);
myTween.addEventListener(TweenEvent.MOTION_FINISH, removeTween);
}
That is my Tooltip handler.
for reference purposes my tween remover is:
public function removeTween(e:TweenEvent = null):void{
e.target.removeEventListener(TweenEvent.MOTION_FINISH, removeTween);
if(smallhelp_panel != null){
removeEventListener(Event.ENTER_FRAME, trackmouse);
stage.removeChild( smallhelp_panel );
smallhelp_panel = null;
}
}
and my mouse tracker that moves the tooltip with the mouse is a simple:
public function trackmouse(e:Event):void{
smallhelp_panel.x = mouseX - 50;
smallhelp_panel.y = mouseY + 15;
}
That's because you've added your MOTION_FINISH event listener to the tween, not to the panel. You remove the panel, if one already exists, but the tween still exists in the tweenholder and tweenArray variables - and fires a MOTION_FINISH event, when its calculations are finished. Your event listener method doesn't know which tween the event came from, and correctly removes the help panel.
To fix this, either remove the tween and event listener along with the help panel in your Main_Warning function, or modify the removal block in your event listener method:
public function removeTween(e:TweenEvent = null):void{
e.target.removeEventListener(TweenEvent.MOTION_FINISH, removeTween);
// --- this will check if the Tween belongs to the panel on the stage!
if (smallhelp_panel && e.target.obj == smallhelp_panel ) {
// ---
removeEventListener(Event.ENTER_FRAME, trackmouse);
stage.removeChild( smallhelp_panel );
smallhelp_panel = null;
}
// --- NOW remove the tween from the array (all of them should be removed after use)
tweenArray.splice (tweenArray.indexOf (e.target), 1);
}
I don't understand exactly why you would need both a tweenholder and a tweenArray variable, though ;)
Your TweenEvent is still being listened for. You never remove the previous listener, so it will fire when the tween calculations are complete.
I assume tweenholder is declared somewhere global? (Like the other answer here, I'm confused as to your need of declaring a new tween, storing it in another reference and adding that reference to an array...) If so, try this:
public function Main_Warning( the_text:String, myTimer:int = 4){
tweenholder.removeEventListener(TweenEvent.MOTION_FINISH,removeTween);
if(smallhelp_panel != null){
...
Related
I have a dropdown menu that lets you select an item to be placed on the stage. The item is drag and droppable so I use event.currentTarget.startDrag(); to start the drag. Ok, everything works fine so far.
However, I also need to be able to rotate the item while it is being dragged (using the spacebar).
stage.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDown);
function myKeyDown(e:KeyboardEvent):void{
if (e.keyCode == Keyboard.SPACE){
rotate++;
if (rotate == 5){
rotate = 1;
}
WHATGOESHERE?.gotoAndStop(rotate);
}
If I hardcode in an instance name of an object everything works fine - so the rotate function is working properly. The problem is, how can I reference event.currentTarget from the startDrag function while inside of the keyDown event?
My first thought was to set event.currentTarget to a variable and then calling the variable from within the keyDown event. However, targetHold = event.currentTarget; does not seem to record the instance name of the object being clicked...
public var targetHold:Object = new Object;
function ClickToDrag(event:MouseEvent):void {
event.currentTarget.startDrag();
targetHold = event.currentTarget;
trace ("targetHold " + targetHold);
stage.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDown);
function myKeyDown(e:KeyboardEvent):void{
if (e.keyCode == Keyboard.SPACE){
rotate++;
if (rotate == 5){
rotate = 1;
}
targetHold.gotoAndStop(rotate); //does not work
}
}
function ReleaseToDrop(event:MouseEvent):void {
event.currentTarget.stopDrag();
}
As you click the object, it should have focus. If you register the listener for the KeyboardEvent on the object and not on the stage, it will be .currentTarget.
Here's an example of what I have in mind. Right after starting the drag, add the listener to the same object instead of the stage.
event.currentTarget.startDrag();
event.currentTarget.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDown);
The proper way of doing this would be to define all the functionality in a class. Within a self contained class, you would not need any .currentTarget.
Here is how I would do this: (well, actually I'd follow #null's advice and encapsulate it in a sub class that all your dragable objects would extend, but that is a little broad so this will do)
public var targetHold:MovieClip; //don't make a new object, just create the empty var
public function YourConstructor(){
//your other constructor code
stage.addEventListener(KeyboardEvent.KEY_DOWN, myKeyDown); //don't add the listener in the click function
}
private function clickToDrag(event:MouseEvent):void {
if(targetHold) ReleaseToDrop(null); //safeguard in case flash lost the focus during the mouse up
targetHold = event.currentTarget as MovieClip; //assign the current target. Might as well cast it as MovieClip and get code completion benefits
targetHold.startDrag();
trace ("targetHold " + targetHold);
}
private function myKeyDown(e:KeyboardEvent):void{
//check if target hold exists
if (targetHold != null && e.keyCode == Keyboard.SPACE){
rotate++;
if (rotate == 5){
rotate = 1;
}
targetHold.gotoAndStop(rotate);
}
}
private function ReleaseToDrop(event:MouseEvent):void {
if(targetHold) targetHold.stopDrag();
targetHold = null;
}
I am new to ActionScript and was following the tutorial here to get me started using FlashDevelop. I set it up to move the item every KEY_DOWN event instead of using the frame event but my KEY_DOWN event is never fired. I quickly added a MOUSE_DOWN event to test the extent of the problem which works.
I am adding the listeners as my Paddle (an extension of Sprite) item is added to the stage:
private function addedToStage(e:Event) : void {
// Remove this event listener
removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
// Add the picture
addChild(pic);
// Set the location of the item in the middle of the screen one
// height length of the image down.
this.y = this.height;
this.x = (this.stage.stageWidth - this.width) / 2;
// Add the keyboard listener (broken).
stage.addEventListener(KeyboardEvent.KEY_DOWN, this.keyDownHandler, false, 0, true);
// Add the mouse listener (works).
stage.addEventListener(MouseEvent.MOUSE_DOWN, this.mouseDown, false, 0, true);
// Set the focus to the stage.
stage.focus = stage;
}
I have a breakpoint in my keyDownHandler function and it is never called.
This may be a duplicate of this question, but I am already doing what the answer in that question describes and in the comments he explains that he does not know what fixed the problem only that it suddenly started working.
Another popular answer to that question mentions this article which is why there is a line in my code to set the focus back to the stage. There is nothing else on my stage.
What could be happening?
Edit:
Here is my listener code:
private function keyDownHandler(e:KeyboardEvent):void {
var increment:Number; // Here is my breakpoint
if (e.keyCode == 65 || e.keyCode == 37) {
increment = -5;
} else if(e.keyCode == 68 || e.keyCode == 39) {
increment = 5;
}
var newX:Number = this.x + 5;
if (newX > 0 && newX + this.width < this.stage.width) {
this.x = newX;
}
}
The problem was unrelated to the event itself, but rather how I was testing to see if it fired. You cannot place breakpoints on declarations.
FlashDevelop will allow you to set a breakpoint there but the debugger will not actually stop at this point.
The code to move the paddle does not work (not surprising to me at this point), but if I move the breakpoint to the line in the if statement (or any other line when an actual action performed such as the trace) suddenly it breaks fine. Now that I think about it even the other languages I've worked with have this behavior, I'm just too pampered by IDE's that will move the breakpoint to the nearest available line in such situations.
I'm new to AS3 and have made a simple "asteroids" game with a game over screen and a resetButton that lets the user play again. When the user clicks on the reset button, the game over screen and the reset button are removed from the stage, and the game proper is added to the stage, along with eventListeners. One of these is a MouseEvent.CLICK listener added to the stage, which calls a fireBullet function. This function draws a bullet and adds it to the stage (other parts of the code then make the bullet move on the screen).
The issue that I am having is that when the user clicks on the reset button, the gameover screen is removed correctly, and the game proper (player, asteroids, eventListeners) are added to the stage correctly, but also at the same time a bullet fires even though the user has not clicked after clicking on the reset button.
My gameOver() function is like this:
stage.removeChild() all objects
stage.removeEventListener() all listeners
null out all objects
draw and add to the stage the game over text and resetButton
addEventListener(MouseEvent.CLICK, onReset) to the resetButton
Then, the onReset() function looks like this:
stage.removeChild() the gameover text and the resetButton
call gameStart();
The gameStart() function looks like this:
initialize variables
draw and add player and asteroids on the screen
add eventListeners including MouseEvent.Click, fireBullet
I've added traces at each function to see what's going on, and this is the flow:
added fireBullet listener //this is gameStart() function being called from Main() and adding everything to the stage the first time
fired bullet //shooting at the asteroids
fired bullet
fired bullet
fireBullet listener should have been removed //this is gameOver() being called that removes everything from the stage and adds the resetButton
clicked on reset
added fireBullet listener //gameStart() being called again from onReset() function
fired bullet //I did not click a second time after clicking on reset
I've read somewhere that events are dispatched all the time regardless if any listeners are actually listening for them, so my suspicion is that my MouseEvent.CLICK listener is picking up the mouse button click from the time when the reset button is clicked, even though this listener is added to the stage afterwards.
I don't have enough experience with AS3 or programming to figure out if this is really the case and what can I do to make sure that the MouseEvent.CLICK listener does not respond to any clicks that happened before it was added to the stage, so any help with this would be greatly appreciated.
====
EDIT
I was assuming I had a logic problem or didn't know something about AS3 and flash, so I just used pseudo code above. Below is a link to the full .as file including the generated .swf
And below that are the relevant functions in full
https://www.dropbox.com/sh/a4rlasq8o0taw82/wP3rB6KPKS
private function startGame():void this is called from Main
{
//initialize variables
bulletArray = [];
cleanupBullets = [];
bulletSpeed = 10;
score = 0;
asteroid1Speed = 0;
asteroid2Speed = 0;
asteroid3Speed = 0;
asteroid4Speed = 0;
//draw player and asteroids
ship = drawPlayer();
asteroid1 = drawAsteroid();
asteroid2 = drawAsteroid();
asteroid3 = drawAsteroid();
asteroid4 = drawAsteroid();
//embarrasing and inefficient code to get random number between -5 and 5 without a 0
asteroid1Speed = Math.ceil(Math.random() * 10 -5);
if (asteroid1Speed == 0)
asteroid1Speed = returnNonZero(asteroid1Speed);
asteroid2Speed = Math.ceil(Math.random() * 10 -5);
if (asteroid2Speed == 0)
asteroid2Speed = returnNonZero(asteroid2Speed);
asteroid3Speed = Math.ceil(Math.random() * 10 -5);
if (asteroid3Speed == 0)
asteroid3Speed = returnNonZero(asteroid3Speed);
asteroid4Speed = Math.ceil(Math.random() * 10 -5);
if (asteroid4Speed == 0)
asteroid4Speed = returnNonZero(asteroid4Speed);
//trace(asteroid1Speed, asteroid2Speed, asteroid3Speed, asteroid4Speed);
//add asteroids to stage
stage.addChild(asteroid1);
stage.addChild(asteroid2);
stage.addChild(asteroid3);
stage.addChild(asteroid4);
//position player and add to stage
ship.x = 40;
ship.y = 40;
stage.addChild(ship);
//add event listeners
stage.addEventListener(Event.ENTER_FRAME, onFrame);
stage.addEventListener(MouseEvent.CLICK, fireBullet);
trace("added fireBullet listener");
}
private function gameOver():void this is called from an onFrame(called every frame) function that I am not including (it's too big and not exactly relevant). it's called when all asteroids are removed.
{
//remove any remaining bullets off the screen
for each (var item:Sprite in bulletArray)
{
stage.removeChild(item);
}
//null out objects and remove listeners
bulletArray = null;
stage.removeEventListener(Event.ENTER_FRAME, onFrame);
stage.removeEventListener(MouseEvent.CLICK, fireBullet);
//check if the listener has actually been removed
if (!(stage.hasEventListener(MouseEvent.CLICK))) {
trace("fireBullet listener should have been removed");
}
stage.removeChild(ship);
ship = null
//graphic for resetButton
resetButton = new Sprite();
resetButton.graphics.beginFill(0xFFFFFF);
resetButton.graphics.drawRect(0, 0, 100, 50);
resetButton.graphics.endFill();
//position for resetButton
resetButton.x = 250;
resetButton.y = 300;
//text for resetButton
resetTextField = new TextField();
var resetTextFormat:TextFormat = new TextFormat();
resetTextFormat.size = 30;
resetTextFormat.color = 0x000000;
resetTextField.defaultTextFormat = resetTextFormat;
resetTextField.selectable = false;
resetTextField.text = "RESET";
resetButton.addChild(resetTextField);
//add resetButton and listener
stage.addChild(resetButton);
resetButton.addEventListener(MouseEvent.CLICK, onReset);
//gameover text
gameOverTxtField = new TextField();
gameOverFormat = new TextFormat();
gameOverFormat.size = 50;
gameOverFormat.color = 0xFFFFFF;
gameOverFormat.align = "center";
gameOverTxtField.defaultTextFormat = gameOverFormat;
gameOverTxtField.selectable = false;
gameOverTxtField.text = "GAME OVER";
gameOverTxtField.width = 660;
gameOverTxtField.height = 200;
gameOverTxtField.x = -10;
gameOverTxtField.y = 20;
stage.addChild(gameOverTxtField);
}
private function onReset(e:MouseEvent):void
{
trace("clicked on reset");
//remove gameover objects and null them
resetButton.removeEventListener(MouseEvent.CLICK, onReset);
stage.removeChild(gameOverTxtField);
stage.removeChild(resetButton);
resetButton = null;
gameOverTxtField = null;
//restart the game
startGame();
}
What's happening is that MouseEvent.CLICK is a bubbling event. In Flash, events have three phases: the "capture phase", the "at target" phase, and "bubbling phase". You can read about it in this Adobe article.
Your reset button's click event handler happens in the "at target" phase. If you trace out the event's phase in the reset button click handler, it will show that event.phase is 2. Per the docs, 1 = "capture phase", 2 = "at target", 3 = "bubbling phase".
After the reset button click handler does its work, the event then bubbles back up through the display list. Since the stage is at the top of the display list, the click event "bubbles up" to the stage. And by that time, you've started the game again and added the stage's click event handler. So the stage's click handler is also triggered.
You can confirm this by tracing out the value of event.phase in your bulletFired() method:
private function fireBullet(e:MouseEvent):void
{
// most of this time it will trace out 2 for the phase
// except when you click on an asteroid when firing or
// click the reset button
trace("fired bullet, event phase: " + e.eventPhase);
bullet = drawBullet();
bullet.y = ship.y;
bullet.x = ship.x + (ship.width / 2);
bulletArray.push(bullet);
stage.addChild(bullet);
}
To fix the problem, you can stop the event from bubbling in your onReset() method:
private function onReset(e:MouseEvent):void
{
// prevent this event from bubbling
e.stopPropagation();
trace("clicked on reset");
//remove gameover objects and null them
resetButton.removeEventListener(MouseEvent.CLICK, onReset);
stage.removeChild(gameOverTxtField);
stage.removeChild(resetButton);
resetButton = null;
gameOverTxtField = null;
//restart the game
startGame();
}
It sounds to me like the previous iteration of your game has not had the MOUSE.CLICK event listener removed. Even if the game is removed, the MOUSE.CLICK event will continue triggering whatever handler you added to it, eg; addEventListener(MOUSE.ClICK, ). When the game is removed you also need to removeEventListener(MOUSE.CLICK, ).
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.
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