我用来控制玩家精灵在我的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'的第一次机会异常),而我的精灵静止不动。关于如何阻止它的任何提示?
我不只是在寻找一个有效的解决方案,但对于那些耐用而高效的东西感觉坚如磐石和专业,所以对这个主题的讨论非常受欢迎。
答案 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。