Jak spowolnić lub zatrzymać naciśnięcia klawiszy W XNA
Zacząłem pisać grę używając frameworka XNA i napotkałem jakiś prosty problem, który nie wiem jak rozwiązać poprawnie.
Wyświetlam menu używając Texture2D i za pomocą klawiatury (lub gamepada) zmieniam wybrany element menu. Mój problem polega na tym, że bieżąca funkcja używana do przełączania między pozycjami menu jest zbyt szybka. Mogę kliknąć przycisk w dół i to pójdzie w dół 5 lub 6 pozycji menu (ze względu na fakt, że Update() jest wywoływany wiele razy w ten sposób aktualizowanie wybranych pozycji).
ex.
(> indicate selected)
> MenuItem1
MenuItem2
MenuItem3
MenuItem4
MenuItem5
I press the down key for just a second), then I have this state:
MenuItem1
MenuItem2
MenuItem3
> MenuItem4
MenuItem5
What I want is (until I press the key again)
MenuItem1
> MenuItem2
MenuItem3
MenuItem4
MenuItem5
Szukam sposobu, aby albo gracz klikał klawisz góra/dół wiele razy, aby przejść z jednego elementu menu do drugiego, albo mieć jakiś minimalny czas oczekiwania przed przejściem do następnego elementu menu.
12 answers
Zbudowałem (dużą) klasę, która bardzo pomaga we wszystkich zadaniach związanych z wejściami XNA, dzięki czemu to, o co prosisz, jest łatwe.
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
namespace YourNamespaceHere
{
/// <summary>
/// an enum of all available mouse buttons.
/// </summary>
public enum MouseButtons
{
LeftButton,
MiddleButton,
RightButton,
ExtraButton1,
ExtraButton2
}
public class InputHelper
{
private GamePadState _lastGamepadState;
private GamePadState _currentGamepadState;
#if (!XBOX)
private KeyboardState _lastKeyboardState;
private KeyboardState _currentKeyboardState;
private MouseState _lastMouseState;
private MouseState _currentMouseState;
#endif
private PlayerIndex _index = PlayerIndex.One;
private bool refreshData = false;
/// <summary>
/// Fetches the latest input states.
/// </summary>
public void Update()
{
if (!refreshData)
refreshData = true;
if (_lastGamepadState == null && _currentGamepadState == null)
{
_lastGamepadState = _currentGamepadState = GamePad.GetState(_index);
}
else
{
_lastGamepadState = _currentGamepadState;
_currentGamepadState = GamePad.GetState(_index);
}
#if (!XBOX)
if (_lastKeyboardState == null && _currentKeyboardState == null)
{
_lastKeyboardState = _currentKeyboardState = Keyboard.GetState();
}
else
{
_lastKeyboardState = _currentKeyboardState;
_currentKeyboardState = Keyboard.GetState();
}
if (_lastMouseState == null && _currentMouseState == null)
{
_lastMouseState = _currentMouseState = Mouse.GetState();
}
else
{
_lastMouseState = _currentMouseState;
_currentMouseState = Mouse.GetState();
}
#endif
}
/// <summary>
/// The previous state of the gamepad.
/// Exposed only for convenience.
/// </summary>
public GamePadState LastGamepadState
{
get { return _lastGamepadState; }
}
/// <summary>
/// the current state of the gamepad.
/// Exposed only for convenience.
/// </summary>
public GamePadState CurrentGamepadState
{
get { return _currentGamepadState; }
}
/// <summary>
/// the index that is used to poll the gamepad.
/// </summary>
public PlayerIndex Index
{
get { return _index; }
set {
_index = value;
if (refreshData)
{
Update();
Update();
}
}
}
#if (!XBOX)
/// <summary>
/// The previous keyboard state.
/// Exposed only for convenience.
/// </summary>
public KeyboardState LastKeyboardState
{
get { return _lastKeyboardState; }
}
/// <summary>
/// The current state of the keyboard.
/// Exposed only for convenience.
/// </summary>
public KeyboardState CurrentKeyboardState
{
get { return _currentKeyboardState; }
}
/// <summary>
/// The previous mouse state.
/// Exposed only for convenience.
/// </summary>
public MouseState LastMouseState
{
get { return _lastMouseState; }
}
/// <summary>
/// The current state of the mouse.
/// Exposed only for convenience.
/// </summary>
public MouseState CurrentMouseState
{
get { return _currentMouseState; }
}
#endif
/// <summary>
/// The current position of the left stick.
/// Y is automatically reversed for you.
/// </summary>
public Vector2 LeftStickPosition
{
get
{
return new Vector2(
_currentGamepadState.ThumbSticks.Left.X,
-CurrentGamepadState.ThumbSticks.Left.Y);
}
}
/// <summary>
/// The current position of the right stick.
/// Y is automatically reversed for you.
/// </summary>
public Vector2 RightStickPosition
{
get
{
return new Vector2(
_currentGamepadState.ThumbSticks.Right.X,
-_currentGamepadState.ThumbSticks.Right.Y);
}
}
/// <summary>
/// The current velocity of the left stick.
/// Y is automatically reversed for you.
/// expressed as:
/// current stick position - last stick position.
/// </summary>
public Vector2 LeftStickVelocity
{
get
{
Vector2 temp =
_currentGamepadState.ThumbSticks.Left -
_lastGamepadState.ThumbSticks.Left;
return new Vector2(temp.X, -temp.Y);
}
}
/// <summary>
/// The current velocity of the right stick.
/// Y is automatically reversed for you.
/// expressed as:
/// current stick position - last stick position.
/// </summary>
public Vector2 RightStickVelocity
{
get
{
Vector2 temp =
_currentGamepadState.ThumbSticks.Right -
_lastGamepadState.ThumbSticks.Right;
return new Vector2(temp.X, -temp.Y);
}
}
/// <summary>
/// the current position of the left trigger.
/// </summary>
public float LeftTriggerPosition
{
get { return _currentGamepadState.Triggers.Left; }
}
/// <summary>
/// the current position of the right trigger.
/// </summary>
public float RightTriggerPosition
{
get { return _currentGamepadState.Triggers.Right; }
}
/// <summary>
/// the velocity of the left trigger.
/// expressed as:
/// current trigger position - last trigger position.
/// </summary>
public float LeftTriggerVelocity
{
get
{
return
_currentGamepadState.Triggers.Left -
_lastGamepadState.Triggers.Left;
}
}
/// <summary>
/// the velocity of the right trigger.
/// expressed as:
/// current trigger position - last trigger position.
/// </summary>
public float RightTriggerVelocity
{
get
{
return _currentGamepadState.Triggers.Right -
_lastGamepadState.Triggers.Right;
}
}
#if (!XBOX)
/// <summary>
/// the current mouse position.
/// </summary>
public Vector2 MousePosition
{
get { return new Vector2(_currentMouseState.X, _currentMouseState.Y); }
}
/// <summary>
/// the current mouse velocity.
/// Expressed as:
/// current mouse position - last mouse position.
/// </summary>
public Vector2 MouseVelocity
{
get
{
return (
new Vector2(_currentMouseState.X, _currentMouseState.Y) -
new Vector2(_lastMouseState.X, _lastMouseState.Y)
);
}
}
/// <summary>
/// the current mouse scroll wheel position.
/// See the Mouse's ScrollWheel property for details.
/// </summary>
public float MouseScrollWheelPosition
{
get
{
return _currentMouseState.ScrollWheelValue;
}
}
/// <summary>
/// the mouse scroll wheel velocity.
/// Expressed as:
/// current scroll wheel position -
/// the last scroll wheel position.
/// </summary>
public float MouseScrollWheelVelocity
{
get
{
return (_currentMouseState.ScrollWheelValue - _lastMouseState.ScrollWheelValue);
}
}
#endif
/// <summary>
/// Used for debug purposes.
/// Indicates if the user wants to exit immediately.
/// </summary>
public bool ExitRequested
{
#if (!XBOX)
get
{
return (
(IsCurPress(Buttons.Start) &&
IsCurPress(Buttons.Back)) ||
IsCurPress(Keys.Escape));
}
#else
get { return (IsCurPress(Buttons.Start) && IsCurPress(Buttons.Back)); }
#endif
}
/// <summary>
/// Checks if the requested button is a new press.
/// </summary>
/// <param name="button">
/// The button to check.
/// </param>
/// <returns>
/// a bool indicating whether the selected button is being
/// pressed in the current state but not the last state.
/// </returns>
public bool IsNewPress(Buttons button)
{
return (
_lastGamepadState.IsButtonUp(button) &&
_currentGamepadState.IsButtonDown(button));
}
/// <summary>
/// Checks if the requested button is a current press.
/// </summary>
/// <param name="button">
/// the button to check.
/// </param>
/// <returns>
/// a bool indicating whether the selected button is being
/// pressed in the current state and in the last state.
/// </returns>
public bool IsCurPress(Buttons button)
{
return (
_lastGamepadState.IsButtonDown(button) &&
_currentGamepadState.IsButtonDown(button));
}
/// <summary>
/// Checks if the requested button is an old press.
/// </summary>
/// <param name="button">
/// the button to check.
/// </param>
/// <returns>
/// a bool indicating whether the selected button is not being
/// pressed in the current state and is being pressed in the last state.
/// </returns>
public bool IsOldPress(Buttons button)
{
return (
_lastGamepadState.IsButtonDown(button) &&
_currentGamepadState.IsButtonUp(button));
}
#if (!XBOX)
/// <summary>
/// Checks if the requested key is a new press.
/// </summary>
/// <param name="key">
/// the key to check.
/// </param>
/// <returns>
/// a bool that indicates whether the selected key is being
/// pressed in the current state and not in the last state.
/// </returns>
public bool IsNewPress(Keys key)
{
return (
_lastKeyboardState.IsKeyUp(key) &&
_currentKeyboardState.IsKeyDown(key));
}
/// <summary>
/// Checks if the requested key is a current press.
/// </summary>
/// <param name="key">
/// the key to check.
/// </param>
/// <returns>
/// a bool that indicates whether the selected key is being
/// pressed in the current state and in the last state.
/// </returns>
public bool IsCurPress(Keys key)
{
return (
_lastKeyboardState.IsKeyDown(key) &&
_currentKeyboardState.IsKeyDown(key));
}
/// <summary>
/// Checks if the requested button is an old press.
/// </summary>
/// <param name="key">
/// the key to check.
/// </param>
/// <returns>
/// a bool indicating whether the selectde button is not being
/// pressed in the current state and being pressed in the last state.
/// </returns>
public bool IsOldPress(Keys key)
{
return (
_lastKeyboardState.IsKeyDown(key) &&
_currentKeyboardState.IsKeyUp(key));
}
/// <summary>
/// Checks if the requested mosue button is a new press.
/// </summary>
/// <param name="button">
/// teh mouse button to check.
/// </param>
/// <returns>
/// a bool indicating whether the selected mouse button is being
/// pressed in the current state but not in the last state.
/// </returns>
public bool IsNewPress(MouseButtons button)
{
switch (button)
{
case MouseButtons.LeftButton:
return (
_lastMouseState.LeftButton == ButtonState.Released &&
_currentMouseState.LeftButton == ButtonState.Pressed);
case MouseButtons.MiddleButton:
return (
_lastMouseState.MiddleButton == ButtonState.Released &&
_currentMouseState.MiddleButton == ButtonState.Pressed);
case MouseButtons.RightButton:
return (
_lastMouseState.RightButton == ButtonState.Released &&
_currentMouseState.RightButton == ButtonState.Pressed);
case MouseButtons.ExtraButton1:
return (
_lastMouseState.XButton1 == ButtonState.Released &&
_currentMouseState.XButton1 == ButtonState.Pressed);
case MouseButtons.ExtraButton2:
return (
_lastMouseState.XButton2 == ButtonState.Released &&
_currentMouseState.XButton2 == ButtonState.Pressed);
default:
return false;
}
}
/// <summary>
/// Checks if the requested mosue button is a current press.
/// </summary>
/// <param name="button">
/// the mouse button to be checked.
/// </param>
/// <returns>
/// a bool indicating whether the selected mouse button is being
/// pressed in the current state and in the last state.
/// </returns>
public bool IsCurPress(MouseButtons button)
{
switch (button)
{
case MouseButtons.LeftButton:
return (
_lastMouseState.LeftButton == ButtonState.Pressed &&
_currentMouseState.LeftButton == ButtonState.Pressed);
case MouseButtons.MiddleButton:
return (
_lastMouseState.MiddleButton == ButtonState.Pressed &&
_currentMouseState.MiddleButton == ButtonState.Pressed);
case MouseButtons.RightButton:
return (
_lastMouseState.RightButton == ButtonState.Pressed &&
_currentMouseState.RightButton == ButtonState.Pressed);
case MouseButtons.ExtraButton1:
return (
_lastMouseState.XButton1 == ButtonState.Pressed &&
_currentMouseState.XButton1 == ButtonState.Pressed);
case MouseButtons.ExtraButton2:
return (
_lastMouseState.XButton2 == ButtonState.Pressed &&
_currentMouseState.XButton2 == ButtonState.Pressed);
default:
return false;
}
}
/// <summary>
/// Checks if the requested mosue button is an old press.
/// </summary>
/// <param name="button">
/// the mouse button to check.
/// </param>
/// <returns>
/// a bool indicating whether the selected mouse button is not being
/// pressed in the current state and is being pressed in the old state.
/// </returns>
public bool IsOldPress(MouseButtons button)
{
switch (button)
{
case MouseButtons.LeftButton:
return (
_lastMouseState.LeftButton == ButtonState.Pressed &&
_currentMouseState.LeftButton == ButtonState.Released);
case MouseButtons.MiddleButton:
return (
_lastMouseState.MiddleButton == ButtonState.Pressed &&
_currentMouseState.MiddleButton == ButtonState.Released);
case MouseButtons.RightButton:
return (
_lastMouseState.RightButton == ButtonState.Pressed &&
_currentMouseState.RightButton == ButtonState.Released);
case MouseButtons.ExtraButton1:
return (
_lastMouseState.XButton1 == ButtonState.Pressed &&
_currentMouseState.XButton1 == ButtonState.Released);
case MouseButtons.ExtraButton2:
return (
_lastMouseState.XButton2 == ButtonState.Pressed &&
_currentMouseState.XButton2 == ButtonState.Released);
default:
return false;
}
}
#endif
}
}
Po prostu skopiuj ją do oddzielnej klasy fie i przenieś do swojej przestrzeni nazw, następnie zadeklaruj jedną (zmienną inputHelper), zainicjalizuj ją w części inicjalizacyjnej i wywołaj inputHelper.Update() w pętli aktualizacji przed logiką aktualizacji. Wtedy, gdy potrzebujesz czegoś związanego z wejściem, po prostu użyj InputHelper! na przykład, w twojej sytuacji, użyj InputHelper.IsNewPress ([type of input button / key here]), aby sprawdzić, czy chcesz przesunąć element menu w dół lub w górę. Dla tego przykładu: inputHelper.IsNewPress(Słow.Down)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-02-01 00:00:21
Najlepszym sposobem na zaimplementowanie tego jest buforowanie stanu klawiatury/gamepada z instrukcji aktualizacji, która właśnie przeszła.
KeyboardState oldState;
...
var newState = Keyboard.GetState();
if (newState.IsKeyDown(Keys.Down) && !oldState.IsKeyDown(Keys.Down))
{
// the player just pressed down
}
else if (newState.IsKeyDown(Keys.Down) && oldState.IsKeyDown(Keys.Down))
{
// the player is holding the key down
}
else if (!newState.IsKeyDown(Keys.Down) && oldState.IsKeyDown(Keys.Down))
{
// the player was holding the key down, but has just let it go
}
oldState = newState;
W Twoim przypadku prawdopodobnie chcesz przesunąć się "w dół" tylko w pierwszym przypadku powyżej, gdy klawisz został naciśnięty.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-04 00:51:09
Dobrym sposobem radzenia sobie z tego rodzaju rzeczami jest przechowywanie licznika dla każdego klucza, który Cię interesuje, który zwiększasz każdą klatkę, jeśli klucz jest w dół, i resetujesz do 0, jeśli jest w górę.
Zaletą tego jest to, że możesz sprawdzić zarówno stan bezwzględny klawisza (jeśli licznik jest niezerowy, Klawisz jest w dół), a także łatwo sprawdzić, czy właśnie naciśnięto tę ramkę dla menu i tym podobnych (licznik jest 1). Plus powtarzanie klawiszy staje się łatwe (licznik % opóźnienia powtarzania wynosi zero).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-26 12:02:31
Jeśli Twoja aplikacja jest dla komputera z systemem Windows, odniosłem wielki sukces używając tej klasy opartej na zdarzeniach, którą znalazłem tutaj: gamedev.net post na forum
Obsługuje typowe naciśnięcia klawiszy i krótkie przerwy przed rozpoczęciem powtarzania, podobnie jak normalne wprowadzanie tekstu w aplikacji Windows. W zestawie znajdują się również zdarzenia związane z ruchem myszy/kółkiem.
Możesz subskrybować wydarzenia, na przykład, używając następującego kodu:
InputSystem.KeyDown += new KeyEventHandler(KeyDownFunction);
InputSystem.KeyUp += new KeyEventHandler(KeyUpFunction);
Następnie w metodach siebie:
void KeyDownFunction(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.F)
facepalm();
}
void KeyUpFunction(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.F)
release();
}
...i tak dalej. To naprawdę świetna Klasa. Zauważyłem, że jego elastyczność znacznie poprawiła się w porównaniu z domyślną Obsługą klawiatury XNA. Powodzenia!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-04 01:11:25
Myślałem, że poprzednie odpowiedzi były trochę zbyt skomplikowane, więc podaję tę tutaj...
Skopiuj poniższą klasę klawiatury do nowego pliku, zadeklaruj zmienne klawiatury, zainicjalizuj je metodą Initialize (). Stamtąd możesz zrobić if ([yourkey].IsPressed()) ...
Uwaga: ta odpowiedź działa tylko dla wejścia z klawiatury, ale powinna być łatwo przeniesiona na Gamepad lub inne wejście. Myślę, że oddzielenie kodu dla poszczególnych typów wejść jest lepiej.
public class KeyPress
{
public KeyPress(Keys Key)
{
key = Key;
isHeld = false;
}
public bool IsPressed { get { return isPressed(); } }
public static void Update() { state = Keyboard.GetState(); }
private Keys key;
private bool isHeld;
private static KeyboardState state;
private bool isPressed()
{
if (state.IsKeyDown(key))
{
if (isHeld) return false;
else
{
isHeld = true;
return true;
}
}
else
{
if (isHeld) isHeld = false;
return false;
}
}
}
Użycie:
// Declare variable
KeyPress escape;
// Initialize()
escape = new KeyPress(Keys.Escape)
// Update()
KeyPress.Update();
if (escape.IsPressed())
...
Mogę się mylić, ale myślę, że moja odpowiedź jest łatwiejsza w zasobach niż zaakceptowana odpowiedź, a także bardziej czytelna!
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-14 17:22:29
Można zapisać wartość całkowitą time od ostatniego naciśniętego klawisza (w lewo,w prawo...), a jeśli ten czas jest większy niż jakiś limit, możesz przeszukiwać nowy klawisz wciśnięty. Jednak można to zrobić tylko dla menu, ponieważ w grze będziesz potrzebował tej informacji natychmiast.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-24 19:47:17
Możesz również zrobić sobie funkcję łączącą KyeUp i KeyDown, która informuje, kiedy klawisz został naciśnięty raz, tylko w 1 pętli aktualizacji, tak, że działa tylko za każdym razem, gdy naciśniesz klawisz ponownie.
Ok, rozgryzłem to. Najpierw dodałem
private Keys keyPressed = Keys.None;
I w mojej metodzie Update () wykonuję następujące czynności:
KeyboardState keyboardState = Keyboard.GetState();
if (keyboardState.IsKeyUp(keyPressed))
{
keyPressed = Keys.None;
}
if (keyboardState.IsKeyDown(keyPressed))
{
return;
}
// Some additionnal stuff is done according to direction
if (keyboardState.IsKeyDown(Keys.Up))
{
keyPressed = Keys.Up;
}
else if (keyboardState.IsKeyDown(Keys.Down))
{
keyPressed = Keys.Down;
}
Wygląda na to, że działa poprawnie.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-25 22:13:16
Zapisuję GamePadState i KeyboardState z poprzedniej aktualizacji. Przy następnym uruchomieniu aktualizacji sprawdzam przyciski, które nie zostały naciśnięte w ostatnim uruchomieniu, ale są naciśnięte teraz. Następnie zapisuję aktualny stan.
Mam to wszystko zapakowane w statyczną klasę, której mogę użyć do odpytywania o konkretne przyciski i / lub uzyskania listy przycisków od ostatniej aktualizacji. To sprawia, że naprawdę łatwo pracować z wieloma klawiszami jednocześnie (coś, co na pewno chcesz w grach) i byłoby trywialnie rozszerzalny na akordy.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-26 08:46:42
Ranieri, Jak to wygląda? Ciężko mi żonglować tymi cyklami aktualizacji...
Hrmmm...
public static bool CheckKeyPress(Keys key)
{
return keyboardState.IsKeyUp(key) && lastKeyboardState.IsKeyDown(key);
}
SetStates () jest prywatna i jest wywoływana w update ()
private static void SetStates()
{
lastKeyboardState = keyboardState;
keyboardState = Keyboard.GetState();
}
Oto aktualizacja...
public sealed override void Update(GameTime gameTime)
{
// Called to set the states of the input devices
SetStates();
base.Update(gameTime);
}
Próbowałem dodać dodatkowe czeki..
if (Xin.CheckKeyPress(Keys.Enter) ||
Xin.CheckButtonPress(Buttons.A))
{
if (Xin.LastKeyboardState != Xin.KeyboardState ||
Xin.LastGamePadState(PlayerIndex.One) != Xin.GamePadState(PlayerIndex.One))
{
Nie wydaje się mieć żadnych zauważalnych efektów - nie mogę spowolnić potwierdzenia menu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-19 20:06:34
Cóż, co można zrobić, to coś takiego (również będzie śledzić każdy klucz)
int[] keyVals;
TimeSpan pressWait = new TimeSpan(0, 0, 1);
Dictionary<Keys, bool> keyDowns = new Dictionary<Keys, bool>();
Dictionary<Keys, DateTime> keyTimes = new Dictionary<Keys, DateTime>();
public ConstructorNameHere
{
keyVals = Enum.GetValues(typeof(Keys)) as int[];
foreach (int k in keyVals)
{
keyDowns.Add((Keys)k, false);
keyTimes.Add((Keys)k, new DateTime()+ new TimeSpan(1,0,0));
}
}
protected override void Update(GameTime gameTime)
{
foreach (int i in keyVals)
{
Keys key = (Keys)i;
switch (key)
{
case Keys.Enter:
keyTimes[key] = (Keyboard.GetState().IsKeyUp(key)) ? ((keyDowns[key]) ? DateTime.Now + pressWait : keyTimes[key]) : keyTimes[key];
keyDowns[key] = (keyTimes[key] > DateTime.Now) ? false : Keyboard.GetState().IsKeyDown(key);
if (keyTimes[key] < DateTime.Now)
{
// Code for what happens when Keys.Enter is pressed goes here.
}
break;
}
}
Robiąc to w ten sposób, możesz sprawdzić każdy klucz. Można to również zrobić dla każdego klucza, tworząc oddzielne wartości DateTimes
i seperate bool
.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-22 07:12:58
Wiem, że to stare, ale co powiesz na: Dodaj słownik threadsafe:
private ConcurrentDictionary<Keys, DateTime> _keyBounceDict = new ConcurrentDictionary<Keys, DateTime>();
Następnie użyj tej metody, aby śledzić naciśnięte klawisze i określić, czy istnieje odbicie klawisza:
///////////////////////////////////////////////////////////////////////////////////////////
/// IsNotKeyBounce - determines if a key is bouncing and therefore not valid within
/// a certain "delay" period
///////////////////////////////////////////////////////////////////////////////////////////
private bool IsNotKeyBounce(Keys thekey, double delay)
{
bool OKtoPress = true;
if (_keyBounceDict.ContainsKey(thekey))
{
TimeSpan ts = DateTime.Now - _keyBounceDict[thekey];
if (ts.TotalMilliseconds < _tsKeyBounceTiming)
{
OKtoPress = false;
}
else
{
DateTime dummy;
_keyBounceDict.TryRemove(thekey, out dummy);
}
}
else
{
_keyBounceDict.AddOrUpdate(thekey, DateTime.Now, (key, oldValue) => oldValue);
}
return OKtoPress;
}
Oto co umieściłem w mojej metodzie aktualizacji:
if (Keyboard.GetState().IsKeyDown(Keys.W))
{
if (IsNotKeyBounce(Keys.W, 50.0)) _targetNew.Distance *= 1.1f;
}
Używam 50 ms, ale możesz użyć tego, co ma sens dla Twojej aplikacji lub powiązać ją z GameTime lub czymkolwiek...
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-13 15:07:09