I am creating a video game using Visual Basic .NET for IPT at school.
The game is a top-down shooter/adventure in which the player controls their character going up, down, left, right, and diagonally, and must acquire an object to finish the level. On the way are enemies and obstacles that block or kill the player character.
I'm trying to figure out a simple way to assign all the picture boxes meant to be obstacles as...well, obstacles that block the player, and then have the player's movement timer in whichever direction stop by changing into a long interval (if I just make the timer stop, it will start again as the arrow key is being held, thus resulting in stuttering in place as the player holds the arrow key in that direction). For the sake of this question, I only included an if statement for the player's "up" movement.
I have been using some code I found out with our textbook to identify "enemies", in which I create an array and define an object as obj and integer as I, then for each control in the form, check if it is a picture box and has a specific tag, then if it does, assign it to the array. Then for stuff like collision, for I = 0 To whatever, if the player intersects with the assigned objects, stuff happens yadda yadda. Like this:
Public Class Form2
Dim Skeleton(1) As PictureBox
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim obj As Object, I As Integer = 0
For Each obj In Me.Controls
' assign picture boxes with "skeleton" tag to Skeleton array
If TypeOf obj Is PictureBox AndAlso obj.tag = "skeleton" Then
Skeleton(I) = obj
I += 1
End If
Next
Private Sub tmrMovement_Tick(sender As Object, e As EventArgs) Handles tmrMovement.Tick
For I = 0 To 1
If Collision(Skeleton(I), picPlayer) Then
picPlayer.Visible = False
MsgBox("You died!" & Environment.NewLine & "Try again!")
Reset()
End If
It worked fine. So I figured if I want to quickly identify blocks that are meant to be impassable by the player, I'd just use another integer J and object otherobj, and another array. For example:
Public Class Form2
Dim Border(7) As PictureBox
Private Sub Form2_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Dim obj As Object, I As Integer = 0, otherobj As Object, J As Integer = 0
For Each otherobj In Me.Controls
' Assign picture boxes with "border" tag to Border array
If TypeOf otherobj Is PictureBox AndAlso otherobj.tag = "border" Then
Border(J) = otherobj
J += 1
End If
Next
Private Sub PicPlayer_LocationChanged(sender As Object, e As EventArgs) Handles picPlayer.LocationChanged
For J = 0 To 7
If Border(J).Bounds.IntersectsWith(picPlayer.Bounds) Then
If tmrUp.Enabled Then
tmrUp.Stop()
tmrUp.Interval = 10000
End If
End If
Next
However, I'm getting a null reference exception, and on run-time the assigning never happens and J remains 0. However, I have a private sub for a timer ticking (a timer which is always enabled, for I have used it for enemy movement), and if the for each loop is in that sub, instead of the picPlayer_LocationChanged sub, then it does work! The objects have collision!
My (new) Question: Why is it that the iteration shows a NullReferenceException error in a LocationChanged event for the player object, but it works perfectly fine if I have it in a Tick event for a timer?