Я согласен с Pop Catalin: вероятно, лучше не блокировать эти командные функции. Я думаю, вы могли бы улучшить свою игру, немного подумав о дизайне. Позвольте мне высказать некоторые соображения о том, как вы могли бы улучшить свой дизайн.
Во-первых, похоже, что проблема, которую вы описываете, заключается в том, что вы хотите отправить множество команд перемещения в определенном порядке игровому компоненту и заставить его выполнять эти команды в определенном порядке. Как вы заметили, существует разница во времени, которое требуется компьютеру для выполнения вычислений (для скорости или вращения), и времени, которое требуется компоненту для фактического выполнения действия (перемещения или вращения).
Проблема с блокировкой во время вычислений (Ahead, TurnLeft и т. Д.) Заключается в том, что цикл обновления, вызывающий эту функцию, не может обновлять любые другие компоненты. Это может работать нормально, если беспокоиться только об одном компоненте, но обычно это не так в большинстве игр.
Теперь по хорошей части: как мы можем решить эту проблему? Я думаю, что у Эриккалена правильная идея, но я бы пошел дальше. Похоже, что игровой компонент - это некая сущность, которая будет перемещаться, так почему бы не дать ему очередь действий? Простая реализация состоит в том, чтобы ваша вызывающая функция вызывала что-то вроде:
gameComponent.queueAction( (MethodInvoker)delegate()
{ gameComponent.Ahead(10); });
Ваша функция queueAction может выглядеть следующим образом:
public void queueAction(MethodInvoker action)
{
queue.Enqueue(action);
}
В верхней части функции обновления вы можете добавить:
if(noCurrentAction && queue.Count > 0)
{
((MethodInvoker)queue.Dequeue()).Invoke();
noCurrentAction = false;
}
И вам нужно добавить строку в конце функции обновления, например:
if(!moving && !rotating)
noCurrentAction = true;
Теперь я бы точно не назвал это лучшим решением, но для его реализации не требуется много кода. Конечно, если вам нужно двигаться и вращаться одновременно, вам придется немного подправить его. Кроме того, будет сложнее, если вы добавите различные типы действий.
Для более общего решения я бы подумал о создании базового класса Action и извлечении из него определенных классов действий. Затем вы можете просто отправить действия в очередь, и ваша функция обновления может вызвать функцию обновления действия, которая будет выполнять ту работу, которую сейчас выполняют две части ваших игровых компонентов, которые выполняет функция обновления.
Это всего лишь некоторые идеи для размышления, надеюсь, что-то здесь поможет вам начать.
Последнее, что я хотел упомянуть, это то, что я не вижу, чтобы вы использовали переменную gameTime, которая передается в Update. Количество, которое ваш компонент перемещает и вращает, может зависеть от времени, прошедшего с момента последнего вызова Update. Это означает, что функция Update будет перемещать и вращать ваш игровой компонент на основе прошедшего времени, а не только того, сколько раз была вызвана функция Update. Я не очень хорошо объясняю это, и это зависит от того, как вы хотите, чтобы ваша игра функционировала. Вот пара различных сообщений от Шона Харгривза (эксперт XNA). Кроме того, XNA Forum post обсуждает вопрос, который я пытался сделать.