Come ottenere il tempo trascorso di pressione dei tasti?


8

Devo essere in grado di determinare da quanto tempo viene tenuto premuto un tasto con elevata precisione. Ad esempio, se toccano i tasti molto velocemente, potrebbe indicare un tempo inferiore a quello di ciascun frame di aggiornamento.


Sulla base degli altri tuoi commenti, devo chiederti, l'accuratezza di ~ 16ms è effettivamente dannosa per il tuo gioco? Praticamente tutti i giochi che io abbia mai fatto non si sono preoccupati dell'input sulla scala dei sub-frame. Forse ci sono altre cose che fanno stare male il gioco (cosa che presumo lo faccia, altrimenti perché me lo chiedi?)
Tetrad

1
Sai, i giochi di Mario non avevano bisogno della precisione del sub-frame per ottenere la "scheda rapida per il salto in basso, la pressione completa per il salto in alto". Meglio aggiungere un vettore di accelerazione per i primi 2-3 fotogrammi del salto.
Kyte,


@Andrew Russel: questa dovrebbe essere la risposta.
Michael Coleman,

Risposte:


4

È possibile acquisire l'input utilizzando la classe System.Windows.Forms.NativeWindow. Riceverai una notifica quando si verifica un evento di input. In questo modo verrai avvisato il più rapidamente possibile al momento opportuno, consentendoti di registrare l'ora con una precisione maggiore. Diventa un po 'disordinato (codice nativo / non sicuro), ma funziona.

Penso che questo funzioni solo su Windows, ma penso che sia la piattaforma di destinazione (non è necessario su Xbox e WP7).

Ecco un buon esempio (dal framework nuclex): WindowInputCapturer (nota: questo codice potrebbe essere stato aggiornato di recente e non l'ho scritto )

Modifica: questo consente anche di ottenere il codice carattere della pressione del tasto. Questo potrebbe essere utile per prendere input di testo (specialmente cose come i caratteri latini) Non sono sicuro del motivo per cui dovresti ottenere input con una precisione così elevata, ma questo sarebbe un buon modo per farlo secondo me.


2

XNA è un framework basato su loop, non un framework basato su eventi. Se è necessario il momento esatto in cui si è verificato un evento, prendere in considerazione un progetto winforms (un progetto basato su eventi) e, se necessario, collegare XNA a un controllo per il rendering.


1

Memorizza lo stato chiave in una variabile e confrontalo nel ciclo successivo con gli stati chiave correnti. Crea un DateTimeoggetto per contenere l'inizio e puoi confrontarlo con DateTime.Nowquando lo stato chiave precedente non corrisponde.

Esempio molto semplice di cosa intendo:

   if(currentKeyboardState.IsKeyDown(Keys.Space)
      && !previousKeyboardState.IsKeyDown(Key.Space))
      { DateTime startTime = DateTime.Now; }
    ...
    if(!currentKeyboardState.IsKeyDown(Keys.Space)
      && previousKeyboardState.IsKeyDown(Key.Space))
      { TimeSpan elapsedTime = DateTime.Now - startTime; }

Ho chiesto specificamente qualcosa che possa darmi un tempo inferiore a quello di ogni aggiornamento. La tua risposta mi darà solo tempo con incrementi di 16 ms.
AttackingHobo

1
Quindi eseguilo nel suo thread. XNA non ha un gestore eventi per le modifiche alla tastiera.
riv_rec,

DateTime.Now ha una risoluzione peggiore dell'aggiornamento, però. Prova il cronometro.
Kyte,

0

Non sono a conoscenza di alcun modo ufficiale per farlo, potresti eseguire un secondo thread in un ciclo molto stretto solo per controllare l'input e inviarlo a un buffer circolare sufficientemente grande da richiedere una sincronizzazione molto piccola tra i thread.

(Conserva una sorta di numero crescente in ogni slot del buffer e aggiorna che DOPO il thread ha scritto tutti i dati, quindi continua a leggere gli slot con i dati dal buffer fino a quando il numero non diminuisce (non dimenticare di verificare la presenza di numeri straripanti!))


0

Se aggiorni trenta volte al secondo, un essere umano non sarà in grado di premere i tasti più velocemente di quanto tu possa campionare lo stato della tastiera. Se aggiorni più lentamente di quanto un umano possa digitare, potresti aver bisogno di un thread per il rendering della grafica e un altro thread per leggere e rispondere alla tastiera / mouse.

Tuttavia, se si aggiorna più lentamente di quanto un umano possa digitare, non è possibile fornire un feedback visivo per ogni pressione di un tasto. Questo non importa se l'idea è quella di visualizzare un feedback aggregato, come il tempo medio tra la pressione dei tasti.


Non ho mai detto nulla sulla digitazione. Voglio sapere quando è stato premuto un tasto, i millisecondi esatti.
Attacco di

E in realtà un essere umano può digitare a una velocità superiore a 30 tasti al secondo, ma solo in una sequenza di poche chiavi, non a una velocità sostenuta.
Attacco di

Se aggiorni sessanta volte al secondo, ottieni una precisione di 16ms. Che precisione hai bisogno e perché?
bmcnett,

Per il movimento del giocatore, voglio che l'utente sia in grado di toccare una volta rapidamente e di muovere il giocatore per meno di 1 pressione completa.
Attacco di

@AttackingHobo Non potresti usare le equazioni del movimento per questo? Mentre viene tenuto premuto, applicare un vettore di accelerazione a un vettore di velocità? Più a lungo viene tenuto premuto, maggiore è la velocità?
Ray Dey,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.