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.

 21
Author: tomzx, 2009-05-24

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)

 18
Author: RCIX,
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.

 26
Author: Joel Martinez,
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).

 6
Author: James Sutherland,
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!

 3
Author: bufferz,
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!

 1
Author: AceShot,
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.

 0
Author: mnn,
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.

 0
Author: ,
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 12:08:32

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.
 0
Author: tomzx,
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.

 0
Author: drxzcl,
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,

 0
Author: Bixel,
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.
 0
Author: Jake,
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...

 0
Author: Mikla,
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