XNA游戏的优化键盘控制

时间:2012-03-19 23:15:57

标签: xna-4.0

我用来控制玩家精灵在我的2D游戏中的四向移动的代码表现出一些不必要的感情。我意识到这种感情是因为首次遇到的if条件将胜过其他的ifs ...所以我的代码现在显示的方向感情是:left>对> up>下来。

我想要的是什么样的感情:按下的第一个方向&gt; <第二方向按下> <第三方向按下>第四个方向紧迫。

我还希望它能记住按键的顺序,直到它们被释放。

实施例: 我向左抱,精灵向左移动。 我向上推,同时仍然保持向左,精灵立即向上移动。 我在向左扶着时释放,精灵继续向左移动。

这个内存应该包含所有四个方向键,这样如果用户有“胖手指”,控件就不会感到错误。

到目前为止,这是我用于移动的代码:

            if (CurrentKeyboardState.IsKeyDown(Keys.Left) == true)
            {
                Speed.X = moveSpeed;
                Direction.X = moveLeft;
            }
            else if (CurrentKeyboardState.IsKeyDown(Keys.Right) == true)
            {
                Speed.X = moveSpeed;
                Direction.X = moveRight;
            }
            else if (CurrentKeyboardState.IsKeyDown(Keys.Up) == true)
            {
                Speed.Y = moveSpeed;
                Direction.Y = moveUp;
            }
            else if (CurrentKeyboardState.IsKeyDown(Keys.Down) == true)
            {
                Speed.Y = moveSpeed;
                Direction.Y = moveDown;
            }

我想我可以使用List并将方向按下(左,右,上,下)字符串作为字符串(如果它不在列表中),然后始终检查最新的项目是什么列表是决定移动什么方向。当然,在释放相应的键时删除字符串。这是解决问题的好方法吗?

以下是我对此的尝试:

            if (currentKeyboardState.IsKeyDown(Keys.Left))
            {
                if (!keyDownList.Contains("left"))
                {
                    keyDownList.Add("left");
                    System.Diagnostics.Debug.WriteLine("left inserted");
                }
            }
            else if (oldKeyboardState.IsKeyDown(Keys.Left))
            {
                keyDownList.Remove("left");
                System.Diagnostics.Debug.WriteLine("left removed");
            }



            if (currentKeyboardState.IsKeyDown(Keys.Right))
            {
                if (!keyDownList.Contains("right"))
                {
                    keyDownList.Add("right");
                    System.Diagnostics.Debug.WriteLine("right added");
                }
            }
            else if (oldKeyboardState.IsKeyDown(Keys.Right))
            {
                keyDownList.Remove("right");
                System.Diagnostics.Debug.WriteLine("right removed");
            }



            if (currentKeyboardState.IsKeyDown(Keys.Up))
            {
                if (!keyDownList.Contains("up"))
                {
                    keyDownList.Add("up");
                    System.Diagnostics.Debug.WriteLine("up added");
                }
            }
            else if (oldKeyboardState.IsKeyDown(Keys.Up))
            {
                keyDownList.Remove("up");
                System.Diagnostics.Debug.WriteLine("up removed");
            }



            if (currentKeyboardState.IsKeyDown(Keys.Down))
            {
                if (!keyDownList.Contains("down"))
                {
                    keyDownList.Add("down");
                    System.Diagnostics.Debug.WriteLine("down added");
                }
            }
            else if (oldKeyboardState.IsKeyDown(Keys.Down))
            {
                keyDownList.Remove("down");
                System.Diagnostics.Debug.WriteLine("down removed");
            }


            try
            {
                if (keyDownList[keyDownList.Count-1].Contains("left"))
                {
                    //move left
                    speed.X = moveSpeed;
                    direction.X = moveLeft;
                }
                else if (keyDownList[keyDownList.Count-1].Contains("right"))
                {
                    //move right
                    speed.X = moveSpeed;
                    direction.X = moveRight;
                }
                else if (keyDownList[keyDownList.Count-1].Contains("up"))
                {
                    //move up
                    speed.Y = moveSpeed;
                    direction.Y = moveUp;
                }
                else if (keyDownList[keyDownList.Count-1].Contains("down"))
                {
                    //move down
                    speed.Y = moveSpeed;
                    direction.Y = moveDown;
                }
            }
            catch (Exception e)
            {
            }

我最初遇到了一些问题,但它现在似乎工作正常,除了它生成异常(mscorlib.dll中发生类型'System.ArgumentOutOfRangeException'的第一次机会异常),而我的精灵静止不动。关于如何阻止它的任何提示?

我不只是在寻找一个有效的解决方案,但对于那些耐用而高效的东西感觉坚如磐石和专业,所以对这个主题的讨论非常受欢迎。

1 个答案:

答案 0 :(得分:1)

耐用,高效,坚如磐石等等可能不是,但您对if / else if块的说法是,您只对每帧的一个键状态感兴趣,当我认为不是这样的时候。

如果你尝试会发生什么:

if (CurrentKeyboardState.IsKeyDown(Keys.Down) & !CurrentKeyboardState.IsKeyDown(Keys.Up))
{
    Speed.Y = moveSpeed;
    Direction.Y = moveDown;
}
if (CurrentKeyboardState.IsKeyDown(Keys.Up) & !CurrentKeyboardState.IsKeyDown(Keys.Down))
{
    Speed.Y = moveSpeed;
    Direction.Y = moveUp;
}

左右重复类似。通过测试相反方向之间的相互排他性,您可以避免在同一帧中添加和减去方向。此外,通过使用单独的条件而不是if / elseif链,您可以在同一帧中处理Left + Up。