How to fully delete a PictureBox when another PictureBox touches it

samhobbs 41 Reputation points
2021-10-08T12:00:16.613+00:00

At the moment, I am programming a game in VB.NET. My game consists of a ball, paddle, and some blocks, all of which are PictureBoxes. The way one section of the game works is that, whenever the ball touches a block, that block is supposed to disappear. Here is a snippet of code that shows how the system works:

Dim left_motion As Integer = 5
    Dim top_motion As Integer = 5
    Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
        Ball.Top += top_motion
        Ball.Left += left_motion
        If Ball.Bounds.IntersectsWith(YellowBlock6.Bounds) Then
            top_motion = top_motion * -1
            YellowBlock6.Hide()
            Score = Score + 1
            lblScore.Text = Score

This code may be a little hard to understand, so I'll break it down. Basically, left_motion and top_motion relate to the direction in which the ball moves in, and I set them both to 5, as I want this to be the speed of the ball. When the ball touches the block, the direction of travel will be reversed, the block is hidden, and my score label updates by 1. All of this occurs within a timer. The hiding of the block is the part I am having trouble with.

I found out that, even the block is hidden and you can't see it, the ball acts like the ball is still there. So sometimes, when the ball is moving and it touches a blank area where one of the blocks has disappeared, it still acts as though the block is there. How do I make it so that the block fully disappears instead of just being hidden? In reality, the rest of the code shouldn't need editing. It should just be the YellowBlock6.Hide() part (line 8)

Developer technologies | VB
{count} votes

1 answer

Sort by: Most helpful
  1. Michael Taylor 60,326 Reputation points
    2021-10-08T14:44:55.107+00:00

    Personally I would not recommend using multiple pictureboxes for this. It will be very inefficient especially as you throw more items on the screen. The better approach would probably be to create just a regular custom control that manages a list of images (or whatever data you really need) and their location. Then you can change the position of the image and refresh to "move" things around. To do hit detection you normally have a bounding box around each object (irrelevant of what or the shape). When an object is moved you check to see if its bounding box intersects any other object's bounding box. If so then they have collided. It is a pretty standard and straightforward algorithm to implement. To "remove" an item just remove the image from your control's list and refresh. The hit detection logic doesn't need to change.

    ' My VB is rusty...
    Public Class MyImageControl Inherits Control
       'On paint, draw the images
    
       'Add an image
       Public Sub Add ( image As Image )
          _images.Add(image)
    
          Refresh()
       End Sub
    
       ' Remove an image
       Public Sub Remove ( image As Image )
          _images.Remove(image)
    
          Refresh()
       End Sub
    
       ' Hit detection doesn't need to change as it should enumerate _images only
    
       Private List(Of Image) _images As New List(Of Image)
    End Class
    

    If you want to continue using pictureboxes for now then you can. If you want to keep the PBs around then modify your hit detection logic to check to see if the PB's Visible property is true or not. If it isn't then it is hidden. I'm assuming here that is the property you're toggling to show/hide them.

    If YellowBlock6.Visible AndAlso Ball.Bounds.IntersectsWith(YellowBlock6.Bounds) Then
       ...
    

    However if you were building a shooting game where you are going to need to have lots of temporary images on the screen then you will end up creating more and more PBs and just hiding them. This will be expensive and slow down as your game progresses. In this case you should probably just get rid of the PB when you're done with it. So instead of setting it hidden, remove it from the parent control's Controls property. Then dispose of it and any image it contained. Your hit detection logic doesn't need to change.

    Private Sub RemoveImage ( target As PictureBox )
       ' Remove from parent controls so it disappears
       Me.Controls.Remove(target)
    
       ' Clean it up, probably should consider cleaning up the image as well but it depends on how you are using images
       target.Dispose()
    End Sub
    
    ' No changes to hit detection needed
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.