What to use instead of Application.DoEvents in my game?

I create a Space Invaders game with C # WinForms and when coding a player’s gun movement, I create this event handler:

private void Game_Screen_KeyDown(object sender, KeyEventArgs e)
{
    for (int i = 0; i < 500; i++)
    {

        if (e.KeyCode == Keys.Left)
        {
            cannonBox.Location = new Point(cannonBox.Left - 2, cannonBox.Top); //Changes location of cannonBox to a new location to the left
            Application.DoEvents();
            System.Threading.Thread.Sleep(10); //Delays the movement by couple milliseconds to stop instant movement
        }

        if (e.KeyCode == Keys.Right)
        {
            cannonBox.Location = new Point(cannonBox.Left + 2, cannonBox.Top); //Changes location of cannonBox to a new location to the right
            Application.DoEvents();
            System.Threading.Thread.Sleep(10); //Delays the movement by couple milliseconds to stop instant movement
        }

        if (e.KeyCode == Keys.Up)
        {
            createLaser(); //Calls the method whenever Up arrow key is pressed
        }
    }
}

But on different sites regarding how unreliable it is in C #, I'm going to not use it on this. What other alternatives can be used instead of Application.DoEvents in this instance?

+4
source share
3 answers

I suggest making this event handler asyncand using await Task.Delay()instead Thread.Sleep():

private async void Game_Screen_KeyDown(object sender, KeyEventArgs e)
{
    for (int i = 0; i < 500; i++)
    {
        if (e.KeyCode == Keys.Left)
        {
            cannonBox.Location = new Point(cannonBox.Left - 2, cannonBox.Top); //Changes location of cannonBox to a new location to the left
            await Task.Delay(10); //Delays the movement by couple milliseconds to stop instant movement
        }

        if (e.KeyCode == Keys.Right)
        {
            cannonBox.Location = new Point(cannonBox.Left + 2, cannonBox.Top); //Changes location of cannonBox to a new location to the right
            await Task.Delay(10); //Delays the movement by couple milliseconds to stop instant movement
        }

        if (e.KeyCode == Keys.Up)
        {
            createLaser(); //Calls the method whenever Up arrow key is pressed
        }
    }
}

, , ( Application.DoEvents()). , () 10 , .

, , , , . , . , ( , ).
, . "" (, ).


, , async Task .

+5

, 20 .

KeyDown/KeyUp , .

:

[Flags]
public enum ActionState
{
    MoveLeft,
    MeveRight,
    FireLaser,
}

// stores the current state
private ActionState _actionState;

// set action state
private void Game_Screen_KeyDown(object sender, KeyEventArgs e)
{
    switch ( e.KeyCode )
    {
        case Keys.Left:
            _actionState |= ActionState.MoveLeft;
            break;
        case Keys.Right:
            _actionState |= ActionState.MoveRight;
            break;
        case Keys.Up:
            _actionState |= ActionState.FireLaser;
            break;
        default:
            break;
    }
}

// remove action state
private void Game_Screen_KeyUp(object sender, KeyEventArgs e)
{
    switch ( e.KeyCode )
    {
        case Keys.Left:
            _actionState &= ~ActionState.MoveLeft;
            break;
        case Keys.Right:
            _actionState &= ~ActionState.MoveRight;
            break;
        case Keys.Up:
            _actionState &= ~ActionState.FireLaser;
            break;
        default:
            break;
    }
}

// called from a timer every 20 milliseconds
private void Game_Screen_LoopTimer_Tick(object sender, EventArgs e)
{
    if ( _actionState.HasFlag( ActionState.MoveLeft ) && !_actionState.HasFlag( ActionState.MoveRight ) )
    {
        cannonBox.Location = new Point(cannonBox.Left - 2, cannonBox.Top); //Changes location of cannonBox to a new location to the left
    }
    if ( _actionState.HasFlag( ActionState.MoveRight ) && !_actionState.HasFlag( ActionState.MoveLeft ) )
    {
        cannonBox.Location = new Point(cannonBox.Left + 2, cannonBox.Top); //Changes location of cannonBox to a new location to the right
    }
    if ( _actionState.HasFlag( ActionState.FireLaser ) )
    {
        createLaser(); //Calls the method whenever Up arrow key is pressed
    }
}
+2

.DoEvents() , ( ). ...

async ( ) - .

. , , 500 , . , , ...

, while (true) Application.DoEvents.

Or you respond to the key_down event and execute the action at the same time. => press left → move one left → press left again → move once more ... and so on.

https://msdn.microsoft.com/en-us//library/system.windows.forms.application.doevents(v=vs.110).aspx

0
source

Source: https://habr.com/ru/post/1691111/


All Articles