Keep picture box from leaving form using keydown event

shaz1

Member
Joined
Jul 22, 2013
Messages
9
Programming Experience
Beginner
I am having difficulties with getting a picture box to not go off the form in any of the 4 directions (left, right, up, down) using a Key Down Event. I have sourced a useful function from this site but am still having a bit of difficulty. This is what I have so far: The function looks great but I am not sure where to put it in my location changed code.

PublicClass Form1
Dim vx As Single = 1.0
Dim vy As Single = 1.0
Private Sub Form1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
Select Case e.KeyCode
Case Keys.Up
PictureBox1.Top -= 10
Case Keys.Down
PictureBox1.Top += 10
Case Keys.Right
PictureBox1.Left += 10
Case Keys.Left
PictureBox1.Left -= 10
End Select
End Sub
Private Function moveIsInBounds(ByVal futurePosition As Point, ByVal objMoving As Size, ByVal container As Size) As Boolean
Dim xInBounds As Boolean = (futurePosition.X >= 0) AndAlso (futurePosition.X + objMoving.Width <= container.Width)
Dim yInBounds As Boolean = (futurePosition.Y >= 0) AndAlso (futurePosition.Y + objMoving.Height <= container.Height)
If xInBounds AndAlso yInBounds Then
Return True
Else
Return False
End If
End Function
Private Sub picturebox1_LocationChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox1.LocationChanged
Dim l As Integer = PictureBox1.Left + vx
Dim t As Integer = PictureBox1.Top + vy
If (l <= 0) Or (l + PictureBox1.Width >= Me.ClientSize.Width) Then
vx = -vx 'reverse X velocity
Else
PictureBox1.Left = 1
End If
If (t <= 0) Or (t + PictureBox1.Height >= Me.ClientSize.Height) Then
vy = -vy 'reverse Y velocity
Else
PictureBox1.Top = t
End If
End Sub
End
Class


Any assistance would be appreciated.Thanks
 
Hi,

You can override the ProcessDialogKey to control the movement of the PictureBox. Have a play with this example:-

VB.NET:
Public Class Form1
 
  Protected Overrides Function ProcessDialogKey(keyData As System.Windows.Forms.Keys) As Boolean
    Const moveVolocity As Integer = 10
 
    If keyData = Keys.Up OrElse keyData = Keys.Down OrElse keyData = Keys.Left OrElse keyData = Keys.Right Then
      Select Case keyData
        Case Keys.Up
          If PictureBox1.Top - moveVolocity <= 0 Then
            PictureBox1.Top = 0
          Else
            PictureBox1.Top -= moveVolocity
          End If
        Case Keys.Down
          If PictureBox1.Bottom + moveVolocity >= Me.ClientRectangle.Bottom Then
            PictureBox1.Top = Me.ClientRectangle.Bottom - PictureBox1.Height
          Else
            PictureBox1.Top += moveVolocity
          End If
        Case Keys.Left
          If PictureBox1.Left - moveVolocity <= 0 Then
            PictureBox1.Left = 0
          Else
            PictureBox1.Left -= moveVolocity
          End If
        Case Keys.Right
          If PictureBox1.Right + moveVolocity >= Me.ClientRectangle.Right Then
            PictureBox1.Left = Me.ClientRectangle.Right - PictureBox1.Width
          Else
            PictureBox1.Left += moveVolocity
          End If
      End Select
      Return True
    Else
      Return MyBase.ProcessDialogKey(keyData)
    End If
  End Function
End Class

Hope that helps.

Cheers,

Ian
 
Thank you so much for your help, this is exactly what I needed to achieve but kept getting stuck. Thanks again
 
Another issue. I have a maze like set up on the form with solid objects scattered around the form (like long bars) that my img when collides with needs to move 1 pixel in the opposite direction. The problem I have is that it is not known in which direction the image will hit the long bar at any given time. And so it doesn't seem to be working. THis is the code thus far:

Private Sub frmLevel1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
Select Case e.KeyCode ' move player
Case Keys.Up
player.Top += up.Text
Case Keys.Down
player.Top += Down.Text
Case Keys.Left
player.Left += left.Text
Case Keys.Right
player.Left += Right.Text
Case Keys.Escape
End
End Select
End Sub
Private Sub player_LocationChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles player.LocationChanged
If player.Bounds.IntersectsWith(wall1.Bounds) Then
If player.Left < wall1.Left Then
If player.Top > wall1.Top Then
player.Left = player.Left + Val(left.Text)
End If
If player.Top < wall1.Top Then
player.Left = player.Left + Val(up.Text)
End If
End If
If player.Left + player.Width > wall1.Left Then
If player.Top Then
End If
End If
 
 
End If
End Sub
Private Sub frmLevel1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Dim speed As Integer = 10
Dim speedinvert As Integer
speedinvert = speed * -1
up.Text = speedinvert
Down.Text = speed
left.Text = speedinvert
Right.Text = speed
End Sub
End
Class
 
Hi,

I am not sure I agree with you with regards to this statement:-

The problem I have is that it is not known in which direction the image will hit the long bar at any given time. And so it doesn't seem to be working.

The reason why I say this is because you are using the Arrow Key to control the direction of the image so you will always know which edge of the image is colliding with a wall. i.e (in pseudo code):-

1) If Left Key Pressed, Check for occurrence of Intersection and Test Left Edge of Image with Right Edge of Wall.
2) If Right Key Pressed, Check for occurrence of Intersection and Test Right Edge of Image with Left Edge of Wall.
3) If Up Key Pressed, Check for occurrence of Intersection and Test Top Edge of Image with Bottom Edge of Wall.
4) If Down Key Pressed, Check for occurrence of Intersection and Test Bottom Edge of Image with Top Edge of Wall.

Once you code this correctly for one wall you just need to use a loop to iterate through your collection of walls and test each wall in the same manner.

As additional thought, if you want to keep using the LocationChanged event then you need to make sure you save the value of the Key that was pressed so that the direction of movement can be interrogated correctly.

Hope that helps.

Cheers,

Ian

BTW, When posting code, please use the Advanced Button to post your question where you will find a button for encasing your code in Code tags. It helps to keep the formatting of the Code which makes things a lot easier to read.
 
Back
Top