Код, который я использую для управления четырехнаправленным движением спрайта игрока в моей 2D-игре, демонстрирует некоторую нежелательную привязанность. Я понимаю, что эта привязанность вызвана тем, что условия if, которые будут выполнены в первую очередь, превзойдут последующие ifs ... Таким образом, привязанность направления, которую показывает мой код сейчас: left> right> up> down.
Какая привязанность мне нужна: первое нажатое направление> второе нажатое направление> третье нажатое направление> четвертое нажатое направление.
Я также хочу, чтобы он запомнил, в каком порядке нажатия клавиш, пока они не отпущены.
Пример:
Я держу влево, спрайт движется влево.
Я толкаю вверх, все еще удерживая влево, и спрайт немедленно движется вверх.
Я отпускаю вверх, все еще удерживая левую, и спрайт возобновляет свое движение влево.
Эта память должна охватывать все четыре клавиши со стрелками, чтобы элементы управления не выглядели глючными, если у пользователя "толстые пальцы".
Это код, который я использую для движения:
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;
}
Я думаю, что мог бы использовать Список и просто указать направление нажатия (влево, вправо, вверх, вниз) как строки в списке, если его еще нет в списке, а затем всегда проверять, какой последний элемент в список должен решить, какое направление переместить. И, конечно, удалить строки, когда соответствующие ключи отпущены. Будет ли это хорошим способом ее решения?
Вот моя попытка:
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)
{
}
Первоначально у меня были некоторые проблемы с ним, но теперь он, кажется, работает нормально, за исключением того, что он генерирует исключения (первое случайное исключение типа «System.ArgumentOutOfRangeException» произошло в mscorlib.dll), пока мой спрайт стоит на месте. Любые советы о том, как это остановить?
Я не просто ищу решение, которое работает, но что-то долговечное и эффективное, которое кажется прочным и профессиональным, поэтому обсуждение этой темы приветствуется.