Hello.

I've been having a major concern that I haven't been able to figure, likely because I'm just not used to debugging/looking at code critically. Perhaps I'm just being too complicated, but anyway.

I have a single-screen top-down shooter/dungeon-kind-of game in which there's two main objects - blocks and skeletons. There are eight blocks which the player and the skeletons can't pass through, and two skeletons that the player can't touch without restarting the level.
I've used two different arrays to define the objects that are to be skeletons or blocks, so that I don't have to name a whole bunch of objects and refer to them individually. I've been able to get the skeletons to move in the opposite direction (they currently only go right-left) when they hit a block, however the game crashes if the player restarts with an IndexOutOfRange error on the "If Skeleton(I).Bounds.IntersectsWith(Block(J).Bounds) Then" line.

Code:
Dim Skeleton(1) As PictureBox
Dim Block(7) As PictureBox
Dim obj As Object, I As Integer, J As Integer
Dim WhichWay As Direction = Direction.Right
Enum Direction
    Left
    Right
End Enum

Private Sub Form4_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    
' define which objects are "blocks" and which are "skeletons"

For Each obj In Me.Controls
        If TypeOf obj Is PictureBox Then
            If obj.tag = "skeleton" Then
                Skeleton(I) = obj
                I += 1
            End If
            If obj.tag = "block" Then
                Block(J) = obj
                J += 1
            End If
        End If
    Next
End Sub

Private Sub tmrMovement_Tick(sender As Object, e As EventArgs) Handles tmrMovement.Tick
    
' determine skeletons' movement

For I = 0 To 1
        Select Case WhichWay
            Case Direction.Left
                Skeleton(I).Left -= 1
            Case Direction.Right
                Skeleton(I).Left += 1
        End Select
        If Skeleton(I).Bounds.IntersectsWith(picPlayer.Bounds) AndAlso Skeleton(I).Visible = True AndAlso picPlayer.Visible = True Then
            picPlayer.Visible = False
            MsgBox("You died!" & Environment.NewLine & "Try again!")
            Reset()
        End If

        ' determines how the skeleton changes direction when hitting a "block" object

        For J = 0 To 7
            If Skeleton(I).Bounds.IntersectsWith(Block(J).Bounds) Then
                Select Case WhichWay
                    Case Direction.Left
                        WhichWay = Direction.Right
                        Skeleton(I).Left += 1
                    Case Direction.Right
                        WhichWay = Direction.Left
                        Skeleton(I).Left -= 1
                End Select
            End If
        Next
    Next
End Sub

Private Sub Form4_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
    Select Case e.KeyCode
        Case Keys.Left
            tmrLeft.Start()
        Case Keys.Right
            tmrRight.Start()
        Case Keys.Down
            tmrDown.Start()
        Case Keys.Up
            tmrUp.Start()
    End Select

End Sub

 ' the rest is just the player's movement and a function to reset the level when the player dies - so, probably not integral to the problem

Private Sub Form2_KeyUp(sender As Object, e As KeyEventArgs) Handles Me.KeyUp
    Select Case e.KeyCode
        Case Keys.Left
            tmrLeft.Stop()
        Case Keys.Right
            tmrRight.Stop()
        Case Keys.Down
            tmrDown.Stop()
        Case Keys.Up
            tmrUp.Stop()
    End Select
End Sub

Private Sub tmrLeft_Tick(sender As Object, e As EventArgs) Handles tmrLeft.Tick
    picPlayer.Left -= 2
End Sub

Private Sub tmrRight_Tick(sender As Object, e As EventArgs) Handles tmrRight.Tick
    picPlayer.Left += 2
End Sub

Private Sub tmrDown_Tick(sender As Object, e As EventArgs) Handles tmrDown.Tick
    picPlayer.Top += 2
End Sub

Private Sub tmrUp_Tick(sender As Object, e As EventArgs) Handles tmrUp.Tick
    picPlayer.Top -= 2
End Sub

Private Function Reset()
    Dim frm As New Form1
    frm.Show()
    Me.Hide()
End Function
This code should simulate a minimalised version of the game I'm making (the actual game has shooting and a goal and other stuff)

I can't figure anything out. I'm concerned about the fact that the game runs fine when it's first loaded, however if it's reloaded with the Reset() function, it crashes. I don't understand why the IndexOutOfRange error wouldn't occur when it's first loaded. Apparently, when the game crashes, it says that I = 2, which is good, but J = 0, which I'm pretty sure is bad. However, I don't know why it wouldn't equal 0.


Side note - the two skeletons change direction at the same time, even if only one hits a block. Their direction is determined by the "WhichWay" variable. If I want the skeletons to not change direction in unison, do I need a different "WhichWay" integer for each skeleton to determine their direction at any given time, or is there a better way to determine the change in movement of different objects in the same array?


Thanks in advance for any help.