I am currently making a space invaders game in vb (for a school project otherwise I would steer clear of this for making a game...)
I have a class called Invader, where the information on each enemy will be stored. Part of this is having a picturebox to display the image of the invader, which I have added as a property of the class.
Public Class Invader
' PROPERTIES '
Property X As Integer 'The X coordinate'
Property Y As Integer 'The Y coordinate'
Property PicBox As PictureBox 'The picturebox that holds the invader picture'
Property Type As String 'The enemy type that the invader is'
Property Health As Integer 'The health of the invader'
Property Speed As Integer 'The number of pixels that the invader moves when Move() is called'
Property Alive As Boolean 'Whether the invader is alive or not'
Property Direction As Integer 'The direction that the invader is 'facing'. 1 will be right and 0 will be left'
The array is then declared as
Public Enemy(0 To 3, 0 To 10) As Invader
The instances of the class are created from CreateEnemies()
Public Sub CreateEnemies()
For r = 0 To 3
For c = 0 To 10
Enemy(r, c) = New Invader
Next
Next
End Sub
Now, I have a sub called PositionEnemies() which will position each picturebox on the game form (called frmGame) and then load the picture into it and display it.
Public Sub PositionEnemies()
For r = 0 To 3
For c = 0 To 10
Enemy(r, c).PicBox = New PictureBox
Enemy(r, c).X = 0 + ((c + 1) * 110)
Enemy(r, c).Y = 362 - (((r + 1) * 100) - 100)
Enemy(r, c).Alive = True
Enemy(r, c).UpdateLocation(r, c)
Enemy(r, c).PicBox.ImageLocation = normalinvader
Enemy(r, c).PicBox.Load()
Enemy(r, c).PicBox.Height = 50
Enemy(r, c).PicBox.Width = 50
Enemy(r, c).PicBox.Visible = True
MsgBox(Enemy(r, c).PicBox.Created.ToString())
Next
Next
End Sub
I have added the messagebox at the end to tell me if the picturebox has been created, which at the moment always comes back as "false".
All of this is then called when frmGame loads
Private Sub frmGame_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
Me.Show()
CreateEnemies()
PositionEnemies()
End Sub
If you have managed to follow all that, the problem I have is that the load of frmGame completes successfully, but none of the pictureboxes are actually created for some reason (the messagebox returns "false"). I have looked at this code for so long and not been able to figure out why - I hope one of you lovely people could help me out here.
Thanks
Every form wants that you add the controls to be displayed to its Controls collection.
If you don't do it, no display....
Private Sub frmGame_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
CreateEnemies()
PositionEnemies(Me)
Me.Show()
End Sub
Public Sub PositionEnemies(ByVal f as Form)
For r = 0 To 3
For c = 0 To 10
Enemy(r, c).PicBox = New PictureBox
Enemy(r, c).X = 0 + ((c + 1) * 110)
Enemy(r, c).Y = 362 - (((r + 1) * 100) - 100)
Enemy(r, c).Alive = True
Enemy(r, c).UpdateLocation(r, c)
Enemy(r, c).PicBox.ImageLocation = normalinvader
Enemy(r, c).PicBox.Load()
Enemy(r, c).PicBox.Height = 50
Enemy(r, c).PicBox.Width = 50
Enemy(r, c).PicBox.Visible = True
'MsgBox(Enemy(r, c).PicBox.Created.ToString())
f.Controls.Add(Enemy(r, c).PicBox)
Next
Next
End Sub
Also, I would move the call to Show after you have created your Enemies and positioned the PictureBoxes. Of course, if the PositionEnemies is inside the frmGame class then you could use directly the Me reference without passing it.
I think you should add
Me.Controls.Add(Enemy(r, c).PicBox)
in
Public Sub PositionEnemies()
below
Enemy(r, c).PicBox.Visible = True
Related
Public Class Form1
Dim r, r1, g, g1, b, b1 As Integer
Dim grid(0 To 9, 0 To 9) As Label
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
timer1.Enabled = False
Randomize()
For row = 0 To 9
For col = 0 To 9
grid(row, col) = New Label
grid(row, col).Width = 50
grid(row, col).Height = 50
grid(row, col).Left = 55 * col + 55
grid(row, col).Top = 55 * row + 55
grid(row, col).BackColor = Color.White
Me.Controls.Add(grid(row, col))
AddHandler grid(row, col).MouseEnter, AddressOf mouse_enter
Next
Next
End Sub
Private Sub mouse_enter(sender As Label, e As EventArgs)
r = Int(Rnd() * 256)
g = Int(Rnd() * 256)
b = Int(Rnd() * 256)
For row = 0 To 9
For col = 0 To 9
sender.BackColor = Color.FromArgb(r, g, b)
Next
Next
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
Dim row As Integer
Dim col As Integer
For row = 0 To 9
For col = 0 To 9
r = Int(Rnd() * 256)
g = Int(Rnd() * 256)
b = Int(Rnd() * 256)
grid(row, col).BackColor = Color.FromArgb(r, g, b)
Next
Next
End Sub
Private Sub Label2_Click(sender As Object, e As EventArgs) Handles Label2.Click
Timer1.Enabled = True
Timer1.Interval = 800
End Sub
End Class
I want to create a 10x10 array of white boxes which change into a random rgb color once the mouse goes over them, which is working fine. However, I also want the boxes which have already been colored to change into a new rgb value with each timer1 tick. With the code above it's just changing all 100 boxes within the array with each tick, no matter if its been colored or not (by the user going over it with their mouse.) Does anyone know how I would be able to get this done?
"I also want the boxes which have already been colored to change into a new rgb value with each timer1 tick." Since this is happening each time the timer ticks then the If statement will belong in the Timer1.Tick event. If you want the color to remain the same once the mouse has entered a label then add the If in the same way to the mouse_enter code.
You could check if the label's .BackColor is still White but what if the randomly selected .BackColor in the mouse_enter Sub happens to be White? Do you still want to change it? Probably it would be best to use the .Tag property of the Label.
When the mouse_enter is called, set the .Tag property to "Changed". Then in the .Tick event check if the .Tag property is still Nothing.
Although the old vb6 Rnd function will work, it is better to use the .net Random class. Create a single instance of this class at the Form level.
I moved the code getting a random color to a separate function so we didn't need to repeat the code.
Private grid(0 To 9, 0 To 9) As Label
Private Rand As New Random
Private Sub Form4_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Timer1.Enabled = False
For row = 0 To 9
For col = 0 To 9
grid(row, col) = New Label
grid(row, col).Width = 50
grid(row, col).Height = 50
grid(row, col).Left = 55 * col + 55
grid(row, col).Top = 55 * row + 55
grid(row, col).BackColor = Color.White
Controls.Add(grid(row, col))
AddHandler grid(row, col).MouseEnter, AddressOf mouse_enter
Next
Next
End Sub
'The signature of this method must match the signature of Label.MouseEnter
'So sender must be As Object, not As Label
Private Sub mouse_enter(sender As Object, e As EventArgs)
'Not all Objects have a .BackColor property so we must Cast to the underlying type, Label
Dim l = DirectCast(sender, Label)
l.BackColor = GetNewColor()
l.Tag = "Changed"
End Sub
Private Function GetNewColor() As Color
Dim r = Rand.Next(256)
Dim g = Rand.Next(256)
Dim b = Rand.Next(256)
Dim NewColor = Color.FromArgb(r, g, b)
Return NewColor
End Function
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
For row = 0 To 9
For col = 0 To 9
If grid(row, col).Tag Is Nothing Then '.Tag has never been set
grid(row, col).BackColor = GetNewColor()
End If
Next
Next
End Sub
Private Sub Label2_Click(sender As Object, e As EventArgs) Handles Label2.Click
Timer1.Enabled = True
Timer1.Interval = 800
End Sub
I'm trying to create more than one array of PictureBox.
The only thing I know is that I can use limited amount of arrays that was created in a code.
Dim CustomImage() As PictureBox = New PictureBox() {Array1, Array2,..and so on}
But what I'm trying to explain is how do you create those arrays something like this?
In this example, the user inputs number 6 and it shows 6 PictureBoxes.
Dim ArrayNumber as Integer = 6
Dim CustomImage() As PictureBox = New PictureBox() {some code that creates 6 arrays}
Just sample:
Dim myPictBox As PictureBox()
Private Const maxPBCount = 10
Private Sub CreateSomePictureBox(ByVal Count As Int16)
If Count > maxPBCount Then
Exit Sub
End If
Dim myPictBoxLength As Integer = 0
If myPictBox Is Nothing = False Then
myPictBoxLength = myPictBox.Length
End If
Do While myPictBoxLength > Count
myPictBox(myPictBoxLength - 1).Dispose()
myPictBoxLength -= 1
Loop
If Count <= 0 Then
myPictBox = Nothing
Exit Sub
End If
ReDim Preserve myPictBox(Count - 1)
'Arrange Position of PictureBox
MsgBox(myPictBoxLength)
Do While myPictBoxLength < Count
myPictBox(myPictBoxLength) = New PictureBox
myPictBox(myPictBoxLength).Height = 30
myPictBox(myPictBoxLength).Width = 30
myPictBox(myPictBoxLength).Location = New Point(35 * myPictBoxLength, 30)
Me.Controls.Add(myPictBox(myPictBoxLength))
myPictBox(myPictBoxLength).BackColor = Color.Red
myPictBox(myPictBoxLength).Show()
myPictBoxLength += 1
Loop
'Create Sub Procedure to Arrange The Picture Box Created
'ArrangePB()
End Sub
Private Sub Form1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Click
CreateSomePictureBox(6)
End Sub
Hello im having trouble with my code !
we are asked to organize a list of names from a text.txt file the make them show up into a lits box (got that part down :) ) . then from the list box we are asked to create an array and sort that array (using our own sorting method) and organize the names using a button in assending order and another button organizing the array in decending order. the results from the orders names should appear in another list box .
i have gotten only the last name in the list to show up in the second list box but my code has no errors it just wont order the names properly! Help!!!!!
here is my code :)
Public Class FileSort
Dim sr As IO.StreamReader = IO.File.OpenText("C:\Users\Inspiron 15\documents\visual studio 2010\Projects\assigment4 EL\assigment4 EL\names.txt")
Structure names
Dim c As Integer
Dim fullname As String
End Structure
Dim allNames(99) As names
Private Sub btnName_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnName.Click
Do While sr.Peek <> -1
Name = sr.ReadLine
LstNames.Items.Add(Name & " ")
Loop
sr.Close()
End Sub
Private Sub bubbelsort(ByRef names() As System.String, ByVal c As Integer)
c = 0
names(c) = sr.ReadLine()
c = c * 1
For c = 1 To 99 Step +1 '~~~ Addding (Z to A) to the the Listbox
lstOrderedNames.Items.Add(Name & "")'
Next
End Sub
Private Sub BtnAssend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnAssend.Click
Dim names(99) As String
Dim c As Integer
c = 0
Dim A As Integer
A = 99
names(c) = sr.ToString
c = c + 1
For c = 1 To 99 Step +1 '~~~ Addding (Z to A) to the the Listbox
lstOrderedNames.Items.Add(Name & "")
Next
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnDessend.Click
Dim names(99) As String
Dim c As Integer
c = 0
Dim A As Integer
A = 99
names(c) = sr.ToString
names(A) = sr.ToString
A = A - 1
For A = 99 To 0 Step -1 '~~~ Addding (Z to A) to the the Listbox
lstOrderedNames.Items.Add(Name & "")
Next
End Sub
enter image description here
Since your problem is the sorting algorithm (if I understand this correctly).
At first we need an array.
Dim arr(ListBox1.Items.Count - 1) As String
For i As Integer = 0 To arr.Length - 1
arr(i) = CStr(ListBox1.Items(i))
Next
Next the sorting algorithm. Since you wanted to go with BubbleSort:
Private Sub StringBubbleSort(arr As String)
For i As Integer = 0 To arr.Length - 1
For j As Integer = 0 To arr.Length - 2 - i
If String.Compare(arr(j), arr(j + 1)) > 0 Then
Dim temp As String = arr(j)
arr(j) = arr(i)
arr(i) = temp
End If
Next
Next
End Sub
Then you use this function and copy the array to your second ListBox.
StringBubbleSort(arr)
ListBox2.Items.AddRange(arr)
String.Compare: https://msdn.microsoft.com/de-de/library/84787k22(v=vs.110).aspx
you could use linq
ListBox1.Items.Add("Battle")
ListBox1.Items.Add("Cattle")
ListBox1.Items.Add("apple")
ListBox2.DataSource = (From l In ListBox1.Items
Select l Order By l Ascending).ToList
I have a VB.Net program that loops through array's to try to figure out where bottles are on a "conveyor". The point of this program is to visually show staff, how the conveyor works using VB.net and Labels. It's extremely difficult to explain, so I’ll do my best.
Bottle_Number(10) Bottle_Position(128)
There are 10 bottles that I want to track at all 128 stops on the conveyor.
We have a conveyor that can only fit 10 bottles. I need to track the position of each of the 10 bottles. Once bottle 11 comes on - That means bottle 1 is completed and off the conveyor. So, bottle 11 becomes bottle 1, so I need to reset the position of bottle1 to 0, and continue tracking bottles 2-9 while also tracking bottle 11(Not bottle 1). Once bottle 12 comes on it becomes bottle 2, and I need to reset the position of bottle 2 to '0' and continue tracking all bottles.
Any help would be appreciated.
Here is my code:
Public Class frmMain
Dim Product_Position(10) As Integer
Dim Inches_Per_Pulse As Integer
Dim PulseNumber As Integer
Dim Product_Counter As Integer
Dim Product_Location(10) As Integer
Dim Function1 As Integer
Dim Function2 As Integer
Dim Function3 As Integer
Dim Function4 As Integer
Dim Function5 As Integer
Dim Function6 As Integer
Dim Function7 As Integer
Dim Function8 As Integer
Dim Function9 As Integer
Dim Function10 As Integer
Dim Product_in_Tunel As Integer
Dim test As Integer
Dim Roll_OVer As Boolean
Dim Product_Counter_Test As Integer
Private Sub btnStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStart.Click
lblStatus.BackColor = Color.Green
lblStatus.Text = "Conveyor Status: Running"
End Sub
Private Sub btnStop_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnStop.Click
lblStatus.BackColor = Color.Red
lblStatus.Text = "Conveyor Status: Off"
End Sub
Private replace_next As Integer
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
If Product_Counter = 10 Then
replace_next += 1
If replace_next > 10 Then
replace_next = 1 ' replace them in turn 1..10, then loop back to 1
Product_Position(replace_next) = 0 ' put initial position here
End If
End If
Product_Counter = Product_Counter + 1
If Product_Counter > 10 Then
Product_Counter = 1
Roll_over = True
End If
'MsgBox(Product_Counter)
'MsgBox(replace_next)
End Sub
Private Sub btnPulse_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPulse.Click
Get_Location()
End Sub
Private Sub frmMain_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
PulseNumber = "0"
Inches_Per_Pulse = "1"
Roll_OVer = False
'MsgBox("Test")
End Sub
Public Sub Get_Location()
'MsgBox(Product_Counter)
If Roll_OVer = True Then
Product_Counter_Test = 10
'MsgBox("i'm stuck here")
End If
If Roll_OVer = False Then
Product_Counter_Test = Product_Counter
End If
'MsgBox(Product_Counter_Test)
'MsgBox("am I here - Yes")
For test = 1 To Product_Counter_Test
'MsgBox("This works")
Product_Position(test) = Product_Position(test) + Inches_Per_Pulse
Next
PulseNumber = PulseNumber + 1
ClearLabels()
lblProduct1Position.Text = Product_Position(1)
lblProduct2Position.Text = Product_Position(2)
lblProduct3Position.Text = Product_Position(3)
lblProduct4Position.Text = Product_Position(4)
lblProduct5Position.Text = Product_Position(5)
lblProduct6Position.Text = Product_Position(6)
lblProduct7Position.Text = Product_Position(7)
lblProduct8Position.Text = Product_Position(8)
lblProduct9Position.Text = Product_Position(9)
lblProduct10Position.Text = Product_Position(10)
End Sub
Public Sub ClearLabels()
lblProduct1Position.Text = ""
lblProduct2Position.Text = ""
lblProduct3Position.Text = ""
lblProduct4Position.Text = ""
lblProduct5Position.Text = ""
lblProduct6Position.Text = ""
lblProduct7Position.Text = ""
lblProduct8Position.Text = ""
lblProduct9Position.Text = ""
lblProduct10Position.Text = ""
End Sub
The Pulse button is what is actually driving the conveyor, each pulse (click of the button) means the conveyor is moving forward.
Right now once the program gets to bottle 11, it resets and only moves forward the "new" bottle (bottle1). It should continue incrementing the remaining bottles until they reach the end and do the same for them - Reset the position to 0 and begin counting again.
As far as I understand it, once you have 11 bottles, you don't want to reset to only one bottle, but instead still have 10 bottles, and replace one of them. You'll need a second variable to keep track of which is to be replaced.
So instead of :
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
Product_Counter = Product_Counter + 1
If Product_Counter > 10 Then Product_Counter = 1
End Sub
It would be something like:
Private Replace_Next as Integer = 0
Private Sub btnSend_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnSend.Click
If Product_Counter = 10 Then
Replace_Next += 1
If Replace_Next > 10 Then Replace_Next = 1 ' replace them in turn 1..10, then loop back to 1
Product_Position(Replace_Next) = .... ' put initial position here
Else
Product_Counter = Product_Counter + 1
End If
End Sub
Your conveyor is FIFO (first-in, first-out), so rather than constantly shifting, reindexing and/or rebuilding (=reset?) an array to make it seem like it is FIFO, Net includes the Queue(Of T) collection which is FIFO.
A LinkedList(Of T) could also be used. A plain List(Of T) would also work, but if the add/remove frequency is high, that will result in the same inefficient shifting taking place under the hood that you have with an array.
The only issue is enforcement of the size limit, which is easily handled with a small class wrapper. I assume there is something interesting or identifiable about the bottles other than their position. The test code uses a sequence ID and the contents.
Friend Class Bottle
Public Property Contents As String
Public Property SequenceID As Int32
' etc
Public Overrides Function ToString() As String
Return String.Format("{0}: ({1})", SequenceID.ToString("00"), Contents)
End Function
End Class
You likely have more relevant information to show. The, the collection class:
Friend Class BottleQueue
Private mcol As Queue(Of Bottle)
Private lbls As Label()
Private MaxSize As Int32 = 10 ' default
Public Sub New(size As Int32)
MaxSize = size
mcol = New Queue(Of Bottle)
End Sub
Public Sub New(size As Int32, l As Label())
Me.New(size)
lbls = l
End Sub
Public Sub Add(b As Bottle)
mcol.Enqueue(b)
Do Until mcol.Count <= MaxSize
mcol.Dequeue()
Loop
UpdateDisplay()
End Sub
Public Function Peek() As Bottle
Return mcol.ElementAtOrDefault(0)
End Function
Public ReadOnly Property Count() As Int32
Get
Return mcol.Count
End Get
End Property
Public Function Remove() As Bottle
Dim b As Bottle = Nothing
If mcol.Count > 0 Then
b = mcol.Dequeue
UpdateDisplay()
End If
Return b
End Function
Private Sub UpdateDisplay()
Dim n As Int32
If lbls Is Nothing OrElse lbls.Count = 0 Then
Return
End If
For n = 0 To mcol.Count - 1
lbls(n).Text = mcol.ElementAtOrDefault(n).ToString
Next
For n = n To lbls.Count - 1
lbls(n).Text = "(empty)"
Next
End Sub
Public ReadOnly Property GetQueue As Bottle()
Get
Return mcol.ToArray()
End Get
End Property
End Class
The class has 2 display means built in. One updates a set of labels. Since it is a collection, it also provides a way to get the current collection in order for a collection type control such as a Listbox. An even better way would be if the collection itself was "observable", so it could be used as a datasource.
It also provides a way to Removethe next bottle manually. Removing from a specific index (e.g. Remove(3)) is antithetical to a Queue, so it isnt implemented.
test code:
' form level vars:
Private BottleQ As BottleQueue
Private BottleID As Int32 = 7
' form load, passing the labels to use
' using a queue size of FIVE for test
BottleQ = New BottleQueue(5, New Label() {Label1, Label2, Label3, Label4, Label5})
Adding an item:
Dim material = {"Napalm", "Beer", "Perfume", "Pepsi", "Cyanide", "Wine"}
' add new bottle with something in it
BottleQ.Add(New Bottle With {.Contents = material(RNG.Next(0, material.Count)),
.SequenceID = BottleID})
BottleID += 1
' clear and show the contents in a listbox:
lbQueView.Items.Clear()
lbQueView.Items.AddRange(BottleQ.GetQueue)
The BottleId arbitrarily starts at 7, the contents are random. BTW, material shows just about the only way I ever use an array: when the contents are fixed and known ahead of time. In almost all other cases, a NET collection of one sort or another, is probably a better choice.
Because it is not an observable collection (and that is a little at odds with the FIFO nature), the listbox needs to be cleared each time. That could be internal to the class like the label display is. Results:
On the right, the first 5 are shown in order; 3 clicks later, the result is on the left: everything moved up 3 and 3 new items have been added.
Note: If the code using this needs to know when/which Bottle is removed from the conveyor, the class could include a ItemRemoved event which provides the item/Bottle just removed when adding forces one out. That is probably the case, but the question doesnt mention it.
I have made an array of tiles (pictureboxes) in an array and need them to all do something when clicked, but don't know how. Specifically, I want to be able to place some other object on them by clicking a tile and making that object go to that tile's location. I know you may suggest looking at the mouseposition variable and having some invisible box over all the tiles to register clicks, but I would like to know how to register any event for an object in an array for anything that comes up in the future. I do know how to register events for objects which aren't in an array by the way.
The object I want to move on top of the picturebox will also be from an object array, but a different one.
Here is my code:
Public Class Form1
Dim tiles(50) As PictureBox 'This is the object array of tiles
Dim plants() As String 'I haven't set this up yet, but this will be for the objects to be 'placed' on the pictureboxes.
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
Dim tileWidth As Integer = 50
Dim tileHeight As Integer = 50
Dim xindent As Integer = 10
Dim yindent As Integer = 10
For x = 0 To 9
For y = 0 To 4
ReDim Preserve tiles(x * y)
tiles(x * y) = New PictureBox With {.Visible = True, .Size = New System.Drawing.Size(50, 50), .Parent = Me, .BackColor = Color.GreenYellow, .Image = Nothing}
tiles(x * y).Location = New System.Drawing.Point(x * tileWidth + xindent, y * tileHeight + yindent)
If (x Mod 2 = 0 And y Mod 2 = 0) Or (x Mod 2 <> 0 And y Mod 2 <> 0) Then
tiles(x * y).BackColor = Color.Green
End If
Next
Next
End Sub
End Class
I simply don't know how to set up the click event handler for the array of tiles so that's why its not in the code above.
Thanks in advance for your help.
AddHandler is there for that. After the New you just need to attach a function to the event
AddHandler tiles(x * y).Click, AddressOf Tile_Click
And have a function that handles the event
Private Sub Tile_Click(sender As Object, e As System.EventArgs)
' sender represent the reference to the picture box that was clicked
End Sub
If you already know the size of the array, you should ReDim your array just once instead of each time you loop (Move the ReDim out of the loops). Also, since y is 0 on the first loop, you are basically doing a ReDim of 0 elements (x*y = 0 when y = 0)
the_lotus has already given you a great answer.
Just wanted to share a trick I often use when wiring up events with AddHandler.
Declare a temporary variable using WithEvents in your class:
Public Class Form1
Private WithEvents Tile As PictureBox
...
Now, in the two DropDowns across the top of code editor, change Form1 to Tile, and (Declarations) to Click (or whatever event you want). This will enter a method for you that has the correct method signature:
Private Sub Tile_Click(sender As Object, e As EventArgs) Handles Tile.Click
End Sub
Delete the Handles Tile.Click portion that appears at the end of the first line:
Private Sub Tile_Click(sender As Object, e As EventArgs)
End Sub
Finally, remove your temporary declaration that used WithEvents.
Now you've got a method with the correct signature that you can use with AddHandler. This is very handy for events that don't have the standard signature.