Actionscript 3 AS3键盘控制的角色-多个按键的动画问题

Actionscript 3 AS3键盘控制的角色-多个按键的动画问题,actionscript-3,flash,animation,keyboard-events,keyup,Actionscript 3,Flash,Animation,Keyboard Events,Keyup,我在游戏中有一个键盘控制的角色,当没有 按下按键,向上、向下、左、右方向有四种不同的动画 (无对角线运动) 因此,当按下左键时,角色在屏幕上向左移动,并播放左动画。当释放关键点/向上关键点时,静止帧将在角色静止的位置播放 这可以在缓慢的速度下正常工作,但当按下多个键以绕过障碍物等时,角色通常会停留在静止位置,并且仅在延迟后播放动画。使用速度可以很好地移动Movieclip,但动画会受到影响 这肯定与钥匙上的手柄有关。我是一个初学者,所以我肯定我不能理解一些简单的逻辑,但我不能理解它!请帮帮我。无

我在游戏中有一个键盘控制的角色,当没有
按下按键,向上、向下、左、右方向有四种不同的动画
(无对角线运动)

因此,当按下左键时,角色在屏幕上向左移动,并播放左动画。当释放关键点/向上关键点时,静止帧将在角色静止的位置播放

这可以在缓慢的速度下正常工作,但当按下多个键以绕过障碍物等时,角色通常会停留在静止位置,并且仅在延迟后播放动画。使用速度可以很好地移动Movieclip,但动画会受到影响

这肯定与钥匙上的手柄有关。我是一个初学者,所以我肯定我不能理解一些简单的逻辑,但我不能理解它!请帮帮我。无论我以多快的速度点击按键,我都需要播放动画,只有在没有按下任何键的情况下,我才能看到静止的图像

角色在其自己的类中,带有速度变量

package
{
    import flash.display.MovieClip;
    import flash.display.DisplayObject

        [Embed(source="../swfs/characterRes.swf", symbol="Character")]
        public class Character extends MovieClip
        {
            //Public properties
            public var vx:int = 0;
            public var vy:int = 0;

            public function Character()
            {
            }
        }   
}
添加了Keydown和keydup侦听器

_stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
            _stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler); 
在enterFrame中,字符X和Y位置与速度相关联

private function enterFrameHandler(event:Event):void
        {   
            //Move the game character and check its stage boundaries
            _character.x += _character.vx; 
            _character.y += _character.vy;
        }
keydown处理程序使用箭头和WASD控制速度,并播放特定帧的方向(嵌入动画)

上键处理程序停止速度并播放第一帧静止图像

private function keyUpHandler(event:KeyboardEvent):void
        {
            if (event.keyCode == Keyboard.LEFT || event.keyCode == Keyboard.RIGHT 
                || event.keyCode == 65 || event.keyCode == 68)
            {
                _character.vx = 0;
                _character.gotoAndStop(1);
            } 
            else if (event.keyCode == Keyboard.DOWN || event.keyCode == Keyboard.UP 
                || event.keyCode == 87 || event.keyCode == 83 )
            {
                _character.vy = 0;
                _character.gotoAndStop(1);
            }
        }
我还将静止图像设置为亮红色,以便更容易识别,一旦我开始向不同方向移动角色,我就会看到红色!(字面上和比喻上!)

更新

Vesper的答案很好地解决了动画状态问题,但这个新的控制系统似乎想要沿对角线移动,从而将角色发送到一条不需要的路径上

我的舞台是一个50像素的方格。角色是50px,50px的boxess(带碰撞检测)周围有一个50px的边框,因此角色可以在舞台上移动

如果我按住一个方向,角色移动没有问题(从左到右和从上到下也可以),但是如果我向左然后向下或从上到右等,角色将沿该方向移动,然后在框周围继续该方向。当我在没有框的情况下进行测试时,角色将沿着对角线方向继续

因此,如果我想顺时针绕着一个盒子走(从盒子的左下方开始),我会先按向上,然后按向右,如果我不很快地按向下,角色将再次向上和向右移动,朝向舞台的右上方。(如果释放键,字符将停止。)

所以,如果我按下两个相反的上下或左右变量的键,它想要沿对角线移动。有什么办法解决这个问题吗

最终更新


Vesper的回答解决了我最初的动画问题。我会问一些新问题来处理剩下的问题

实际上有四种独立的按键状态,上键按下/释放、下键、左键、右键。从技术上讲,一个人可以在同时按下两个相反的键的情况下执行特殊操作,在你的情况下,这是不需要的,但仍然值得一提。所以,你要分别处理所有这些,然后才选择你的角色应该面对的地方

    var bDown:Boolean=false;
    var bUp:Boolean=false;
    var bLeft:Boolean=false;
    var bRight:Boolean=false;
    // declare vars to store key states. You can use an array if you want

    private function keyDownHandler(event:KeyboardEvent):void
    {
        if (event.keyCode == Keyboard.LEFT || event.keyCode == 65 )
        {
            bLeft=true;
            // now, instead of directly attaching the movement, just set flag
        }
        else if (event.keyCode == Keyboard.RIGHT || event.keyCode == 68)
        {
            bRight=true;
        }
        else if (event.keyCode == Keyboard.UP || event.keyCode == 87 )
        {
            bUp=true;
        }
        else if (event.keyCode == Keyboard.DOWN || event.keyCode == 83)
        {
            bDown=true;
        }   
    }
与密钥更新处理程序相同,将值设置为false。现在根据按下的键解析实际角色的移动。最好的地方是输入帧处理程序-幸好您已经将其放置到位了

    private function enterFrameHandler(event:Event):void
    {   
        var updown:Boolean=Boolean(!(bUp==bDown)); 
        // if both are true or both are false, this is false. If this is true, 
        // we are moving upwards or downwards
        var leftright:Boolean=Boolean(!(bLeft==bRight));
        // same here
        if (!updown && !leftright) {
            // not moving anywhere
            _character.gotoAndStop(1);
            _character.vy=0;
            _character.vx=0; 
            // other mechanics might be in place in case you decide to implement inertia, for example
        } else {
            if (bUp) {
                _character.vy=-4; // hardcoding this might get you issues later
                // will still do for today's task
                _character.gotoAndStop(2);
            } else if (bDown) {
                _character.vy=4;
                _character.gotoAndStop(3);
            } 
            // one side parsed. Note, with this sequence the leftwards or rightwards
            //animation supersedes up/down. But, we don't have diagonals, so there should be superseded animation
            if (bLeft) {
                _character.vx=-4;
                _character.gotoAndStop(4);
            } else if (bRight) {
                _character.vx=4;
                _character.gotoAndStop(5);
            } 
        }
        // Okay, now velocity and facing is set, proceed with move
        //Move the game character and check its stage boundaries
        _character.x += _character.vx; 
        _character.y += _character.vy;
    }

我真傻,我把updown和leftright变量放在程序的开头,而不是enter框架中。它现在工作得相当好,播放适当的动画,并在设置关键帧时停止。但是,控件有点失控,角色将在障碍物周围选择自己的方向。这是因为enterframe处理程序每秒发出60次指令吗?你知道如何解决这个问题吗?这是不可能的,因为速度,但你可以考虑降低帧速率为30,例如,因为最有可能你的游戏最终会太大,以维持60FPS。但实际上,如果新帧相同,您可以从character收集
currentFrame
属性以不调用
gotoAndStop()
。你描述的其他行为我还不清楚。嗨,很抱歉提出速度/进入帧是个问题,这与此无关。我的问题不再是动画,而是实际movieclip对象的运动。我在主要问题部分添加了一个更新。如果你能再帮我一次忙,我将不胜感激。你似乎想沿着网格线移动你的角色,所以如果你的角色在框的左下角,你想先按向上,然后按向右,这样角色首先向上移动到网格分隔处,然后向右移动到下一个网格点。为此,你必须重新设计运动的机制,而且要花很大的力气。速度方法将不再适用于此,因为您希望您的字符相对于您将要走动的长方体向左或向下反弹,并且您将无法确定反弹的方向。我想问一个全新的问题。角色不必严格地沿着网格点移动。想象一下旧的自上而下的塞尔达游戏(上、下、左、右和稳定位置)。旧的控件完美地移动了角色对象,但方向动画会被多次按下弄糊涂,你的答案是动画工作完美,但角色对象在上/左、上/右时呈对角线移动,按下“下/左”或“下/右”。
    private function enterFrameHandler(event:Event):void
    {   
        var updown:Boolean=Boolean(!(bUp==bDown)); 
        // if both are true or both are false, this is false. If this is true, 
        // we are moving upwards or downwards
        var leftright:Boolean=Boolean(!(bLeft==bRight));
        // same here
        if (!updown && !leftright) {
            // not moving anywhere
            _character.gotoAndStop(1);
            _character.vy=0;
            _character.vx=0; 
            // other mechanics might be in place in case you decide to implement inertia, for example
        } else {
            if (bUp) {
                _character.vy=-4; // hardcoding this might get you issues later
                // will still do for today's task
                _character.gotoAndStop(2);
            } else if (bDown) {
                _character.vy=4;
                _character.gotoAndStop(3);
            } 
            // one side parsed. Note, with this sequence the leftwards or rightwards
            //animation supersedes up/down. But, we don't have diagonals, so there should be superseded animation
            if (bLeft) {
                _character.vx=-4;
                _character.gotoAndStop(4);
            } else if (bRight) {
                _character.vx=4;
                _character.gotoAndStop(5);
            } 
        }
        // Okay, now velocity and facing is set, proceed with move
        //Move the game character and check its stage boundaries
        _character.x += _character.vx; 
        _character.y += _character.vy;
    }