Question on controlling picture boxes through a 2D picture box array?

  • (2 Pages)
  • +
  • 1
  • 2

23 Replies - 2502 Views - Last Post: 02 September 2011 - 10:48 AM Rate Topic: -----

#1 hypercat11  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 20-August 11

Question on controlling picture boxes through a 2D picture box array?

Posted 20 August 2011 - 06:24 PM

Hi! I'm... maybe an advanced beginner in VB.net, I have VS 2008 and use VB, not C#/C++ or whatever else. I'm trying to make a battleship game, and I've decided to use the only method I can think of to control the grid. A 2D boolean array for position marking. I have the array set up, and the grid set up in the design form, but I can't figure out with all my research how to link them together. I'm writing this program to shake off the rust before school starts again, and for fun. I took VB in school last year, a half year class, so I have a foundation, now I'm self-educating myself above and beyond the class. I've searched for a way to use a picture box array to use the coordinates of the ship to .Visible=True the picture boxes. I've been working on this for 2 days straight with no results. I just need a little nudge in the right direction. The exception I've been getting with my latest concoction of code is NullReferenceException was Unhandled. I think its referring to the fact that I have no idea how to link the picture boxes into the array. Here's my code, and I'll comment where the exception is thrown:
 Private Sub cmdStart_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdStart.Click
        'label for GoTo statements is Tryline:
        '3 ships 4 length
        Dim a(10, 10) As Boolean, b(10, 10) As Boolean, c As Integer, x As Integer, y As Integer, ox As Integer, oy As Integer, picG(10, 10) As PictureBox, picR(10, 10) As PictureBox
        For c = 1 To 3
            Try
Tryline:
                For x = 0 To 9
                    For y = 0 To 9
                        a(x, y) = False 'clears array after each Try/Catch cycle
                    Next y
                Next x
                ox = Int(Rnd() * 10) 'coordinates saved in origional x/y
                oy = Int(Rnd() * 10)
                c = Int(Rnd() * 4 + 1) 'direction
                If a(ox, oy) = True Then
                    GoTo Tryline
                End If
                a(ox, oy) = True 'marked
                Select Case c
                    Case 1 'up
                        For y = 1 To 4
                            If a(ox, oy + y) = True Then
                                GoTo Tryline
                            Else
                                a(ox, oy + y) = True
                            End If
                        Next y
                    Case 2 'Down
                        For y = 1 To 4
                            If a(ox, oy - y) = True Then
                                GoTo Tryline
                            Else
                                a(ox, oy - y) = True
                            End If
                        Next y
                    Case 3 'Left
                        For x = 1 To 4
                            If a(ox - x, oy) = True Then
                                GoTo Tryline
                            Else
                                a(ox - x, oy) = True
                            End If
                        Next x
                    Case 4 'right
                        For x = 1 To 4
                            If a(ox + x, oy) = True Then
                                GoTo Tryline
                            Else
                                a(ox + x, oy) = True
                            End If
                        Next x
                End Select
            Catch q As IndexOutOfRangeException
                GoTo Tryline
            Catch q As Exception
                Dim result As Integer
                result = MsgBox("A fatal error has occurred in the code, please contact the programmer that wrote this program so he can fix it." + Str(q), 48, "Error!")
                If result = vbOK Then
                    Beep()
                    End
                End If
            Finally
                For x = 0 To 9
                    For y = 0 To 9
                        If a(x, y) = False Then
                            For ox = 0 To 9
                                For oy = 0 To 9
                                    If x = ox And y = oy Then
                                        picR(ox, oy).Visible = True
                                    Else
                                        picG(ox, oy).Visible = True
                                    End If
                                Next oy
                            Next ox
                        End If
                    Next y
                Next x
            End Try
        Next c
    End Sub

I've also attatched the picture of my form design so you can get an idea of what it looks like.
What I'm trying to do, is like for example, when you have a 2D boolean array, you use nested for loops to mark stuff off, and then use those positions for something later like:
For x = 0 to 9
            For y = 0 to 9
                  If a(0,0)= True Then
                      'select case statements... blablabla... (0,) is ace, and (,0) is spades
                      picAceofSpades.Visible=True
                  End If

But as you can see in my project code, i have a wierd special case, and I haven't yet found a way to link the array and the pictures because you can't exactly say
if a(x,y)=True then
         picR(x,y).visible=True
      End If


If all of my picboxes are named by coordinates and color. ex: picR00 is the red picture box that represents (0,0).

THANK YOU IN ADVANCE SOOO MUCH TO WHOEVER ANSWERS MY LONG WINDED POST!!!!!

Is This A Good Question/Topic? 0
  • +

Replies To: Question on controlling picture boxes through a 2D picture box array?

#2 _HAWK_  Icon User is online

  • Master(Of Foo)
  • member icon

Reputation: 1055
  • View blog
  • Posts: 4,086
  • Joined: 02-July 08

Re: Question on controlling picture boxes through a 2D picture box array?

Posted 20 August 2011 - 08:02 PM

I have a much diff than your current design. I would use a custom class with several properties like; a Rectangle, Image, and Boolean or two. Store these in a List(Of <your custom class>). Then you can place these where ever you want on your canvas - 1 pictureBox instead of many. Does the same effect, but not so control heavy. The cool thing about rectangles - they can have dimensions and not be drawn to the canvas yet still use the mouse_down event coordinates for finding them. I feel this is a more OOP way of doing it. If this for school - I have wasted some of time, but still feel it was worth mentioning.
Was This Post Helpful? 0
  • +
  • -

#3 hypercat11  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 20-August 11

Re: Question on controlling picture boxes through a 2D picture box array?

Posted 20 August 2011 - 09:04 PM

View Posthawkvalley1, on 20 August 2011 - 08:02 PM, said:

I have a much diff than your current design. I would use a custom class with several properties like; a Rectangle, Image, and Boolean or two. Store these in a List(Of <your custom class>). Then you can place these where ever you want on your canvas - 1 pictureBox instead of many. Does the same effect, but not so control heavy. The cool thing about rectangles - they can have dimensions and not be drawn to the canvas yet still use the mouse_down event coordinates for finding them. I feel this is a more OOP way of doing it. If this for school - I have wasted some of time, but still feel it was worth mentioning.



Thank you sooooo much for responding!!! I only have a 1/2 year very basic vb classroom experience. I have no idea how to do that custom class stuff.
We only got up to sorting arrays and 2D arrays, and no duplicates in arrays. That's the most complex we got. I've self taught a bunch of stuff, but i would need
Someone to teach me how to do that... This is not for school, if you would believe, it's for fun... I'm indulging the geeky side. I've spent too much time
In the testosterone charged world of cross country. If you could teach me, that would be great, it would be a pain to do the hours of research to turn up nothing like always happens.
Was This Post Helpful? 0
  • +
  • -

#4 _HAWK_  Icon User is online

  • Master(Of Foo)
  • member icon

Reputation: 1055
  • View blog
  • Posts: 4,086
  • Joined: 02-July 08

Re: Question on controlling picture boxes through a 2D picture box array?

Posted 20 August 2011 - 10:07 PM

Custom class object is like the other objects you have used, but this time we making one just for you.

Simple layout:
Public Class xBox
  Public Rect As New Rectangle()
  Public isFound As Boolean
  Public img As Image
   
  Public Sub New(img As Image)
    Me.img = img
  End Sub
End Class


List of said new objects:
'this goes in your form where you draw stuff
Private boxes As New List(Of xBox)


Now each time you add a new object you define it's location by setting the x, y properties of the rectangle. Now after you have loaded several of these objects you can try to mouse click on the picturebox - using the mouse_down event and iterate this List to see if any of the rectangle.Contains(<mouse location>) then you set the isFound boolean to True and update the picturebox. The paint event iterates the List and only draws the ones that isFound = True. viola

Now I have given you a good start. Play with it and let me know what you come up with!

This post has been edited by hawkvalley1: 20 August 2011 - 10:09 PM

Was This Post Helpful? 2
  • +
  • -

#5 hypercat11  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 20-August 11

Re: Question on controlling picture boxes through a 2D picture box array?

Posted 21 August 2011 - 06:08 AM

Thank you so much! I'll try that. I'll post back when i have the results. I'll keep the button that has the code i posted here in it, and I'll create a new button and try this. I'll do some research on this but Thank You!!!
Was This Post Helpful? 0
  • +
  • -

#6 hypercat11  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 20-August 11

Re: Question on controlling picture boxes through a 2D picture box array?

Posted 21 August 2011 - 04:55 PM

Hello again! I'm sorry to say I didn't even really consider your idea because it's too complex for my very basic education on vb.net. I only took a half year class in high school last year, and we barely got to 2D arrays, sorts, and weeding out duplicates from an array. I've taught myself many things like Try...Catch...Finally structured exception handling. But... I finally got the board to work a slightly similar way! By making a PictureBox array, Then at certian points of code, made if-then statements for making a new instance of the picture box class. Were you telling me to do that except with rectangles? Or to define a whole new object class rectangle? Here are the resources that saved me, and got me on the right track with the PictureBox My link


And here is the code:

    
'Public  Public pics(10, 10) As PictureBox, pikachuval As Integer, result As Integer
Private Sub cmdStart2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdStart2.Click
        Dim a(10, 10) As Boolean, b(10, 10) As Boolean, c As Integer, x As Integer, y As Integer _
        , ox As Integer, oy As Integer, d As Integer
        For c = 0 To 2
            Try
Tryline:
                For x = 0 To 9
                    For y = 0 To 9
                        a(x, y) = False 'clears array after each Try/Catch cycle
                    Next y
                Next x
                ox = Int(Rnd() * 10) 'coordinates saved in origional x/y
                oy = Int(Rnd() * 10)
                d = Int(Rnd() * 4 + 1) 'direction
                If a(ox, oy) = True Then
                    GoTo Tryline
                End If
                a(ox, oy) = True 'marked
                Select Case d
                    Case 1 'up
                        For y = 1 To 3
                            If b(ox, oy + y) = True Then
                                GoTo Tryline
                            Else
                                a(ox, oy + y) = True
                            End If
                        Next y
                    Case 2 'Down
                        For y = 1 To 3
                            If b(ox, oy - y) = True Then
                                GoTo Tryline
                            Else
                                a(ox, oy - y) = True
                            End If
                        Next y
                    Case 3 'Left
                        For x = 1 To 3
                            If b(ox - x, oy) = True Then
                                GoTo Tryline
                            Else
                                a(ox - x, oy) = True
                            End If
                        Next x
                    Case 4 'right
                        For x = 1 To 3
                            If b(ox + x, oy) = True Then
                                GoTo Tryline
                            Else
                                a(ox + x, oy) = True
                            End If
                        Next x
                End Select
            Catch q As IndexOutOfRangeException
                GoTo Tryline
            Catch q As Exception
                Dim result As Integer
                result = MsgBox(q.Message)
                If result = vbOK Then
                    Beep()
                    End
                End If
            Finally
                For x = 0 To 9
                    For y = 0 To 9
                        If a(x, y) = True Then
                            b(x, y) = True
                        End If
                    Next y
                Next x
                'make picture boxes do all of the trues in this part within for loop, then after for loop terminates do the falses
                For x = 0 To 9
                    For y = 0 To 9
                        If b(x, y) = True Then
                            pics(x, y) = New PictureBox
                            pics(x, y).Size = New Size(30, 30)
                            pics(x, y).Left = (x * 30) + 5
                            pics(x, y).Top = (y * 30) + 5
                            pics(x, y).Visible = True
                            pics(x, y).BackColor = Color.Gold
                            Controls.Add(pics(x, y))
                        End If
                    Next y
                Next x
            End Try
        Next c
        For x = 0 To 9
            For y = 0 To 9
                If b(x, y) = False Then
                    pics(x, y) = New PictureBox
                    pics(x, y).Size = New Size(30, 30)
                    pics(x, y).Left = (x * 30) + 5
                    pics(x, y).Top = (y * 30) + 5
                    pics(x, y).Visible = True
                    pics(x, y).BackColor = Color.RoyalBlue
                    Controls.Add(pics(x, y))
                End If
            Next y
        Next x
    End Sub
End Class

What it does is it first uses the array a(10,10) as a kind of temp. for each cycle through the Try/Catch blocks. Once a set of 3 positions for the ship finally passes all of the tests, it drops down to the Finally block. I did 3 ships of 3 length, and because it loops the entire Try Catch Finally structure, a(x,y) only has to remember one ship. But in the end, all of the ships need to be remembered, so the position of the ship is transferred to the permanent array b(10,10) so that the positions of the ships can be marked and compared to the results of the rnd to avoid overlaps.

Now because I don't trust a(x,y), I used a For loop to search b(x,y) for trues, and when it finds a true, it makes a gold picture box in that position on the form to indicate that part of the ship is there. And at the end, once VB drops out of the giant For c loop, It searches the b(x,y) array for any parts that are not marked with a ship, aka false. True to the physical battleship board, I made any position that does not contain a ship get a picBox that is blue.

Now, any questions? Comments? Other_______?
Thanks again for reading my very long post. I felt the need to explain myself. And by the way, I've attatched a screenshot of what the program looks like when the board is up. So if you like, take a look. And THANK YOU!!!
Attached Image
Was This Post Helpful? 0
  • +
  • -

#7 _HAWK_  Icon User is online

  • Master(Of Foo)
  • member icon

Reputation: 1055
  • View blog
  • Posts: 4,086
  • Joined: 02-July 08

Re: Question on controlling picture boxes through a 2D picture box array?

Posted 21 August 2011 - 06:50 PM

Well that is how we learn. We need to challenge ourselves if we want to be good. Here's the cool part of being here - as long as you make an attempt we will help. I wanted to teach you the correct way - the OOP way - a code manageable way. How hard is your code to follow? How many loops do you have. My way had 2 loops, one in the paint method and one in the mouse down event - done! Sure you have some stuff to learn: Rectangle structure, List(Of T), implementing a custom class. You didn't want to stop learning with 2D arrays - right?
Was This Post Helpful? 2
  • +
  • -

#8 hypercat11  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 20-August 11

Re: Question on controlling picture boxes through a 2D picture box array?

Posted 22 August 2011 - 09:23 AM

View Posthawkvalley1, on 21 August 2011 - 06:50 PM, said:

Well that is how we learn. We need to challenge ourselves if we want to be good. Here's the cool part of being here - as long as you make an attempt we will help. I wanted to teach you the correct way - the OOP way - a code manageable way. How hard is your code to follow? How many loops do you have. My way had 2 loops, one in the paint method and one in the mouse down event - done! Sure you have some stuff to learn: Rectangle structure, List(Of T), implementing a custom class. You didn't want to stop learning with 2D arrays - right?


Thanks! No I dont want to stop learning after 2D arrays. That's the way I made it work, but I've found out that there's almost always an easier way than mine. With me, I just write the code straight down, and then do debugging for a few hours/days depending on te program. I'd love to learn your way. It sounds so much simpler. I'm going to rephrase my "too complicated" to "I haven't learned it yet." I'll do some research, and come back with what I find. And thanks again for motivating me. By the way, is there a mouse click/button down event for a picture box?
Was This Post Helpful? 0
  • +
  • -

#9 _HAWK_  Icon User is online

  • Master(Of Foo)
  • member icon

Reputation: 1055
  • View blog
  • Posts: 4,086
  • Joined: 02-July 08

Re: Question on controlling picture boxes through a 2D picture box array?

Posted 22 August 2011 - 10:02 AM

Yes, yes there is a mouse down event. In this event you will find an e variable in the signature:

Private Sub pb_mouse_down(sender As Object, e As MouseEventArgs)'<- here 
Dim pt As Point = e.Location '<- coordinates



You will also be using the paint event for the PB. Using the e.Graphics object for drawing. Looks like you will be needing the e.Graphics.FillRectangle(...) method for the yellow color and e.Graphics.DrawRectangle(...) for a border if you need one. There are some great GDI+ tutorials out there. If you are not drawing images you can get away with not having a custom class, but rather store the rectangles in a List(Of Rectangle).

I remember one of the first programs I made. I got it to work, but the code was getting so complicated and hard to manage and repair when updating. I kept learning and found that the use of custom objects and an OOP design made this program much simpler to maintain.

This post has been edited by hawkvalley1: 22 August 2011 - 10:03 AM

Was This Post Helpful? 2
  • +
  • -

#10 hypercat11  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 20-August 11

Re: Question on controlling picture boxes through a 2D picture box array?

Posted 22 August 2011 - 06:15 PM

I'll look around, but stupid question... What should I be looking for? Custom class rectangle? GUI+ Tutorials? How to use rectangles? I'll look around, but I might hit a wall if I don't know what to look for.

View Posthawkvalley1, on 20 August 2011 - 10:07 PM, said:

Custom class object is like the other objects you have used, but this time we making one just for you.

Simple layout:
Public Class xBox
  Public Rect As New Rectangle()
  Public isFound As Boolean
  Public img As Image
   
  Public Sub New(img As Image)
    Me.img = img
  End Sub
End Class


List of said new objects:
'this goes in your form where you draw stuff
Private boxes As New List(Of xBox)


Now each time you add a new object you define it's location by setting the x, y properties of the rectangle. Now after you have loaded several of these objects you can try to mouse click on the picturebox - using the mouse_down event and iterate this List to see if any of the rectangle.Contains(<mouse location>) then you set the isFound boolean to True and update the picturebox. The paint event iterates the List and only draws the ones that isFound = True. viola

Now I have given you a good start. Play with it and let me know what you come up with!



Oh! Now I think I see how to do that! You create a new class, kind of like a picture box is a class, or a command button is a class, except with a rectangle and you define the properties of Rectangle, then create one if the area it contains is clicked! Haha sorry it just took a while for everything to click!
Was This Post Helpful? 0
  • +
  • -

#11 _HAWK_  Icon User is online

  • Master(Of Foo)
  • member icon

Reputation: 1055
  • View blog
  • Posts: 4,086
  • Joined: 02-July 08

Re: Question on controlling picture boxes through a 2D picture box array?

Posted 22 August 2011 - 06:33 PM

The reason I used a boolean is so you have a way to check if the rectangle has been clicked. In the mouse_down event you iterate the list and check each Rect if it .Contains(e.location) if so you set it's isFound = true, then refresh the PB. Your paint event iterates the list and checks this boolean and if true then fill the rectangle and what ever else you want graphically.
Was This Post Helpful? 1
  • +
  • -

#12 hypercat11  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 20-August 11

Re: Question on controlling picture boxes through a 2D picture box array?

Posted 24 August 2011 - 05:54 PM

View Posthawkvalley1, on 22 August 2011 - 06:33 PM, said:

The reason I used a boolean is so you have a way to check if the rectangle has been clicked. In the mouse_down event you iterate the list and check each Rect if it .Contains(e.location) if so you set it's isFound = true, then refresh the PB. Your paint event iterates the list and checks this boolean and if true then fill the rectangle and what ever else you want graphically.



I tried the myRectangle(x,y).Contains(e.location). That didnt work. I tried many variations of that and they didn't work. I looked around again and found that you need to define it as a public function... What does that mean? I'm trying it like this, and then putting a reference to it in the frmForm1 MouseDown event code section. Will that work?
Public Overloads Function Contains(ByRef sender As MouseButtons, ByVal e As System.EventArgs) Handles myRectangle.MouseDown

    End Function
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdEnemySet.Click
        'If the rectangle gets the mousedown event then reveal wether its a hit or miss. Get explosion pic
        Dim myGraphics As Graphics, myPen As New Pen(Color.Blue), x As Integer, y As Integer
        myGraphics = Graphics.FromHwnd(ActiveForm().Handle)
        For x = 0 To 9
            For y = 0 To 9
                myRectangle(x, y) = New Rectangle(x:=(x * 30), y:=(y * 30), Width:=30, Height:=30)
                myGraphics.DrawRectangle(pen:=myPen, rect:=myRectangle(x, y))
            Next y
        Next x
    End Sub

Was This Post Helpful? 0
  • +
  • -

#13 _HAWK_  Icon User is online

  • Master(Of Foo)
  • member icon

Reputation: 1055
  • View blog
  • Posts: 4,086
  • Joined: 02-July 08

Re: Question on controlling picture boxes through a 2D picture box array?

Posted 24 August 2011 - 07:16 PM

You paint in the paint event so that your objects are always showing whether you tell it to paint or the system tells your PB to paint. You also use the e.Graphics object in the paint event - there is no reason to create an object that you should dispose of - if you create it. No need to override the Contains function as the one you want is perfect the way it is. Using the class above:
Private Sub pb_mouseDown(sender As Object, e As MouseEventArgs) Handles pb.MouseDown
  If e.Button =  MouseButtons.Left Then
     For Each xb As xBox In boxes
        If xb.Rect.Contains(e.Location) 'we have a hit
           xb.isFound = True
  ...


Now when painting you iterate the collection the same way but check each object for the .isFound and if it is true then paint it.
Was This Post Helpful? 0
  • +
  • -

#14 hypercat11  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 20-August 11

Re: Question on controlling picture boxes through a 2D picture box array?

Posted 24 August 2011 - 08:42 PM

Ok. Now I'm starting to think were not on the same page here... I'm using the array of rectangles that are created from the code in a grid layout in a rectangle array myRectangle(x,y). I need a way to have the rectangles execute some code on click. The rectangles are created entirely in code so I have no way of accessing them in the design. How can I do that? I'm thinking since the parent form is the drawing surface, the form would detect a mouse click, and it would be easy to just cycle through the array and find which rectangle contains the mouse click. Would it be something like
If myRectangle.Contains(form.e) Then...
I really just don't know how to use that statement. And all the research I've done has, like usual, turned up nothing cause this is a special case. Something tells me the answer is really simple... Oh well...
Was This Post Helpful? 0
  • +
  • -

#15 _HAWK_  Icon User is online

  • Master(Of Foo)
  • member icon

Reputation: 1055
  • View blog
  • Posts: 4,086
  • Joined: 02-July 08

Re: Question on controlling picture boxes through a 2D picture box array?

Posted 24 August 2011 - 08:53 PM

Well the reason I used a class that had a rectangle field was to add a boolean for marking an object as found - cause you wanted to paint the ones you clicked on - or it seemed that way. If you defined several of these object's rectangle field then they exist and when you mouse down the coordinates can be checked to see if they are inside the bounds of the rectangle. That being said if you need more info to process you add more fields or properties to this custom class - extendable object!
Was This Post Helpful? 0
  • +
  • -

  • (2 Pages)
  • +
  • 1
  • 2