简体   繁体   中英

AS3: Click and stop at mouse click

I want to create an object that follows and stops at mouse click. I managed to make it happen with rotation but the problem is that whenever i click on the empty stage, the object will move towards it and it carries on moving. It does not stop at the mouse location. Anyone know how i can do that. Below is my code:

package 
{
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.events.MouseEvent;

    public class Guest extends MovieClip
    {
        var walkSpeed:Number = 5;

        public function Guest()
        {
            stage.addEventListener(MouseEvent.CLICK, walk);
        }

        function walk(event:MouseEvent):void
        {
            var dx = parent.mouseX - x;
            var dy = parent.mouseY - y;
            var angle = Math.atan2(dy,dx) / Math.PI * 180;
            rotation = angle;

            stage.addEventListener(Event.ENTER_FRAME, loop);
        }

        function loop(event:Event):void
        {
            x = x+Math.cos(rotation/180*Math.PI)*walkSpeed;
            y = y+Math.sin(rotation/180*Math.PI)*walkSpeed;
            stage.removeEventListener(Event.ENTER_FRAME, loop);

        }
    }
}

Your code is a bit weird, here you will never move towards position for more than one frame since you remove the event listener as soon as loop is done.

Here is some code that fixes the moving and then stopping issue. However I strongly suggests that you do this with some kind of "tweening library" and I will after this show an example of doing that with Caurina Transitions .

function walk(e:MouseEvent):void {
    targetX = parent.mouseX; //targetX created as a member variable
    targetY = parent.mouseY; //targetY created as a member variable
    var dx = parent.mouseX - x;
    var dy = parent.mouseY - y;
    var angle = Math.atan2(dy,dx) / Math.PI * 180;
    rotation = angle;

    stage.addEventListener(Event.ENTER_FRAME, loop);
}

function loop(e:Event):void {
    var newX:Number = x + Math.cos(rotation / 180 * Math.PI) * walkSpeed;
    var newY:Number = y + Math.sin(rotation / 180 * Math.PI) * walkSpeed;

    var atTarget:Boolean = true;
    if (Math.abs(targetX - newX) > walkSpeed) {
        x = newX;
        atTarget = false;
    }
    if(Math.abs(targetY - y) > walkSpeed) {
        y = newY;
        atTarget = false;
    }

    if (atTarget) {
        stage.removeEventListener(Event.ENTER_FRAME, loop);
    }
}

Here's the same behaviour with caurina.

package
{
    import caurina.transitions.Tweener;
    import flash.display.MovieClip;
    import flash.events.MouseEvent;

    public class TransitionExample extends MovieClip
    {
        private var targetX:Number;
        private var targetY:Number;
        var walkSpeed:Number = 5;

        public function TransitionExample()
        {
            trace("ctor()");
            stage.addEventListener(MouseEvent.CLICK, walk);
        }

        private function walk(e:MouseEvent):void {
            targetX = parent.mouseX;
            targetY = parent.mouseY;

            var dx = targetX - x;
            var dy = targetY - y;
            var angle = Math.atan2(dy,dx) / Math.PI * 180;
            rotation = angle;

            var tweenDone:Function = function():void {
                trace("tween is finished");
            }
            //modify time to be dependant on the "walkspeed" and the distance travelled etc...
            Tweener.addTween(this, { x:targetX, y:targetY, time:0.458, transition:"linear", onComplete:tweenDone});
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM