О, здесь так много неправильного ...
То, что вы, вероятно, делаете до того, как ваш блок if
выражений:
MouseState mouseState = Mouse.GetState();
Теперь функция GetState
что фактически определяет текущее состояние мыши и упаковывает его в структуру MouseState
.С =
вы присваиваете это состояние переменной mouseState
.
Единственный раз, когда mouseState
изменится, это когда вы измените его самостоятельно!Итак, ваше условие выглядит следующим образом:
if (mouseState.LeftButton == ButtonState.Pressed) {
if (mouseState.LeftButton == ButtonState.Released) { /* "do stuff" */ }
}
Вы проверяете, равняется ли mouseState.LeftButton
, который не меняется, двум совершенно разным вещам!Очевидно, что «делать вещи» никогда не будет.
Теперь другую часть проблемы, которую я могу проиллюстрировать, заставляя код работать так, как вы, кажется, думаете, он должен работать:
if (Mouse.GetState().LeftButton == ButtonState.Pressed) {
// Some kind of delay, perhaps?
if (Mouse.GetState().LeftButton == ButtonState.Released) { /* "do stuff" */ }
}
Таким образом, состояние обновляется каждый раз, когда вы проверяете его.
Теперь вот проблема с этим кодом.Ваша мышь должна перейти из состояния «нажата» в состояние «отпущено» между двумя операторами if .Если этого не произойдет, условие не сработает.
Увеличение длительности задержки не исправит ее по многим причинам: во-первых, это отнимает время от фактического запуска вашей игры.Во-вторых, невозможно увеличить его до 100% времени кадра - поэтому всегда будет процентная вероятность того, что ваше условие не сработает.
Поэтому лучший способ обработки ввода - отслеживать состояниесостояние между кадрами .И лучший способ сделать это, как и во всех учебных руководствах, хранить MouseState lastMouseState;
между вызовами вашей Update
функции.Таким образом, ваш код должен выглядеть примерно так:
MouseState mouseState = Mouse.GetState();
if (lastMouseState.LeftButton == ButtonState.Pressed)
{
if (mouseState.LeftButton == ButtonState.Released)
{
/* "do stuff" */
}
}
lastMouseState = mouseState;
Теперь, вы можете сказать, что это все еще оставляет вас с реальной проблемой, которую вы упомянули в первую очередь: что, если использование щелкает так быстро, чтосостояние мыши меняется, а затем переключается обратно между вызовами на GetState
?
Что ж, мой первый ответ на это - «не беспокойся об этом». - известная проблема с платформой ввода XNA.Но на практике вы обнаружите, что люди обычно не нажимают или не набирают текст так быстро, что это вызывает фактических проблем при 60FPS.
Если ваша игра работает со скоростью значительно меньшей 60FPS, вы все равно можете запуститьваши обновления на 60FPS.Чтобы уменьшить свою ничью, вы можете использовать Game.SupressDraw
или заставить Game.BeginDraw
вернуть false (см. здесь и здесь ).Если вам также нужно запускать обновления со скоростью менее 60FPS, вы все равно можете обновить ввод со скоростью 60FPS (или быстрее!), Но это намного больше работы.(Обратите внимание, что ввод XNA должен выполняться в главном потоке .)
(Лично я бы посоветовал вам просто работать со скоростью 60FPS и перестать беспокоиться об этом!)
И, наконец, если вам этого недостаточно, вы можете связываться с interop, подключать насос сообщений и ловить сообщения WM_LBUTTONUP
.Это огромное излишество, но это «правильный» способ получить то, что вы хотите.