Hovering off DPAD sometimes makes character move infinitely in one direction

别等时光非礼了梦想. 提交于 2019-12-20 04:09:55

问题


I have a DPAD in my game when the player holds down let's say the Left DPAD, if he moves his touch to the Up DPAD and let's go, the player continues going in the left direction.

It also works if you hold the a direction, lets say Up continue holding but move off the Up DPAD, sometimes you may continue going in that direction.

What I've tried to prevent this:

  • On direction clicks, trigger checks on whether your in motion, or already going a different direction
  • Setting collisions to force these variables to become false; aka, you hit something, inMotion = false, etc

That's about all I can think of on how to fix this.

Also, I use a lot of variables for my checks, is it better to change my functions to return booleans, or is this way fine? Just curious.

Game Class

package 
{
    import flash.display.MovieClip;
    import flash.utils.Timer;
    import flash.events.TimerEvent;

    public class Game extends MovieClip
    {
        public var area1:Boolean = true;
        public var area2:Boolean = false;
        public var area3:Boolean = false;

        public var player1:Boolean = true;
        public var player2:Boolean = false;

        public var upWalkspeed:Number = -5;
        public var downWalkspeed:Number = 5;
        public var leftWalkspeed:Number = -5;
        public var rightWalkspeed:Number = 5;

        public var inMotion:Boolean = false;
        public var goingUp:Boolean = false;
        public var goingDown:Boolean = false;
        public var goingLeft:Boolean = false;
        public var goingRight:Boolean = false;

        public var playerPosKeeper_mc:MovieClip = new mc_PlayerPosKeeper();

        public var up_dpad:MovieClip = new dpad_Up();
        public var down_dpad:MovieClip = new dpad_Down();
        public var left_dpad:MovieClip = new dpad_Left();
        public var right_dpad:MovieClip = new dpad_Right();
        public var menu_dpad:MovieClip = new dpad_Menu();
        public var run_dpad:MovieClip = new dpad_Menu();

        public var barrierRoof1_game:MovieClip = new game_BarrierRoof();
        public var barrierRoof2_game:MovieClip = new game_BarrierRoof();
        public var barrierSide1_game:MovieClip = new game_BarrierSide();
        public var barrierSide2_game:MovieClip = new game_BarrierSide();

        public var StageCollisions:Array = new Array(barrierRoof1_game, barrierRoof2_game, barrierSide1_game, barrierSide2_game);
        // fix MC goes after not before ||| public var player1States:Array = new Array(mc_P1D1,mc_P1D2,"mc_P1L1","mc_P1L2","mc_P1R1","mc_P1R2","mc_P1U1","mc_P1U2");

        public function Game()
        {
            trace("SUCCESS | Constructed Game Class");

            var aMove:Movement = new Movement(this);
            addChild(aMove);

        }
    }
}

Movement Class

package 
{
    import flash.display.Stage;
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.events.TouchEvent;
    import flash.net.dns.AAAARecord;
    import flash.ui.Multitouch;
    import flash.ui.MultitouchInputMode;


    public class Movement extends MovieClip
    {
        public function Movement(main:Game)
        {
            trace("SUCCESS | Constructed Movement Class");

            addChild(main.playerPosKeeper_mc);
            main.playerPosKeeper_mc.x = 384;
            main.playerPosKeeper_mc.y = 46;

            addChild(main.up_dpad);
            main.up_dpad.x = 55;
            main.up_dpad.y = 336;

            addChild(main.down_dpad);
            main.down_dpad.x = 57;
            main.down_dpad.y = 432;

            addChild(main.left_dpad);
            main.left_dpad.x = 19;
            main.left_dpad.y = 372;

            addChild(main.right_dpad);
            main.right_dpad.x = 118;
            main.right_dpad.y = 372;

            addChild(main.menu_dpad);
            main.menu_dpad.x = 61;
            main.menu_dpad.y = 377;

            addChild(main.run_dpad);
            main.run_dpad.x = 684;
            main.run_dpad.y = 369;

            addChild(main.barrierRoof1_game);
            main.barrierRoof1_game.x = 0;
            main.barrierRoof1_game.y = 0;

            addChild(main.barrierRoof2_game);
            main.barrierRoof2_game.x = 0;
            main.barrierRoof2_game.y = 470;

            addChild(main.barrierSide1_game);
            main.barrierSide1_game.x = 0;
            main.barrierSide1_game.y = 0;

            addChild(main.barrierSide2_game);
            main.barrierSide2_game.x = 790;
            main.barrierSide2_game.y = 0;

            Multitouch.inputMode = MultitouchInputMode.TOUCH_POINT;

            main.up_dpad.addEventListener(TouchEvent.TOUCH_BEGIN, upBeginInput);
            main.down_dpad.addEventListener(TouchEvent.TOUCH_BEGIN, downBeginInput);
            main.left_dpad.addEventListener(TouchEvent.TOUCH_BEGIN, leftBeginInput);
            main.right_dpad.addEventListener(TouchEvent.TOUCH_BEGIN, rightBeginInput);

            // Maybe add diagnol direction buttons in the future?;


            //  !!  NOTE  !!
            //  Use some sort of value, maybe a return or a variable to sync up animations
            // to if the player is moving, in the future

            // Movement Directions

            // Start of UP Movement
            function upBeginInput(e:TouchEvent):void
            {
                main.inMotion = true;
                main.goingUp = true;
                main.goingDown = false;
                main.goingLeft = false;
                main.goingRight = false;
                main.up_dpad.addEventListener(TouchEvent.TOUCH_END, upEndInput);
                addEventListener(Event.ENTER_FRAME,sendUpMovement);
            }
            function upEndInput(e:TouchEvent):void
            {
                main.inMotion = false;
                main.goingUp = false;
                main.up_dpad.removeEventListener(TouchEvent.TOUCH_END, upEndInput);
                removeEventListener(Event.ENTER_FRAME,sendUpMovement);
            }
            function sendUpMovement():void
            {
                if (main.inMotion == true && main.goingUp == true && main.goingDown == false && main.goingLeft == false && main.goingRight == false)
                {
                    movePlayer(0, main.upWalkspeed);
                }
                else
                {
                }
            }
            // End of UP Movement



            // Start of DOWN Movement
            function downBeginInput(e:TouchEvent):void
            {
                main.inMotion = true;
                main.goingUp = false;
                main.goingDown = true;
                main.goingLeft = false;
                main.goingRight = false;
                main.down_dpad.addEventListener(TouchEvent.TOUCH_END, downEndInput);
                addEventListener(Event.ENTER_FRAME,sendDownMovement);
            }
            function downEndInput(e:TouchEvent):void
            {
                main.inMotion = false;
                main.goingDown = false;
                main.down_dpad.removeEventListener(TouchEvent.TOUCH_END, downEndInput);
                removeEventListener(Event.ENTER_FRAME,sendDownMovement);
            }
            function sendDownMovement():void
            {
                if (main.inMotion == true && main.goingUp == false && main.goingDown == true && main.goingLeft == false && main.goingRight == false)
                {
                    movePlayer(0, main.downWalkspeed);
                }
                else
                {
                }
            }
            // End of DOWN Movement



            // Start of LEFT Movement
            function leftBeginInput(e:TouchEvent):void
            {
                main.inMotion = true;
                main.goingUp = false;
                main.goingDown = false;
                main.goingLeft = true;
                main.goingRight = false;
                main.left_dpad.addEventListener(TouchEvent.TOUCH_END, leftEndInput);
                addEventListener(Event.ENTER_FRAME,sendLeftMovement);
            }
            function leftEndInput(e:TouchEvent):void
            {
                main.inMotion = false;
                main.goingLeft = false;
                main.left_dpad.removeEventListener(TouchEvent.TOUCH_END, leftEndInput);
                removeEventListener(Event.ENTER_FRAME,sendLeftMovement);
            }
            function sendLeftMovement():void
            {
                if (main.inMotion == true && main.goingUp == false && main.goingDown == false && main.goingLeft == true && main.goingRight == false)
                {
                    movePlayer(main.leftWalkspeed, 0);
                }
                else
                {
                }
            }
            // End of LEFT Movement



            // Start of RIGHT Movement
            function rightBeginInput(e:TouchEvent):void
            {
                main.inMotion = true;
                main.goingUp = false;
                main.goingDown = false;
                main.goingLeft = false;
                main.goingRight = true;
                main.right_dpad.addEventListener(TouchEvent.TOUCH_END, rightEndInput);
                addEventListener(Event.ENTER_FRAME,sendRightMovement);
            }
            function rightEndInput(e:TouchEvent):void
            {
                main.inMotion = false;
                main.goingRight = false;
                main.right_dpad.removeEventListener(TouchEvent.TOUCH_END, rightEndInput);
                removeEventListener(Event.ENTER_FRAME,sendRightMovement);
            }
            function sendRightMovement():void
            {
                if (main.inMotion == true && main.goingUp == false && main.goingDown == false && main.goingLeft == false && main.goingRight == true)
                {
                    movePlayer(main.rightWalkspeed, 0);
                }
                else
                {
                }
            }
            // End of RIGHT Movement


            function movePlayer(movementX:Number, movementY:Number):void
            {
                var originalX:Number = main.playerPosKeeper_mc.x;
                var originalY:Number = main.playerPosKeeper_mc.y;
                main.playerPosKeeper_mc.x +=  movementX;
                if (checkCollision())
                {
                    main.playerPosKeeper_mc.x = originalX;
                }
                main.playerPosKeeper_mc.y +=  movementY;
                if (checkCollision())
                {
                    main.playerPosKeeper_mc.y = originalY;
                }
            }

            function checkCollision():Boolean
            {
                for each (var StageCollisions:MovieClip in main.StageCollisions)
                {
                    if (main.playerPosKeeper_mc.hitTestObject(StageCollisions))
                    {
                        return true;
                        main.inMotion = false;
                        main.goingUp = false;
                        main.goingDown = false;
                        main.goingLeft = false;
                        main.goingRight = false;
                    }
                }
                return false;
            }
        }
    }
}

回答1:


Before you even start to debug behaviors, you need to understand what algorithmic approach is. You have 4 similar pieces of code which differ in minor details and make your whole script too long and unreadable and hard to manage. Here's the guideline:

var isMoving:Boolean;
var Direction:Point = new Point;
var Buttons:Array = [Up, Down, Left, Right];

// Subscribe all buttons for the same handlers and behaviors.
for each (var aButton:InteractiveObject in Buttons)
{
    aButton.addEventListener(MouseEvent.MOUSE_DOWN, onDown);
    aButton.addEventListener(MouseEvent.MOUSE_OUT, onUp);
    aButton.addEventListener(MouseEvent.MOUSE_UP, onUp);
}

function onDown(e:MouseEvent):void
{
    // Figure which button was pressed.
    switch (e.currentTarget)
    {
        case Up:
            Direction.x = 0;
            Direction.y = -1;
            break;

        case Down:
            Direction.x = 0;
            Direction.y = 1;
            break;

        case Left:
            Direction.x = -1;
            Direction.y = 0;
            break;

        case Up:
            Direction.x = 1;
            Direction.y = 0;
            break;
    }

    // Now start moving Hero into the Direction.
    if (!isMoving)
    {
        isMoving = true;
        addEventListener(Event.ENTER_FRAME, onFrame);
    }
}

function onFrame(e:Event):void
{
    Hero.x += Direction.x;
    Hero.y += Direction.y;
}

function onUp(e:MouseEvent):void
{
    // If any of buttons is released or mouse out, stop moving Hero.
    removeEventListener(Event.ENTER_FRAME, onFrame);

    Direction.x = 0;
    Direction.y = 0;

    isMoving = false;
}

As you can see, the beauty of algorithmic approach is that you need to handle differently only things that need to be handled differently, in the example case (which is pretty similar to what you want to create) it is the block to set the movement direction. The rest of the code is identical for all the buttons and that's why the whole script is short and readable, easy to understand and manageable.



来源:https://stackoverflow.com/questions/42408816/hovering-off-dpad-sometimes-makes-character-move-infinitely-in-one-direction

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!