The problem here is that you are never going out from the Character_KeyDown
handler does not terminate. Because of that, your bit of code in the Character_KeyUp
is never executed.
The root issue that you may not realize is that you only have a single UI thread (at least in all UI frameworks that I know such has been the case), and you are monopolizing it with your for
loop.
In order to do the right thing, something like WPF's Dispatcher.BeginInvoke
, or DispatcherTimer
can be used. (If you use WPF). If you can tell us which UI framework you are using, we might be able to come up with a satisfactory code sample.
Here is how you might do it with a DispatcherTimer
in WPF:
// Add that field to your class.
private readonly DispatcherTimer moveLeftTimer;
// In the constructor, add the lines inside:
YourClassName() // This line is a stub - I do not know your class name.
{
moveLeftTimer = new DispatcherTimer()
{
Interval = TimeSpan.FromMilliseconds(50)
};
moveLeftTimer.Tick += MoveLeft;
}
private void MoveLeft(object source, EventArgs e)
{
Character.Left -= XSpeed;
}
private void Character_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.A)
{
moveLeftTimer.IsEnabled = true;
}
}
private void Character_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.A)
{
moveLeftTimer.IsEnabled = false;
}
}
In order to adapt for Windows Forms, use the Timer
class instead of DispatcherTimer
, and the property is named Enabled
instead of IsEnabled
.