Mouse_leave cannot make movieclip snap back - actionscript-3

I am trying to make a small drag and drop application in flash , i have been able to achieve the following -
1)Drag the movie clips
2)Make sure that two movieclips do not interchange positions when put over each other
3)Make sure the MC that is being dragged stays on top of other movieclips ..
4)Make the movieclip stay when its dropped at designated position
However there is one very important thing i am unable to achieve , when the cursor moves out of stage , the movie clips gets stuck to the cursor , i want that the moment the user goes out of stage the clip that is being dragged goes back to its original position ...
I have tried using the mouse_leave option for this but it does not work...
I am adding the code for drag and drop as below , please guide me here -
Drag Code -
Array to hold the target instances, the drop instances,
and the start positions of the drop instances.
var hitArray:Array = new Array(hitTarget1,hitTarget2,hitTarget3);
var dropArray:Array = new Array(drop1,drop2,drop3);
var positionsArray:Array = new Array();
This adds the mouse down and up listener to the drop instances
and add the starting x and y positions of the drop instances
into the array.
for (var i:int = 0; i < dropArray.length; i++) {
dropArray[i].buttonMode = true;
dropArray[i].addEventListener(MouseEvent.MOUSE_DOWN, mdown);
dropArray[i].addEventListener(MouseEvent.MOUSE_UP, mUp);
positionsArray.push({xPos:dropArray[i].x, yPos:dropArray[i].y});
}
This drags the object that has been selected and moves it
to the top of the display list. This means you can't drag
this object underneath anything.
function mdown(e:MouseEvent):void {
e.currentTarget.startDrag();
setChildIndex(MovieClip(e.currentTarget), numChildren - 1);
}
And here is the drop code
This stops the dragging of the selected object when the mouse is
released. If the object is dropped on the corresponding target
then it get set to the x and y position of the target. Otherwise
it returns to the original position.
function mUp(e:MouseEvent):void {
var dropIndex:int = dropArray.indexOf(e.currentTarget);
var target:MovieClip = e.currentTarget as MovieClip;
target.stopDrag();
if (target.hitTestObject(hitArray[dropIndex])) {
target.x = hitArray[dropIndex].x;
target.y = hitArray[dropIndex].y;
}else{
target.x = positionsArray[dropIndex].xPos;
target.y = positionsArray[dropIndex].yPos;
}
}
Please tell me how to use mouse_leave here and make the snap back,
used it in the both drag and drop section like this below
stage.addEventListener(Event.MOUSE_LEAVE, mouseLeave);
but always get some error like stage does not support property x etc. i add some code like equating the x and y but it does not work .. please guide
Jin

MOUSE_LEAVE shows if we are in or out of the stage, but doesn't detect the position of the mouse. You have to collect mouse's data on MOUSE_DOWN, to restrict the instance into the limits.
const LL:uint = 0;
const LT:uint = 0;
const LR:uint = stage.stageWidth;
const LB:uint = stage.stageHeight;
function EnterFrame(e:Event):void {
e.target.x = mouseX;
e.target.y = mouseY;
if (mouseX < LL) {e.target.x = LL;} else if (mouseX > LR) {e.target.x = LR;}
if (mouseY < LT) {e.target.y = LT;} else if (mouseY > LB) {e.target.y = LB;}
}
In your function 'mdown':
e.currentTarget.addEventListener(Event.ENTER_FRAME, EnterFrame);
In your function 'mUp':
target.removeEventListener(Event.ENTER_FRAME, EnterFrame);
General method
Here is the way this can be done. On MOUSE_UP outside the limits, the target is [object stage]. So you have to create a variable __last that will make you recognize the instance (p1 or another) clicked on MOUSE_DOWN. StartDrag() isn't needed:
const LL:uint = 0;
const LT:uint = 0;
const LR:uint = stage.stageWidth;
const LB:uint = stage.stageHeight;
function EnterFrame(e:Event):void {
e.target.x = mouseX;
e.target.y = mouseY;
if (mouseX < LL) {e.target.x = LL;} else if (mouseX > LR) {e.target.x = LR;}
if (mouseY < LT) {e.target.y = LT;} else if (mouseY > LB) {e.target.y = LB;}
}
var __last:*;
p1.addEventListener(MouseEvent.MOUSE_DOWN, OnMouseDown);
function OnMouseDown(e:MouseEvent):void {
__last = MovieClip(e.target);
__last.addEventListener(Event.ENTER_FRAME, EnterFrame);
}
this.stage.addEventListener(MouseEvent.MOUSE_UP, OnMouseUp);
function OnMouseUp(e:MouseEvent):void {
if(__last) __last.removeEventListener(Event.ENTER_FRAME, EnterFrame);
}
To snap it back to original position
const LL:uint = 0;
const LT:uint = 0;
const LR:uint = stage.stageWidth;
const LB:uint = stage.stageHeight;
var __last:*;
var dropIndex:int;
function EnterFrame(e:Event):void {
if (mouseX < LL || mouseX > LR || mouseY < LT || mouseY > LB) {
__last.x = positionsArray[dropIndex].xPos;
__last.y = positionsArray[dropIndex].yPos;
__last.stopDrag();
}
}
var hitArray:Array = new Array(hitTarget1, hitTarget2, hitTarget3);
var dropArray:Array = new Array(drop1, drop2, drop3);
var positionsArray:Array = [];
for (var i:int = 0; i < dropArray.length; i++) {
dropArray[i].buttonMode = true;
dropArray[i].addEventListener(MouseEvent.MOUSE_DOWN, mdown);
dropArray[i].addEventListener(MouseEvent.MOUSE_UP, mUp);
positionsArray.push({xPos:dropArray[i].x, yPos:dropArray[i].y});
}
function mdown(e:MouseEvent):void {
__last = e.currentTarget;
dropIndex = dropArray.indexOf(__last);
setChildIndex(MovieClip(__last), numChildren - 1);
__last.startDrag();
addEventListener(Event.ENTER_FRAME, EnterFrame);
}
function mUp(e:MouseEvent):void {
if (__last.hitTestObject(hitArray[dropIndex])) {
__last.x = hitArray[dropIndex].x;
__last.y = hitArray[dropIndex].y;
} else {
__last.x = positionsArray[dropIndex].xPos;
__last.y = positionsArray[dropIndex].yPos;
}
__last.stopDrag();
removeEventListener(Event.ENTER_FRAME, EnterFrame);
}

Related

How to stop player from walking on walls

I'm building a test avatar chat... thingy in ActionScript3, but I've come across a problem, whenever I click the chatbar to say something, my avatar (which is currently a penguin) walks to it -- how can I prevent this from happening? In other words, how do I build a wall and keep the penguins out?
This is the code I'm using to make my penguin move.
stage.addEventListener(MouseEvent.CLICK, myClickReaction);
// speeds ALONG NYPOTENUSE
var v:Number = 7;
// vector of movement
var dir:int = 100;
// mouse click point
var clickPoint:Point = new Point();
// angle doesn't change metween clicks - so it can be global
var angle:Number;
function myClickReaction (e:MouseEvent):void {
clickPoint = new Point(mouseX, mouseY);
angle = Math.atan2(clickPoint.y - penguin.y, clickPoint.x - penguin.x);
dir = angle >= 0 ? -1 : 1;
addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
function onEnterFrame(e:Event):void {
var projectedX:Number = penguin.x + v * Math.cos(angle);
var projectedY:Number = penguin.y + v * Math.sin(angle);
var diff:Number = clickPoint.y - projectedY;
if (diff / Math.abs(diff) == dir) {
penguin.x = clickPoint.x;
penguin.y = clickPoint.y;
removeEventListener(Event.ENTER_FRAME, onEnterFrame);
}
else {
penguin.x = projectedX;
penguin.y = projectedY;
}
}

Applying Drag, Snap Back Into Original Position To An Array

I am attempting to drag a movie clip and then have it snap back into its original position after being released. I want to apply this functioniality to an array with actionscript3. Here is the code so far:
var dragArray:Array = new Array;
dragArray.push(blockSmalla);
dragArray.push(blockSmallb);
dragArray.push(blockSmallc);
dragArray.push(blockSmalld);
dragArray.push(blockSmalle);
var startPosition:Point;
function drag(e:Event):void {
dragArray[i].startDrag();
startPosition = new Point( dragArray[i].x, dragArray[i].y);
}
function dragStop(e:Event):void {
dragArray[i].stopDrag();
dragArray[i].x = startPosition.x;
dragArray[i].y = startPosition.y;
startPosition = null;
}
for (var i:uint = 0; i < dragArray.length; i++) {
dragArray[i].addEventListener(MouseEvent.MOUSE_DOWN, drag);
dragArray[i].stage.addEventListener(MouseEvent.MOUSE_UP, dragStop);
}
The function is not being applied to the array. Any suggestions?
I think what null was trying to tell you is that within each function scope you should remove dragArray[i] and use e.currentTarget instead.
Here's a simple fix:
var dragArray:Array = new Array;
dragArray.push(blockSmalla);
dragArray.push(blockSmallb);
dragArray.push(blockSmallc);
dragArray.push(blockSmalld);
dragArray.push(blockSmalle);
var startPosition:Point;
function drag(e:Event):void {
e.currentTarget.startDrag();
startPosition = new Point( e.currentTarget.x, e.currentTarget.y);
}
function dragStop(e:Event):void {
e.currentTarget.stopDrag();
e.currentTarget.x = startPosition.x;
e.currentTarget.y = startPosition.y;
startPosition = null;
}
for (var i:uint = 0; i < dragArray.length; i++) {
dragArray[i].addEventListener(MouseEvent.MOUSE_DOWN, drag);
dragArray[i].addEventListener(MouseEvent.MOUSE_UP, dragStop);
}
Also note I removed the stage reference on your MouseUp listener.

Why can't I reset this game? I tried resetting variables etc

I have this flash game coded with AS3. It works on the first round. When you die, the program will loop it back to the game frame in which a couple or errors occur. One. the dead characters from last round still remain still. Two. The speed doubles everytime. Why????
I create a resetEverything() function to reset all variables, remove Event Listeners and a clear.graphics()
Why doesn't anything work?
Here is my code..
stop();
var leftBorder:verticalwall = new verticalwall(); // defining a variable to hold the left wall
addChild(leftBorder); // adding the left wall to the stage
var rightBorder:verticalwall = new verticalwall(); // defining a variable to hold the left wall
rightBorder.x = 790; // pushing the right wall to the edge of the stage
addChild(rightBorder); // adding the right wall to the stage
var topBorder:horizontalwall = new horizontalwall(); // defining a variable to hold the left wall
addChild(topBorder); // adding the top wall to the stage
var bottomBorder:horizontalwall = new horizontalwall(); // defining a variable to hold the bottom wall
bottomBorder.y = 790; // pushing the bottom wall to the base of the stage
addChild(bottomBorder); // adding the bottom wall to the stage
var P1positions:Array = new Array(); //defining a new variable to hold the poistions of Player 1
var P2positions:Array = new Array(); //defining a new variable to hold the poistions of Player 2
graphics.beginFill( 0x000000 ); // defining a colour for the background
graphics.drawRect( 0, 0, 800, 800); // drawing a rectangle for background
graphics.endFill(); // ending the background creating process
stage.addEventListener(Event.ENTER_FRAME, checkPlayersSpeed);
function checkPlayersSpeed(event:Event)
{
if(P1speed == 0 || P2speed == 0){
P1speed = 0;
P2speed = 0;
gotoAndStop(1, "Conclusion");
}
}
//Player 1
var player1col = "0xFF0000";
var Player1:Shape = new Shape(); //defining a variable for Player 1
Player1.graphics.lineStyle(10,0xffff00); //defining the colour of the style
Player1.graphics.beginFill(0xffff00); //begin filling the shape
Player1.graphics.drawRoundRect(0,0,3,3,360);
Player1.graphics.drawCircle(Player1.x, Player1.x, 2.4) //draw a circle
Player1.graphics.endFill(); //finish the filling process
addChild(Player1); //add player 1 to stage
Player1.x = 250;
Player1.y = 250;
var P1leftPressed:Boolean = false; //boolean to check whether the left key for Player 1 was pressed
var P1rightPressed:Boolean = false; //boolean to check whether the right key for Player 1 was pressed
var P1speed = 3.5; //variable to store the speed of which player 1 moves
var P1Dir = 45; //variable containing the direction in which player 1 moves
var P1position, P2position;
Player1.addEventListener(Event.ENTER_FRAME, P1fl_MoveInP1DirectionOfKey); //adding a listener to the player
stage.addEventListener(KeyboardEvent.KEY_DOWN, P1fl_SetKeyPressed); //listener for a key to be pressed
stage.addEventListener(KeyboardEvent.KEY_UP, P1fl_UnsetKeyPressed); // listener for a key to be released
function P1fl_MoveInP1DirectionOfKey(event:Event) //Moves the player depedning on what key was pressed
{
if(Player1.hitTestObject(leftBorder) || Player1.hitTestObject(rightBorder) || Player1.hitTestObject(topBorder) || Player1.hitTestObject(bottomBorder)){ //checking to see whether Player 1 has hit the wall
P1speed = 0; //stopping Player 1 from moving
Player1.removeEventListener(Event.ENTER_FRAME, P1fl_MoveInP1DirectionOfKey); //adding a listener to the player
stage.removeEventListener(KeyboardEvent.KEY_DOWN, P1fl_SetKeyPressed); //listener for a key to be pressed
stage.removeEventListener(KeyboardEvent.KEY_UP, P1fl_UnsetKeyPressed); // listener for a key to be released
}
if (P1leftPressed)
{
P1Dir -= 0.1; //changes the direction to make Player 1 rotate
}
if (P1rightPressed)
{
P1Dir += 0.1; //changes the direction to make Player 1 rotate
}
P1position = [Player1.x, Player1.y]; //defining a variable for Player 1's constant positions
P1positions.push(P1position); //pushes every position of Player 1 to the array
for (var i = 0; i < P1positions.length - 10; i++) { //a loop that opperates for as long as the array is receiving positions
var P1x = P1positions[i][0]; //saving x positions into array with a unique identifier
var P1y = P1positions[i][1]; //saving y positions into array with a unique identifier
if (distanceBetween(P1x, P1y, Player1.x, Player1.y) < 15) { //checking distance between Player 1 and its trail
P1speed = 0;
}
}
Player1.x += P1speed * Math.cos(P1Dir); //this makes player 1 move forard
Player1.y += P1speed * Math.sin(P1Dir); //this makes player 2 move forward
var P1trail:Shape = new Shape; //defining a variable for player 1's trail
graphics.lineStyle(8, player1col); //setting the format for the trail
graphics.drawCircle(Player1.x, Player1.y, 1.4); //drawing the circles within the trail
addChild(P1trail); //adding the circles to the stage
}
function P1fl_SetKeyPressed(event:KeyboardEvent):void
{
switch (event.keyCode)
{
case Keyboard.LEFT:
{
P1leftPressed = true; //tells the computer that left has been pressed
break;
}
case Keyboard.RIGHT:
{
P1rightPressed = true; //tells the computer that right has been pressed
break;
}
}
}
function P1fl_UnsetKeyPressed(event:KeyboardEvent):void
{
switch (event.keyCode)
{
case Keyboard.LEFT:
{
P1leftPressed = false; //tells the computer that left has been released
break;
}
case Keyboard.RIGHT:
{
P1rightPressed = false; //tells the computer that left has been released
break;
}
}
}
function distanceBetween (x1:Number, y1:Number, x2:Number, y2:Number) { // creating a function
// return d = Math.sqrt(x2 - x1)^2 +(y2 - y1)^2);
var diffX = x2 - x1; // creating variable to tidy up the pythagoras line below
var diffY = y2 - y1; // creating variable to tidy up the pythagoras line below
return Math.sqrt(diffX * diffX + diffY * diffY); // using pythagras theorem
}
// Player 2
var player2col = "0x0066CC";
var Player2:Shape = new Shape(); //defining a variable for Player 1
Player2.graphics.lineStyle(10,0xffff00); //defining the colour of the style
Player2.graphics.beginFill(0xffff00); //begin filling the shape
Player2.graphics.drawRoundRect(0,0,3,3,360);
Player2.graphics.drawCircle(Player2.x, Player2.x, 2.4) //draw a circle
Player2.graphics.endFill(); //finish the filling process
addChild(Player2); //add player 1 to stage
Player2.x = 500;
Player2.y = 500;
var P2leftPressed:Boolean = false;
var P2rightPressed:Boolean = false;
var P2speed = 3.5;
var P2Dir = 180;
Player2.addEventListener(Event.ENTER_FRAME, P2fl_MoveInP1DirectionOfKey);
stage.addEventListener(KeyboardEvent.KEY_DOWN, P2fl_SetKeyPressed);
stage.addEventListener(KeyboardEvent.KEY_UP, P2fl_UnsetKeyPressed);
function P2fl_MoveInP1DirectionOfKey(event:Event)
{
if(Player2.hitTestObject(leftBorder) || Player2.hitTestObject(rightBorder) || Player2.hitTestObject(topBorder) || Player2.hitTestObject(bottomBorder)){
P2speed = 0;
Player2.removeEventListener(Event.ENTER_FRAME, P2fl_MoveInP1DirectionOfKey);
stage.removeEventListener(KeyboardEvent.KEY_DOWN, P2fl_SetKeyPressed);
stage.removeEventListener(KeyboardEvent.KEY_UP, P2fl_UnsetKeyPressed);
}
if (P2leftPressed)
{
P2Dir -= 0.1;
}
if (P2rightPressed)
{
P2Dir += 0.1;
}
P2position = [Player2.x, Player2.y];
//trace(P2position);
P1positions.push(P2position);
for (var a = 0; a < P1positions.length - 10; a++) {
var P2x = P1positions[a][0];
var P2y = P1positions[a][1];
if (distanceBetween(P2x, P2y, Player2.x, Player2.y) < 15) {
P2speed = 0;
}
}
Player2.x += P2speed * Math.cos(P2Dir);
Player2.y += P2speed * Math.sin(P2Dir);
var P2trail:Shape = new Shape;
graphics.lineStyle(8, player2col);
graphics.drawCircle(Player2.x, Player2.y, 1.4);
addChild(P2trail);
}
function P2fl_SetKeyPressed(event:KeyboardEvent):void
{
switch (event.keyCode)
{
case event.keyCode = 90:
{
P2leftPressed = true;
break;
}
case event.keyCode = 67:
{
P2rightPressed = true;
break;
}
}
}
function P2fl_UnsetKeyPressed(event:KeyboardEvent):void
{
switch (event.keyCode)
{
case event.keyCode=90:
{
P2leftPressed = false;
break;
}
case event.keyCode=67:
{
P2rightPressed = false;
break;
}
}
}
Please help!

Drag panning with zoom on mouseclick location AS3

So, another post on here REALLY helped me prior from this link!
It got me to zoom in neatly, but what I'm really looking for in my panning is a mouse drag (I will be working with a touch screen, so dragging to move is important) No need to use Touch classes, I have done dragging events with Mouse classes before and find it easier to me.
My problem here is that my neat zoom is linked to this MOUSE_MOVE panning, and I want to know a clean way to change my panning to a drag event, and still not have my panning go past my image constraints.
bg_mc- is my background image to move and zoom.
My code:
import com.greensock.*;
bg_mc.doubleClickEnabled = true;
//Variables
var percX:Number;
var percY:Number;
var destX:Number;
var destY:Number;
//Image panned and masked
this.mask = mask_mc;
stage.addEventListener(MouseEvent.MOUSE_MOVE,mousemove);
function mousemove(e:MouseEvent) {
if (mask_mc.hitTestPoint(stage.mouseX,stage.mouseY,false)) {
if (bg_mc.width>mask_mc.width) {//Avoids Scrolling if image is under mask area width
percX = mask_mc.mouseX/mask_mc.width;
}
if (bg_mc.height>mask_mc.height) {
//Avoids Scrolling if image is under mask area height
percY = mask_mc.mouseY/mask_mc.height;
}
destX = -(bg_mc.width-mask_mc.width)*percX;
destY = -(bg_mc.height-mask_mc.height)*percY;
TweenMax.to(bg_mc,.5,{x:destX,y:destY});
}
}
//Add listeners for the imgLoader movie clip.
bg_mc.doubleClickEnabled = true;
bg_mc.addEventListener(MouseEvent.DOUBLE_CLICK, increaseSize);
bg_mc.addEventListener(MouseEvent.CLICK, decreaseSize);
function scaleAroundMouse(objectToScale:DisplayObject, scaleAmount:Number,
bounds:Rectangle = null, onComplete:Function = null):TweenLite {
// scaling will be done relatively
var relScaleX:Number = scaleAmount / objectToScale.scaleX;
var relScaleY:Number = scaleAmount / objectToScale.scaleY;
// map vector to centre point within parent scope
var scalePoint:Point = objectToScale.localToGlobal( new
Point(objectToScale.mouseX, objectToScale.mouseY));
scalePoint = objectToScale.parent.globalToLocal( scalePoint );
// current registered postion AB
var AB:Point = new Point( objectToScale.x, objectToScale.y );
// CB = AB - scalePoint, objectToScale vector that will scale as it runs from the centre
var CB:Point = AB.subtract( scalePoint );
CB.x *= relScaleX;
CB.y *= relScaleY;
// recaulate AB, objectToScale will be the adjusted position for the clip
AB = scalePoint.add( CB );
// set actual properties
if(bounds){
var limits:Rectangle = new Rectangle(
bounds.x + (bounds.width - (objectToScale.width * relScaleX)),
bounds.y + (bounds.height - (objectToScale.height * relScaleY)),
(objectToScale.width * relScaleX) - bounds.width,
(objectToScale.height * relScaleY) - bounds.height
);
if(AB.x < limits.x) AB.x = limits.x;
if(AB.x > limits.x + limits.width) AB.x = limits.x + limits.width;
if(AB.y < limits.y) AB.y = limits.y;
if(AB.y > limits.y + limits.height) AB.y = limits.y + limits.height;
}
return TweenLite.to(objectToScale,1,{onComplete: onComplete,
scaleX: scaleAmount, scaleY: scaleAmount, x: AB.x, y: AB.y});
}
function increaseSize(event:MouseEvent):void{
stopMouseMove();
scaleAroundMouse(bg_mc, 4, null, resumeMouseMove);
}
function decreaseSize(event:MouseEvent):void{
stopMouseMove();
scaleAroundMouse(bg_mc, 1, null, resumeMouseMove);
}
function stopMouseMove():void {
stage.removeEventListener(MouseEvent.MOUSE_MOVE,mousemove);
}
function resumeMouseMove():void {
stage.addEventListener(MouseEvent.MOUSE_MOVE,mousemove);
}
Any help I can get would be great!
On a mousedown or whatever listener you want to start dragging, use the MovieClip.StartDrag() function to allow dragging, and the StopDrag() to stop it.
While you could use the built in startDrag (or startTouchDrag) and stopDrag methods, it will not play nice with your zoom in/out function.
bg_mc.addEventListener(MouseEvent.MOUSE_DOWN,mouseDown); //add the listener to the bg directly
function mouseDown(e:MouseEvent) {
// if (mask_mc.hitTestPoint(stage.mouseX,stage.mouseY,false)) { //this isn't needed if you add the listener directly to bg_mc
stage.addEventListener(MouseEvent.MOUSE_UP,mouseUp);
bg_mc.startDrag(false, getBoundsRect()); //see the code below for the getBoundsRect() function
}
function mouseUp(e:MouseEvent):void {
bg_mc.stopDrag();
stage.removeEventListener(MouseEvent.MOUSE_UP,mouseUp);
}
You'd be better served to have a custom drag function, like below:
import com.greensock.*;
import flash.events.MouseEvent;
import flash.geom.Rectangle;
import flash.events.Event;
import flash.geom.Point;
bg_mc.doubleClickEnabled = true;
//Variables
var percX:Number;
var percY:Number;
var destX:Number;
var destY:Number;
//Image panned and masked
bg_mc.mask = mask_mc;
//this function generates a bounds rectangle that would keep bg_mc edges from going outside of mask_mc area
function getBoundsRect():Rectangle {
return new Rectangle((mask_mc.x + mask_mc.width) - bg_mc.width, (mask_mc.y + mask_mc.height) - bg_mc.height, bg_mc.width - mask_mc.width, bg_mc.height - mask_mc.height);
}
var isZoomed:Boolean = false; //a var to keep track of whether your zoomed in or out
var isDragging:Boolean = false; //a var to keep track of whether the bg is being dragged
var tmpMousePoint:Point = new Point(); //this stores the mouse coordinates on the mouse down, to compare later on the mouse up to see if the mouse moved
var decay:Number = .27; //make this lower for slower drag, make it 1 to turn off a smooth drag all together
var tmpMouseMoved:Boolean = false; //to keep track on mouse up whether the action was a drag or a click
var mouseMoveSensitivity:Number = 15; //how far does mouse need to move before you cancel the click event
var offset:Point = new Point(); //the offset of the initial mouse click relative to bg_mc's 0,0
bg_mc.addEventListener(MouseEvent.MOUSE_DOWN,mouseDown);
bg_mc.addEventListener(MouseEvent.CLICK,mouseClick, false, 99999); //listen with a higher priority than any other click listeners on bg_mc - this way if it's a drag, you can cancel the click event
function mouseDown(e:Event):void {
//reset these to default
isDragging = true;
tmpMouseMoved = false;
tmpMousePoint.x = mouseX; //capture the current mouse to check later if it moved (so you know the user intended to drag not click)
tmpMousePoint.y = mouseY;
offset.x = bg_mc.mouseX;
offset.y = bg_mc.mouseY;
bg_mc.addEventListener(Event.ENTER_FRAME,bgEnterFrame); //listen every frame until the mouse is released
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUp);
}
function bgEnterFrame(e:Event):void {
bg_mc.x += decay * (mouseX - offset.x - bg_mc.x);
bg_mc.y += decay * (mouseY - offset.y - bg_mc.y);
var bounds:Rectangle = getBoundsRect();
switch(true){
case (bg_mc.x < bounds.x):
bg_mc.x = bounds.x;
break;
case (bg_mc.x > bounds.x + bounds.width):
bg_mc.x = bounds.x + bounds.width;
}
switch(true){
case (bg_mc.y < bounds.y):
bg_mc.y = bounds.y;
break;
case (bg_mc.y > bounds.y + bounds.height):
bg_mc.y = bounds.y + bounds.height;
}
if(Math.abs(tmpMousePoint.x - mouseX) > mouseMoveSensitivity || Math.abs(tmpMousePoint.y - mouseY) > mouseMoveSensitivity){
tmpMouseMoved = true;
}
}
function mouseUp(e:Event):void {
isDragging = false;
//remove listeners
bg_mc.removeEventListener(Event.ENTER_FRAME,bgEnterFrame);
stage.removeEventListener(MouseEvent.MOUSE_UP, mouseUp);
}
function mouseClick(e:MouseEvent):void {
trace("CLICK cap");
if(tmpMouseMoved){
trace("Kill");
e.stopImmediatePropagation(); //cancel the mouse event
}
}
//Add listeners for the imgLoader movie clip.
bg_mc.doubleClickEnabled = true;
bg_mc.addEventListener(MouseEvent.DOUBLE_CLICK, increaseSize);
bg_mc.addEventListener(MouseEvent.CLICK, decreaseSize,false,0,true);
function scaleAroundMouse(objectToScale:DisplayObject, scaleAmount:Number,
bounds:Rectangle = null, onComplete:Function = null):TweenLite {
// scaling will be done relatively
var relScaleX:Number = scaleAmount / objectToScale.scaleX;
var relScaleY:Number = scaleAmount / objectToScale.scaleY;
// map vector to centre point within parent scope
var scalePoint:Point = objectToScale.localToGlobal( new
Point(objectToScale.mouseX, objectToScale.mouseY));
scalePoint = objectToScale.parent.globalToLocal( scalePoint );
// current registered postion AB
var AB:Point = new Point( objectToScale.x, objectToScale.y );
// CB = AB - scalePoint, objectToScale vector that will scale as it runs from the centre
var CB:Point = AB.subtract( scalePoint );
CB.x *= relScaleX;
CB.y *= relScaleY;
// recaulate AB, objectToScale will be the adjusted position for the clip
AB = scalePoint.add( CB );
// set actual properties
if(bounds){
var limits:Rectangle = new Rectangle(
bounds.x + (bounds.width - (objectToScale.width * relScaleX)),
bounds.y + (bounds.height - (objectToScale.height * relScaleY)),
(objectToScale.width * relScaleX) - bounds.width,
(objectToScale.height * relScaleY) - bounds.height
);
if(AB.x < limits.x) AB.x = limits.x;
if(AB.x > limits.x + limits.width) AB.x = limits.x + limits.width;
if(AB.y < limits.y) AB.y = limits.y;
if(AB.y > limits.y + limits.height) AB.y = limits.y + limits.height;
}
TweenLite.killTweensOf(objectToScale); //need to add this so the click/double click don't compete with each other
return TweenLite.to(objectToScale,1,{onComplete: onComplete,
scaleX: scaleAmount, scaleY: scaleAmount, x: AB.x, y: AB.y});
}
function increaseSize(event:MouseEvent):void{
if(isZoomed){
scaleAroundMouse(bg_mc, 4, getBoundsRect());
isZoomed = false;
}
}
function decreaseSize(event:MouseEvent):void{
if(!isZoomed){
scaleAroundMouse(bg_mc, 1, getBoundsRect());
isZoomed = true;
}
}

elastic string script makes flash crash

I'm in over my head in this AS3 project.
I'm no expert in actionscript and certainly not in AS3 but I managed to create (with help from this: http://swamy-techtalk.blogspot.com/2011/07/elastic-string-to-mouse-pointer-effect.html) a eleastic string effect from a point to a draggable movieclip.
Problem is the script seems to crash flash or the browser when I test it. (Not right away just when I'm playing around with the movieclip)
Sinse I'm in over my head in the script I compiled I'm not exactly sure whats wrong.
A bit of google research hinted that it might have something to do with removeChildAt() wich I changed from removeChildAt(0) to removeChildAt(1) to prevent it from removing my movieclip.
Hope somebody has the patience to read through my script to see what I did wrong.
Example here: http://www.madsringblom.dk/flash/pullstring.html (beware it might crash your browser)
Code below:
Object(this).leaf_mc.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
var origX:int = Object(this).leaf_mc.x + 1;
var origY:int = Object(this).leaf_mc.y + 2;
var pullbackX:int = Object(this).leaf_mc.x;
var pullbackY:int = Object(this).leaf_mc.y;
var dragging:Boolean = false;
//speed of pulling and rotating back when stop dragging.
var speed:int = 15;
var addX:int = 2
var addY:int = 3
function mouseDownHandler(e:MouseEvent):void
{
var obj = e.target;
obj.startDrag();
dragging = true;
}
function mouseUpHandler(e:MouseEvent):void
{
var obj = e.target;
Object(this).leaf_mc.stopDrag();
dragging = false;
}
import flash.display.*;
import flash.events.MouseEvent;
import flash.events.Event;
var haschild:Boolean = false;
var gotonodes:Array = new Array();
var currentnodes:Array = new Array();
var posX:int = Object(this).leaf_mc.x + addX;
var posY:int = Object(this).leaf_mc.y + addY;
gotonodes = Interpolate(posX,posY,origX,origY,25);
currentnodes = gotonodes;
stage.addEventListener(Event.ENTER_FRAME, onmove1);
function onmove1(e:Event)
{
for (var node = 0; node < gotonodes.length - 1; node++)
{
currentnodes[node].xco=currentnodes[node].xco+(gotonodes[node].xco-currentnodes[node].xco)/(node*node/30+1);
currentnodes[node].yco=currentnodes[node].yco+(gotonodes[node].yco-currentnodes[node].yco)/(node*node/30+1);
}
var posX:int = Object(this).leaf_mc.x + addX;
var posY:int = Object(this).leaf_mc.y + addY;
gotonodes=Interpolate(posX,posY,origX,origY,25);
// pull leaf_mc back to starting point when released. And rotate back.
if (dragging == false)
{
Object(this).leaf_mc.x-=(Object(this).leaf_mc.x-pullbackX)/speed;
Object(this).leaf_mc.y-=(Object(this).leaf_mc.y-pullbackY)/speed;
Object(this).leaf_mc.rotation+=Object(this).leaf_mc.rotation/speed;
}
// rotating the leaf_mc according to the point (origX,origY)
var theX:int = origX - Object(this).leaf_mc.x;
var theY:int = (origY - Object(this).leaf_mc.y) * -1;
var angle = Math.atan(theY/theX)/(Math.PI/180);
Math.atan( -5 / 10) / (Math.PI / 180);
if (theX < 0)
{
angle += 180;
}
if (theX >= 0 && theY < 0)
{
angle += 360;
}
Object(this).leaf_mc.rotation = (angle*-1) + 90;
DrawNodes(currentnodes);
}
function FindAngle(x1, x2, y1, y2):Number
{
return Math.atan2(y2-y1, x2-x1);
};
function Distance(x1, x2, y1, y2):Number
{
return Math.sqrt(Math.pow(x2-x1,2)+Math.pow(y2-y1,2));
}
function Interpolate(x1, y1, x2, y2, n):Array
{
var dist= Distance(x1,x2,y1,y2);
var ang = FindAngle(x1,x2,y1,y2);
var points = [];
for (var l = 0; l <= dist; l += dist / n)
{
var x3 =x1+l*Math.cos(ang);
var y3 = y1+l*Math.sin(ang);
points.push({xco:x3,yco:y3});
}
points.push( { xco:x1, yco:y1 } );
return points;
}
function DrawNodes(array):void
{
if(haschild)
{
this.removeChildAt(1);
haschild=false;
}
var shape:Shape = new Shape();
shape.graphics.lineStyle(1,0x331100,40);
shape.graphics.moveTo(array[0].xco, array[0].yco);
for (var i = 0; i < array.length - 1; i++)
{
shape.graphics.lineTo(array[i].xco,array[i].yco);
}
shape.graphics.beginFill(0xFBFFA4,1);
shape.graphics.drawCircle(array[0].xco,array[0].yco,1);
shape.graphics.endFill();
this.addChild(shape);
haschild = true;
}
Where is this code placed? From what you pasted, I'm thinking on the stage.
A stop(); somewhere in the script might be a start and help quite a bit - otherwise the Flash movie will loop, and every time it hits this frame (every frame if you only have one), you'll add new event handlers etc. Eventually you'll run out of memory, and the onmove1 event handler will eat up your CPU, running 50 times per frame after 50 frames, 200 times after 200 frames etc.