Search code examples
vb.netcollisionkeypress

Visual Basic - event until on keypress


First off, I am really sorry about the vague title. I am pretty knew to stack overflow and I have no idea how to phrase this question. What I want is on a key press (say the up arrow) I want to move a picture box across the windows form until it collides with a separate picture box. Here's my code so far.

Private Async Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
    Select Case e.KeyCode
        Case Keys.Left
            Me.pBox1.Left -= 20
        Case Keys.Up
            Me.pBox1.Top -= 20
        Case Keys.Right
            Me.pBox1.Left += 20

        Case Keys.Down
            Me.pBox1.Top += 20

    End Select

That's not all the code, just the important part. Basically, on a key press, the picture box moves across the form. But, I have to continually hold down the key to keep it moving. What I want is to press a key, and have the picture box to move across the screen until it hits another picture box.

P.S. I already have the collision code. (pBox1.Bounds.IntersectsWith(pBox2.Bounds)) Please keep in mind that I am pretty knew to visual basic and stack overflow.


Solution

  • you can create a subroutine which contains the moving of the picturebox as well as detection logic. call it from inside Form1_keyDown(). Key things to remember:

    1. use loop to simulate the moving instruction of clicking.
    2. use thread.sleep to create delay effect
    3. while picturebox is moving, use 'inTheMiddleOfMoving' flag to make sure that pressing any arrow keys have no effect (exit the subroutine).
    4. exit the loop either when hitting picturebox2, or wait a certain timespan (this is important)

      Select Case e.KeyCode
          Case Keys.Left
              MovePictureBox(pbox1, pbox2, 20, KeyMovingDirection.Left)
      ...
      
      Public Enum KeyMovingDirection
        Left
        Right
        Top
        Bottom
      End Enum
      
      
      Private inTheMiddleOfMoving As Boolean = False
      Public Sub MovePictureBox(pbox1 As PictureBox, pbox2 As PictureBox, stepA 
         As Integer, direction As KeyMovingDirection)
      
        If inTheMiddleOfMoving Then Exit Sub
      
        Dim collided As Boolean = False
        Dim t As New Stopwatch
        t.Start()
        Do
          Select Case direction
              Case KeyMovingDirection.Left
                  pbox1.Left -= stepA
              Case KeyMovingDirection.Right
                  pbox1.Left += stepA
              Case KeyMovingDirection.Top
                  pbox1.Top -= stepA
              Case KeyMovingDirection.Bottom
                  pbox1.Top += stepA
          End Select
          inTheMiddleOfMoving = True
      
          Threading.Thread.Sleep(200)
          If pbox1.Bounds.IntersectsWith(pbox2.Bounds) OrElse t.ElapsedMilliseconds > 5000 Then
              '...
              collided = True
          End If
        Loop Until collided
        t.Stop()
         inTheMiddleOfMoving = False
       End Sub