Xna jak na Input – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Xna jak na Input – .NET – Fórum – Programujte.comXna jak na Input – .NET – Fórum – Programujte.com

 

Belze
~ Anonymní uživatel
23 příspěvků
21. 5. 2012   #1
-
0
-

Zdravim

Narazil jsem na problem s inputem z klavesnice u XNA. Jde o to ze kdyz uzivatel je napr. v menu a stiskne enter tak se program sam od sebe "proklika" az na konec. Tento problem jsem vyresil jednoduchym 

if (newState.IsKeyDown(Keys.Enter) && !oldState.IsKeyDown(Keys.Enter))

Ale tam nastala chyba cislo 2. Kvuli tomu ze se cely program projede kazdych cca 17ms se pomerne casto stane ze program vubec nestaci zareagovat na stisk klavesy. Hodne jsem hledal na internetu a zjistil jsem ze moznym resenim je vytvorenim jakesi tridy ktera funguje jako Buffer a ulozi si stisk klavesy a tady je prave ta vec vubec nechapu jak takovou tridu pouzit, kdyz mam takovyto kod a stisknu treba "f" tak mi to vypise "F5"  a kdyz budu pouzivat odpoznamkovany TextBuffer tak vse vypisuje v poradku nevite nekdo nahodou jak vyresit tento problem s bufferem ?

   private void CharacterEntered(object sender, EventInput.CharacterEventArgs e)        {
            // Add key to text buffer. If not a symbol key.
            if (!((int)e.Character < 32 || (int)e.Character > 126)) //From space to tilde
            {
                // Capitals are already supported in DLL so we don't have to worry about checking shift
                if (!(Keyboard.GetState().IsKeyDown(Keys.LeftControl) || Keyboard.GetState().IsKeyDown(Keys.RightControl)))
                {
                   ks.Add((Keys)e.Character);
                    //TextBuffer += e.Character;
                }
            }

            // Backspace - remove character if there are any
            if ((int)e.Character == 0x08 && TextBuffer.Length > 0)
            {
                ks.RemoveAt(ks.Count - 1);
               // TextBuffer = TextBuffer.Remove(TextBuffer.Length - 1);
            }
        }

Dekuji za rady doufam ze jsem vse vysvetlil dobre.

Nahlásit jako SPAM
IP: 90.180.234.–
Belze
~ Anonymní uživatel
23 příspěvků
21. 5. 2012   #2
-
0
-

#1 Belze 
Jen poznamka

List<Keys> ks = new List<Keys>();
Nahlásit jako SPAM
IP: 90.180.234.–
zlz
~ Anonymní uživatel
634 příspěvků
21. 5. 2012   #3
-
0
-

Co vypíše to "F5" ?

Ten prvotní pokus je správným směrem, ale pak tam někde máš ještě něco špatně. Ten buffer pro tebe asi bude nejschůdnější řešení.

Když z nějakého důvodu nemůžeš/nechceš zpracovat klávesu tam, kde ji detekuješ (Update) a ukládáš si ji do bufferu, tak prostě pak ty klávesy zjišťuješ (a odstaňuješ) z toho bufferu.

Nahlásit jako SPAM
IP: 80.188.216.–
Belze
~ Anonymní uživatel
23 příspěvků
21. 5. 2012   #4
-
0
-

stiskem klavesy ''t'' to vypise F5 , zajimavy je ze kdyz podrzim "Shift" + "t" tak to vypise normalne "T"

Nahlásit jako SPAM
IP: 90.180.234.–
Belze
~ Anonymní uživatel
23 příspěvků
21. 5. 2012   #5
-
0
-

#4 Belze

Aha ted jsem prisel na to v cem je chyba, do Keys nemuzu ulozit male pismena, muze mit hodnoty pouze velka pismena

Nahlásit jako SPAM
IP: 90.180.234.–
Belze
~ Anonymní uživatel
23 příspěvků
22. 5. 2012   #6
-
0
-

Tak uz mne vazne nenapada jak na ten input buffer, Opravdu bych ocenil kdyby sem nekdo mohl dat odkaz na nejaky funkcni kod i s vysvetlenim jak ten kod pouzit, nebo clanek podle ktereho bych si takovy buffer dokazal udelat i ja jako zacatecnik

Nahlásit jako SPAM
IP: 85.132.158.–
zlz
~ Anonymní uživatel
634 příspěvků
22. 5. 2012   #7
-
0
-

#5 Belze
Keys nejsou malá ani velká písmena ale klávesy. A hodnoty některých znaků jsou náhodou "odpovídající" hodnoty Keys.

Jestli chceš bufferovat Keys, tak asi bude lepší místo CharEntered zkusit použít třeba KeyDown, nebo tak něco.

Funkční kód bez kravin je přímo v dokumentaci - Detecting a Key Press (Windows, Windows Phone, Xbox 360)

Nahlásit jako SPAM
IP: 80.188.216.–
Belze
~ Anonymní uživatel
23 příspěvků
22. 5. 2012   #8
-
0
-

#7 zlz
no ano o tom kodu v dokumentaci samozrejme vim ale u toho je prave ten problem ze program snima klavesnici kazdych 17 ms a tudiz vynecha nektere znaky pokud pisete dost rychle, jednim resenim by bylo nelimitovat FPS hry ale je zbytecne aby hra mela 200fps jen kvuli spatnemu inputu a druhym resenim je prave vytvorit si buffer.

Tady na teto strance se snazili tento problem vyresit dali tam udajne funkcni kod ale uplne bez jakychkoliv popisku nebo navodu jak presne ho pouzit, proto jsem se obratil tady na forum jestli s tim nekdo nema uz nejake zkusenosti a neporadil by

Nahlásit jako SPAM
IP: 90.180.234.–
zlz
~ Anonymní uživatel
634 příspěvků
23. 5. 2012   #9
-
0
-

Nevím teda co je to za aplikaci, ale pochybuju, že by normální člověk při pohybu potřeboval odezvu pod ~17 ms. A když jsi řešil problém s tím, že jsi jeden stisk zaregistroval několikrát a nejednou ho nezaregistruješ vůbec, tak si spíš myslím, že problém bude úplně jinde a zbytečně si to komplikuješ. Ukaž víc kódu.

Nahlásit jako SPAM
IP: 80.188.216.–
Belze
~ Anonymní uživatel
23 příspěvků
23. 5. 2012   #10
-
0
-

prave ze XNA se dobre hodi na pohyb, protoze "vidi" jestli je tlacitko stlaceno a dokud je stlaceno tak treba hybe postavou, ale uz se nehodi na psani textu, protoze nema zadny buffer jako klasicky c#.

using System;
using System.Runtime.InteropServices;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace EventInput
{

    /// <summary>
    ///  CREDITS INFINIMINER
    ///  http://code.google.com/p/infiniminer/
    /// </summary>
    public class CharacterEventArgs : EventArgs
    {
        private readonly char character;
        private readonly int lParam;

        public CharacterEventArgs(char character, int lParam)
        {
            this.character = character;
            this.lParam = lParam;
        }

        public char Character
        {
            get { return character; }
        }

        public int Param
        {
            get { return lParam; }
        }

        public int RepeatCount
        {
            get { return lParam & 0xffff; }
        }

        public bool ExtendedKey
        {
            get { return (lParam & (1 << 24)) > 0; }
        }

        public bool AltPressed
        {
            get { return (lParam & (1 << 29)) > 0; }
        }

        public bool PreviousState
        {
            get { return (lParam & (1 << 30)) > 0; }
        }

        public bool TransitionState
        {
            get { return (lParam & (1 << 31)) > 0; }
        }
    }

    public class KeyEventArgs : EventArgs
    {
        private Keys keyCode;

        public KeyEventArgs(Keys keyCode)
        {
            this.keyCode = keyCode;
        }

        public Keys KeyCode
        {
            get { return keyCode; }
        }
    }

    public delegate void CharEnteredHandler(object sender, CharacterEventArgs e);
    public delegate void KeyEventHandler(object sender, KeyEventArgs e);

    public static class EventInput
    {
        /// <summary>
        /// Event raised when a character has been entered.
        /// </summary>
        public static event CharEnteredHandler CharEntered;

        /// <summary>
        /// Event raised when a key has been pressed down. May fire multiple times due to keyboard repeat.
        /// </summary>
        public static event KeyEventHandler KeyDown;

        /// <summary>
        /// Event raised when a key has been released.
        /// </summary>
        public static event KeyEventHandler KeyUp;

        delegate IntPtr WndProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam);

        static bool initialized;
        static IntPtr prevWndProc;
        static WndProc hookProcDelegate;
        static IntPtr hIMC;

        //various Win32 constants that we need
        const int GWL_WNDPROC = -4;
        const int WM_KEYDOWN = 0x100;
        const int WM_KEYUP = 0x101;
        const int WM_CHAR = 0x102;
        const int WM_IME_SETCONTEXT = 0x0281;
        const int WM_INPUTLANGCHANGE = 0x51;
        const int WM_GETDLGCODE = 0x87;
        const int WM_IME_COMPOSITION = 0x10f;
        const int DLGC_WANTALLKEYS = 4;

        //Win32 functions that we're using
        [DllImport("Imm32.dll")]
        static extern IntPtr ImmGetContext(IntPtr hWnd);

        [DllImport("Imm32.dll")]
        static extern IntPtr ImmAssociateContext(IntPtr hWnd, IntPtr hIMC);

        [DllImport("user32.dll")]
        static extern IntPtr CallWindowProc(IntPtr lpPrevWndFunc, IntPtr hWnd, uint Msg, IntPtr wParam, IntPtr lParam);

        [DllImport("user32.dll")]
        static extern int SetWindowLong(IntPtr hWnd, int nIndex, int dwNewLong);

        /// <summary>
        /// Initialize the TextInput with the given GameWindow.
        /// </summary>
        /// <param name="window">The XNA window to which text input should be linked.</param>
        public static void Initialize(GameWindow window)
        {
            if (initialized)
                throw new InvalidOperationException("TextInput.Initialize can only be called once!");

            hookProcDelegate = new WndProc(HookProc);
            prevWndProc = (IntPtr)SetWindowLong(window.Handle, GWL_WNDPROC,
                (int)Marshal.GetFunctionPointerForDelegate(hookProcDelegate));

            hIMC = ImmGetContext(window.Handle);
            initialized = true;
        }

        static IntPtr HookProc(IntPtr hWnd, uint msg, IntPtr wParam, IntPtr lParam)
        {
            IntPtr returnCode = CallWindowProc(prevWndProc, hWnd, msg, wParam, lParam);

            switch (msg)
            {
                case WM_GETDLGCODE:
                    returnCode = (IntPtr)(returnCode.ToInt32() | DLGC_WANTALLKEYS);
                    break;

                case WM_KEYDOWN:
                    if (KeyDown != null)
                        KeyDown(null, new KeyEventArgs((Keys)wParam));
                    break;

                case WM_KEYUP:
                    if (KeyUp != null)
                        KeyUp(null, new KeyEventArgs((Keys)wParam));
                    break;

                case WM_CHAR:
                    if (CharEntered != null)
                        CharEntered(null, new CharacterEventArgs((char)wParam, lParam.ToInt32()));
                    break;

                case WM_IME_SETCONTEXT:
                    if (wParam.ToInt32() == 1)
                        ImmAssociateContext(hWnd, hIMC);
                    break;

                case WM_INPUTLANGCHANGE:
                    ImmAssociateContext(hWnd, hIMC);
                    returnCode = (IntPtr)1;
                    break;
            }

            return returnCode;
        }
    }
}

tohle je trida toho bufferu

Nahlásit jako SPAM
IP: 85.132.158.–
zlz
~ Anonymní uživatel
634 příspěvků
24. 5. 2012   #11
-
0
-

O to mi právě šlo, jestli potřebuješ zpracovávat rychlé psaní nebo něco podobného.

Jsme zpátky u #7, CharEntered dostává znaky. Jestli tě zajímají klávesy, tak použij KeyDown/KeyUp.

Nahlásit jako SPAM
IP: 80.188.216.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 35 hostů

Podobná vlákna

Jak se naučit xna — založil James Extreme

Jak zopakovat uživatelský input — založil Začátečník JKs

Input a input type — založil

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý