problema System.Timers.Timer con iniziare dopo l'altro tasto viene rilasciato
Domanda
Ho un programma WinForms, dove ho un certo oggetto animato che si muove intorno quando si preme Su, Giù, Sinistra e Destra. Il movimento dell'oggetto è animato all'interno di un timer, che viene chiamata ogni 30 ms. Il timer inizia il KeyDown, e si ferma in caso di evento KeyUp.
Quindi, se tengo ad esempio a sinistra, e poi subito dopo mi rilasciare il tasto sinistro e premere un altro, c'è una piccola pausa (circa mezzo secondo), prima che si muove in quella direzione. Questo problema non viene visualizzata, se tengo lasciato, il rilascio di esso, e attendere un po ', e poi premere a destra. In tal caso, sarebbe spostare subito a destra. Inoltre non viene visualizzato se ho in mano verso il basso a sinistra, e quindi avviare tenendo premuto a destra, mentre io sono ancora in mano lasciato. In tal caso, sarebbe iniziare a muoversi subito a destra, troppo. appare solo il problema, quando ho rilasciare il tasto e premere immediatamente un altro in seguito.
evento KeyDown:
private void form_KeyDown(object sender, KeyEventArgs e)
{
k = 0;
watch.Start();
if (e.KeyCode == Keys.Left)
{
direction = MOVE_LEFT;
}
else if (e.KeyCode == Keys.Right)
{
direction = MOVE_RIGHT;
}
else if (e.KeyCode == Keys.Up)
{
direction = MOVE_UP;
}
else if (e.KeyCode == Keys.Down)
{
direction = MOVE_DOWN;
}
timerMove.Start();
}
evento KeyUp:
private void form_KeyUp(object sender, KeyEventArgs e)
{
timerMove.Stop();
}
evento Timer (movimento animazione)
void charMovement(object sender, System.Timers.ElapsedEventArgs e)
{
if (direction == MOVE_LEFT)
{
timerMove.Interval = 30;
CharSize(11, 15); //mainChar.Size = new System.Drawing.Size(11, 15);
//code for movement
}
else if (direction == MOVE_RIGHT) //... etc. etc.
Soluzione
Il problema non è il timer, ma l'impostazione di pausa di ripetizione della tastiera. Se si tiene premuto un tasto, c'è una pausa tra la prima e la seconda lettera. Una pausa più lunga quindi tra le seguenti lettere. Questo è ciò che si vede.
Si potrebbe dimenticare gli eventi della tastiera e utilizzare un solo cuore timer battito, controllare ciò che si premono i tasti e poi agire su di esso. Sembra WinForms non avere qualcosa di simile GetKeySate , ma si potrebbe P / Invoke la funzione Win32 .
Oppure si potrebbe rotolare la propria versione di GetKeyState e ricordare ciò che le chiavi sono presse in KeyDown e reimpostare la bandiera in KeyUp. Il timer mossa continua a funzionare finché non viene premuto almeno una chiave.
Altri suggerimenti
prova a fare questo se non l'hai ancora fatto
FormName.KeyPreview = true;
Inoltre, utilizzare un solo metodo .. non due .. tendenza è la pressione del tasto sarebbe stato letto due volte in quanto non v'è un alto e un basso ... provare a utilizzare KeyPreview = true; quindi utilizzare KeyPress invece di KeyDown e KeyUp