【问题标题】:AS3 Keyboard Controlled Character - Animation problems with multiple key pressesAS3 键盘控制字符 - 多次按键的动画问题
【发布时间】:2014-01-25 15:47:17
【问题描述】:

我在游戏中有一个键盘控制的角色,当没有时它有一个固定的框架
按下按键,上、下、左、右四个不同的动画
(无对角线移动)。

因此,当按下左键时,_character 会在屏幕上向左移动并播放左侧动画。松开按键/向上按键时,静止帧会在角色静止的位置播放。

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

这肯定与 key up 处理程序有关。我是初学者,所以我确定我无法理解一些简单的逻辑,但我想不通!请帮帮我。无论我点击多快的键,我都需要播放该动画,并且只有在没有按下任何内容时,我才能看到静止图像。

在自己的类中的字符,带有速度变量。

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 和 KeyUp 侦听器。

_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 keyDownHandler(event:KeyboardEvent):void
        {
            if (event.keyCode == Keyboard.LEFT || event.keyCode == 65 )
            {
                _character.vx = -4;
                _character.gotoAndStop(4);
            }
            else if (event.keyCode == Keyboard.RIGHT || event.keyCode == 68)
            {
                _character.vx = 4;
                _character.gotoAndStop(5);
            }
            else if (event.keyCode == Keyboard.UP || event.keyCode == 87 )
            {
                _character.vy = -4;
                _character.gotoAndStop(2);
            }
            else if (event.keyCode == Keyboard.DOWN || event.keyCode == 83)
            {
                _character.vy = 4;
                _character.gotoAndStop(3);
            }   
        }

Key up 处理程序停止速度并播放第一帧,即静止图像。

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 的回答出色地解决了动画状态问题,但这个新的控制系统似乎想要沿对角线移动,从而将角色送上不想要的路径。

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

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

所以如果我想顺时针绕一个盒子(从它的左下角开始),我会向上按,然后向右,如果我不快速向下按,角色会再次向上和向右移动,朝向舞台的右上角。 (如果松开键,字符会停止。)

因此,如果我从对立的 updown 或 leftright 变量中按下两个键,它就会沿对角线移动。任何想法如何解决这个问题?

最终更新

Vesper 的回答解决了我原来的动画问题。我会提出新问题来处理剩余的查询。

【问题讨论】:

    标签: actionscript-3 flash animation keyboard-events keyup


    【解决方案1】:

    实际上,您有四个事实上独立的键状态,向上键按下/释放,向下键,向左键,向右键。从技术上讲,如果一次按下两个相反的键,可以执行特殊操作,在您的情况下,它不是必需的,但仍然值得一提。所以,你分别处理所有这些,然后才选择你的角色应该面向哪里。

        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 变量放在程序的开头,而不是在输入框架中。它现在工作得很好,播放适当的动画并在按键时停止。然而,控制有点失控,角色会在障碍物周围选择自己的方向。这会是由于 enterframe 处理程序每​​秒触发 60 次指令吗?知道如何解决这个问题吗?
    • 由于速度原因,这不太可能,但您可以考虑将帧速率降低到 30,例如,因为您的游戏最终可能会太大而无法维持 60fps。但实际上,如果新框架相同,您可以从字符中收集currentFrame 属性以不调用gotoAndStop()。你描述的其他行为我不清楚。
    • 您好,抱歉提示速度/输入框是问题所在,与此无关。我的问题不再是动画,而是实际影片剪辑对象的移动。我在主要问题部分添加了更新。如果您能再次查看并提供帮助,我将不胜感激。
    • 嗯。你似乎想沿着网格线移动你的角色,所以如果说你的 char 在框的左下角,你想先按上然后再按右并使其首先移动到网格分隔处,然后到下一个网格点。为此,您必须重新设计运动机制,而且非常重。速度方法将不再适用于此,因为您希望您的 char 相对于您将要四处走动的盒子向左或向下弹跳,并且您将无法确定弹跳的方向。我会说为此提出一个全新的问题。
    • 角色不必严格沿着网格点移动。想想旧的自上而下的 zelda 游戏(上、下、左、右和稳定的位置。)旧控件完美地移动了角色对象,但方向动画会因多次按下而变得混乱,您的回答动画效果很好,但角色按下上/左、上/右、下/左或下/右时,对象沿对角线移动。
    猜你喜欢
    • 2010-11-16
    • 1970-01-01
    • 1970-01-01
    • 2011-10-10
    • 1970-01-01
    • 1970-01-01
    • 2014-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多