¿Cómo obtener el tiempo transcurrido de la pulsación de teclas?

8

Necesito poder determinar cuánto tiempo se ha mantenido presionada una tecla con alta precisión. Por ejemplo, si presionaron la tecla muy rápido, podría informar un tiempo que es menor que el tiempo para cada marco de actualización.

AttackingHobo
fuente
De acuerdo con sus otros comentarios, debo preguntar, ¿obtener una precisión de ~ 16 ms es realmente perjudicial para su juego? Casi todos los juegos que he hecho nunca se han molestado con la entrada en la escala de subtrama. Tal vez hay otras cosas que hacen que el juego se sienta mal (lo que supongo que sí, de lo contrario, ¿por qué lo preguntas?)
Tetrad
1
Ya sabes, los juegos de Mario no necesitaban una precisión de subcuadro para lograr lo de "pestaña rápida para salto bajo, presión completa para salto alto". Mejor agregue un vector de aceleración para los primeros 2-3 cuadros del salto.
Kyte
@ Andrew Russel: esa debería ser la respuesta.
Michael Coleman

Respuestas:

4

Puede capturar la entrada utilizando la clase System.Windows.Forms.NativeWindow. Recibirá una notificación cuando ocurra un evento de entrada. De esa manera, se le notificará lo más rápido posible cuando ocurra, lo que le permitirá registrar el tiempo con mayor precisión. Se pone un poco desordenado (código nativo / inseguro), pero funciona.

Creo que esto solo funciona en Windows, pero creo que esa es la plataforma a la que apunta (no es necesario para esto en Xbox y WP7).

Aquí hay un buen ejemplo (de nuclex framework): WindowInputCapturer (nota: este código podría haberse actualizado recientemente y no lo codifiqué)

Editar: Esto también le permite obtener el código de caracteres de la tecla presionada. Esto podría ser útil para tomar entradas de texto (especialmente cosas como caracteres latinos). No estoy seguro de por qué necesitaría recibir entradas con una precisión tan alta, pero esta sería una buena forma de hacerlo en mi opinión.

Michael Coleman
fuente
2

XNA es un marco basado en bucle, no un marco basado en eventos. Si necesita la hora exacta en que ocurrió un evento, considere un proyecto winforms (un proyecto basado en eventos) y conecte XNA a un control si es necesario para la representación.

Steve H
fuente
1

Almacene el estado clave en una variable y compárelo en el siguiente ciclo con los estados clave actuales. Cree un DateTimeobjeto para mantener el inicio y pueda compararlo DateTime.Nowcuando el estado de la clave anterior no coincida.

Muy simple ejemplo de lo que quiero decir:

   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; }
riv_rec
fuente
Pedí específicamente algo que pueda darme un tiempo menor que el tiempo de cada actualización. Su respuesta solo me dará tiempo en incrementos de 16 ms.
AttackingHobo
1
Así que ejecuta eso en su propio hilo. XNA no tiene un controlador de eventos para cambios de teclado.
riv_rec
Sin embargo, DateTime.Now tiene una resolución peor que la actualización. Prueba el cronómetro.
Kyte
0

No conozco ninguna forma oficial de hacer esto, podría ejecutar un segundo subproceso en un bucle muy ajustado solo para verificar la entrada y enviar esto a un búfer circular lo suficientemente grande como para requerir muy poca sincronización entre subprocesos.

(Almacene algún tipo de número creciente en cada ranura del búfer y actualícela DESPUÉS de que el hilo haya escrito todos los datos, luego continúe leyendo las ranuras con datos del búfer hasta que el número disminuya (¡no olvide verificar si hay números desbordados!))

Elva
fuente
0

Si actualiza treinta veces por segundo, un humano no podrá presionar teclas más rápido de lo que puede muestrear el estado del teclado. Si actualiza más lentamente de lo que un humano puede escribir, entonces puede necesitar un hilo para representar gráficos y otro hilo para leer y responder al teclado / mouse.

Pero, si actualiza más lentamente de lo que un humano puede escribir, tampoco puede proporcionar comentarios visuales para cada pulsación de tecla. Esto no importa si la idea es mostrar comentarios agregados, como el tiempo promedio entre pulsaciones de teclas.

bmcnett
fuente
Nunca dije nada sobre escribir. Quiero saber cuándo se presionó una tecla, los milisegundos exactos.
AttackingHobo
Y en realidad, un humano puede escribir a una velocidad de más de 30 teclas por segundo, pero solo en una ráfaga de algunas teclas, no a una velocidad sostenida.
AttackingHobo
Si actualiza sesenta veces por segundo, obtendrá una precisión de 16 ms. ¿Qué precisión requiere y por qué?
bmcnett
Para el movimiento del jugador, quiero que el usuario pueda tocar una vez rápidamente y que el jugador se mueva menos de 1 pulsación completa.
AttackingHobo
@AttackingHobo ¿No podrías hacer uso de ecuaciones de movimiento para esto? Mientras se mantiene presionado, ¿aplica un vector de aceleración a un vector de velocidad? Cuanto más tiempo se mantiene presionado, mayor es la velocidad?
Ray Dey