Battleships game vb.net Watch

M-AR
Badges: 3
Rep:
?
#1
Report Thread starter 9 months ago
#1
I am currently creating a battleships game in vb.net and I am currently stuck on how to get the mouseposition using the mousedown events.
-I have created my grids using an array of pictureboxes and im struggling to make it interactive using mouse events.

This is my code for one of the grids :


Public Sub Init()

Me.Controls.Clear()
'Drawing the first player's grid'
For x As Integer = 0 To Columns - 1
For y As Integer = 0 To Rows - 1
grid(x, y) = New PictureBox()
grid(x, y).Size = New Size(50, 50)
grid(x, y).Location = New Point((x * 50), (y * 50))
grid(x, y).BackColor = Color.LightGray
grid(x, y).BorderStyle = BorderStyle.FixedSingle

Me.Controls.Add(grid(x, y))

Next
Next

End sub

Thanks.
0
quote
reply
winterscoming
Badges: 18
Rep:
?
#2
Report 9 months ago
#2
What exactly are you trying to do with the mouse position? Whatever it is that you're trying to do, there might be an easier way than messing around with the mouse position.

For example, if you want to run some code when the mouse enters one of your PictureBox controls, then you could use the MouseEnter event for that control:
https://msdn.microsoft.com/en-gb/lib...ouseenter.aspx

Similarly, you could use one of the Mouse Click events when one of your PictureBox controls receives a mouse click:
https://msdn.microsoft.com/en-us/lib...v=vs.110).aspx

If you need to have a click handler which listens on behalf of a PictureBox control, then you could create your own custom PictureBox which knows about its own click handler, and any other information which happens to be specific to that PictureBox. for example:
Code:
Public Class MyGridPictureBox 
    Inherits System.Windows.Forms.PictureBox 

End Class
It's usually a little bit easier to split your code down into separate controls with their own functions, instead of shoving everything in to your main Form.

If you really want the mouse coordinates, you can use Control.MousePosition which is a Point object containing the X, Y screen coordinates of the mouse:
https://msdn.microsoft.com/en-us/lib...v=vs.110).aspx

Remember, its coordinates are relative to the top-left corner of your screen. Your app will be running in a window, but its top-left screen coordinates could change (the user can move the window, and they might be able to resize it as well, and they might be able to hide areas of the window, etc), So you'll need an extra step to get one which is relative to your control instead, using the PointToClient method:
https://msdn.microsoft.com/en-us/lib...code-snippet-1
2
quote
reply
M-AR
Badges: 3
Rep:
?
#3
Report Thread starter 9 months ago
#3
I want to be able to change the backcolor or the image of each picturebox in the grid when the mouse clicks on it.
0
quote
reply
winterscoming
Badges: 18
Rep:
?
#4
Report 9 months ago
#4
In which case I would think about doing that inside the Control instead, then you won't need to care about the mouse position.

For example, if you create your own control which Inherits PictureBox, you can handle the OnMouseClick event specifically for that control - e.g.
Code:
Public Class MyGridPictureBox
    Inherits PictureBox

    Private _isClicked As Boolean = False
    
    Protected Overrides Sub OnMouseDown (e As MouseEventArgs)
        If (_isClicked)
            BackColor = Color.LightGray
        Else
            BackColor = Color.DarkRed
        End If
        _isClicked = Not _isClicked
    End Sub
End Class
Then the code which creates the PictureBox objects can just create MyGridPictureBox instead, allowing that to care about the mouse event:
Code:
Public Sub Init()
 
    Me.Controls.Clear()
    'Drawing the first  player's grid'
    For x = 0 To Columns - 1
        For y = 0 To Rows - 1
            grid(x, y) = New MyGridPictureBox()
            grid(x, y).Size = New Size(50, 50)
            grid(x, y).Location = New Point((x * 50), (y * 50))
            grid(x, y).BackColor = Color.LightGray
            grid(x, y).BorderStyle = BorderStyle.FixedSingle
            Me.Controls.Add(grid(x, y))
        Next
    Next 
     End Sub
Also, in the spirit of keeping all of the PictureBox related code together, you could move those properties into its constructor too:
Code:
Public Class MyGridPictureBox
    Inherits PictureBox

    Private _isClicked As Boolean = False

    Public Sub New(x As Integer, y As Integer) 
        Size = New Size(50, 50)
        Location = New Point((x * 50), (y * 50))
        BackColor = Color.LightGray
        BorderStyle = BorderStyle.FixedSingle
    End Sub

    Protected Overrides Sub OnMouseDown (e As MouseEventArgs)
        If (_isClicked)
            BackColor = Color.LightGray
        Else
            BackColor = Color.DarkRed
        End If
        _isClicked = Not _isClicked
    End Sub
End Class
And then simplify the Init() method slightly:
Code:
Public Sub Init()
 
    Me.Controls.Clear()
    'Drawing the first  player's grid'
    For x = 0 To Columns - 1
        For y = 0 To Rows - 1
            grid(x, y) = New MyGridPictureBox(x, y)
            Me.Controls.Add(grid(x, y))
        Next
    Next 
     End Sub
(This doesn't really change the way it works, it's more about the way you organise code, to keep it close to the place where that code is used)
0
quote
reply
M-AR
Badges: 3
Rep:
?
#5
Report Thread starter 9 months ago
#5
Thanks , it works perfectly .
0
quote
reply
M-AR
Badges: 3
Rep:
?
#6
Report Thread starter 9 months ago
#6
I plan on using picture boxes for my ships and I want to be able to drag and drop them on to the players grid.How do I approach this?
0
quote
reply
winterscoming
Badges: 18
Rep:
?
#7
Report 9 months ago
#7
(Original post by M-AR)
I plan on using picture boxes for my ships and I want to be able to drag and drop them on to the players grid.How do I approach this?
That should be fairly easy - the various events and properties you'll need for this are explained on here: https://msdn.microsoft.com/en-gb/library/ms973845.aspx

You can create a 'draggable' control by calling DoDragDrop() in the MouseDown method for a PictureBox (or any other control) to switch the mouse into "DragDrop mode". DragDrop mode basically holds some data with the mouse and allows you to "drop" that data onto another 'destination' control in your app.

The 'destination' PictureBox control needs to be set up to receive the dragged/dropped data too. There are 3 things to do on that:
  • Set the AllowDrop property to True. (As the name suggests, allows a dragging mouse to call "Drag" methods on the control)
  • Add a method to handle the DragEnter event (Called when the dragging mouse enters the control)
  • Add a method to handle the DragDrop event (Called when the dragging mouse is inside the control and the mouse button is released)


You might also want to create another new derived PictureBox class for your "draggable" control. For example, extending the code from the previous post, here's a Blue coloured PictureBox which is draggable because it calls DoDragDrop when it receives a MouseDown. The control has also got some plain text string data which it will "send" with the mouse:
Code:
Public Class MyDraggablePictureBox
    Inherits PictureBox

    Private ReadOnly _data As String

    Public Sub New(data As String, x As Integer, y As Integer)
        Size = New Size(50, 50)
        Location = New Point((x * 50), (y * 50))
        BackColor = Color.Blue
        BorderStyle = BorderStyle.FixedSingle
        _data = data
    End Sub

    Private Sub HandleMouseDown (sender As Object, args As MouseEventArgs) Handles Me.MouseDown
        DoDragDrop(_data, DragDropEffects.Move)
    End Sub
End Class
This new 'Draggable' picture box control isn't doing a whole lot - similar to the PictureBox from the previous post, it's got a border, colour, position. The main difference is that it also has some data (to be carried by the mouse when the mouse drags), and its HandleMouseDown method simply enables the DragDrop mode using the data, and setting the mouse cursor to "Move".


Next, here's the same MyGridPictureBox control from the previous post which can now receive a dragging mouse using 'AllowDrop = True', 'Handles DragEnter' and 'Handles DragDrop' - it checks the data being carried by the mouse and uses that data to change the colour either to Green or Purple:
Code:
Public Class MyGridPictureBox
   Inherits PictureBox

   Private _isClicked As Boolean = False

   Public Sub New(x As Integer, y As Integer)
       Size = New Size(50, 50)
       Location = New Point((x * 50), (y * 50))
       BackColor = Color.LightGray
       BorderStyle = BorderStyle.FixedSingle
       AllowDrop = True
   End Sub

   Private Sub HandleMouseDown (sender As Object, args As MouseEventArgs) Handles Me.MouseDown
       If (_isClicked)
           BackColor = Color.LightGray
       Else
           BackColor = Color.DarkRed
       End If
       _isClicked = Not _isClicked
   End Sub

   Private Sub HandleDragEnter (sender As Object, args As DragEventArgs) Handles Me.DragEnter
       args.Effect = DragDropEffects.Move
   End Sub

   Private Sub HandleDragDrop (sender As Object, args As DragEventArgs) Handles Me.DragDrop
       Dim data = args.Data.GetData(DataFormats.Text)
       if String.Equals(data, "Fred", StringComparison.OrdinalIgnoreCase)
           BackColor = Color.Green
       Else If String.Equals(data, "Barney", StringComparison.OrdinalIgnoreCase)
           BackColor = Color.Purple
       End If
   End Sub
End Class
What's changed from the same control from the previous reply:
  • The constructor now sets AllowDrop = True to allow it to receive a mouse drop.
  • A new HandleDragEnter method - doesn't really do much aside from set the mouse pointer to 'Move' when a dragging mouse enters the control
  • A new HandleDragDrop method - "receives" the dragging data and sets the colour to 'Green' if the data is "Fred", or 'Purple' if the data is "Barney".


Lastly, a small update in the Grid form which creates a pair of MyDraggablePictureBox objects and places them to the side of the app window:
Code:
Public Class Grid
    Private Const Columns As Integer = 8
    Private Const Rows As Integer = 8
    Private ReadOnly _grid(8, 8) As MyGridPictureBox

    Private Sub Init()
        For x = 0 To Columns - 1
            For y = 0 To Rows - 1
                _grid(x, y) = New MyGridPictureBox(x, y)
                Controls.Add(_grid(x, y))
            Next
        Next

        Controls.Add(New MyDraggablePictureBox("Fred", 10, 1))
        Controls.Add(New MyDraggablePictureBox("Barney", 10, 3))
    End Sub
End Class
Not much extra here either - just a couple of lines at the end of the Init() method which adds a couple of MyDraggablePictureBox controls, with data "Fred" and "Barney" (that's the data which will be carried by the mouse when the PictureBox is dragged), and an x,y position.

Does this make sense?
0
quote
reply
M-AR
Badges: 3
Rep:
?
#8
Report Thread starter 9 months ago
#8
I understand what you have done but when I attempt to move one of the draggable picture boxes this error pauses the program.Do you know what I can to to fix this ?
Name:  c45.PNG
Views: 59
Size:  14.5 KB
0
quote
reply
winterscoming
Badges: 18
Rep:
?
#9
Report 9 months ago
#9
(Original post by M-AR)
I understand what you have done but when I attempt to move one of the draggable picture boxes this error pauses the program.Do you know what I can to to fix this ?
Name:  c45.PNG
Views: 59
Size:  14.5 KB
That exception means something in your program is set to 'Nothing' (that's the VB equivalent to 'null' ).

I suspect that the value of _data is null. Have you checked its value? have you set it to anything in the constructor? What data are you actually passing into it exactly?

Otherwise, you'll need to set some debug breakpoints, both to your HandleMouseDown and HandleDragDrop to find out what part of your program has a null value
0
quote
reply
M-AR
Badges: 3
Rep:
?
#10
Report Thread starter 9 months ago
#10
I fixed it . On the form that the grid is on ,I have created a button called "Set Grid".The purpose of this button is to only enable the HandlesMouseDown sub in the MyGridPictureBox class if it is pressed. Is it possible to call a sub that exists in a different class ?
0
quote
reply
New- Emperor
Badges: 19
Rep:
?
#11
Report 9 months ago
#11
(Original post by M-AR)
I am currently creating a battleships game in vb.net and I am currently stuck on how to get the mouseposition using the mousedown events.
-I have created my grids using an array of pictureboxes and im struggling to make it interactive using mouse events.

This is my code for one of the grids :


Public Sub Init()

Me.Controls.Clear()
'Drawing the first player's grid'
For x As Integer = 0 To Columns - 1
For y As Integer = 0 To Rows - 1
grid(x, y) = New PictureBox()
grid(x, y).Size = New Size(50, 50)
grid(x, y).Location = New Point((x * 50), (y * 50))
grid(x, y).BackColor = Color.LightGray
grid(x, y).BorderStyle = BorderStyle.FixedSingle

Me.Controls.Add(grid(x, y))

Next
Next

End sub

Thanks.
Have you considered using a IDE like u it’s or somthing you got to use C# or Java but there are some really good online resource to help you out and it make making a games a lot more fun an easy. C# is the next step from VV and much more versatile.

Good luck.
0
quote
reply
winterscoming
Badges: 18
Rep:
?
#12
Report 9 months ago
#12
(Original post by M-AR)
I fixed it . On the form that the grid is on ,I have created a button called "Set Grid".The purpose of this button is to only enable the HandlesMouseDown sub in the MyGridPictureBox class if it is pressed. Is it possible to call a sub that exists in a different class ?
You could do that, but I think it'd be a bit messy. What you're describing here sounds like just remembering whether a button has been pressed (or to put it in programming terms, you're describing a state which is used to change the way your UI behaves).

State is pretty fundamental to writing GUIs; the problem with state is that some kind of state change which might be initiated from one part of the UI is probably important for another part of the UI (as it is in your case here). So for that reason, a very common way to handle state in a GUI app is to create a completely separate class which only contains properties about the state.

The reason for doing this is that it can get really convoluted to have different Controls talking directly to each other. The neat thing about splitting your app into separate controls is that you can keep them nicely self-contained and things stay fairly simple that way. If those controls start calling methods belonging to other controls then it can make the code get a bit messy, - the controls stop being so self-contained, and after a while you might find out that you've coded yourself up a "spaghetti" GUI.

Obviously there's nothing actually stopping you from having them talk directly to each other, but I'd personally try to avoid it for the sake of my own sanity when trying to trace through the code to see what's actually going on

In your case, the app state class is probably something as simple as:
Code:
Public Class MyAppState
    Public Property IsDragDropEnabled As Boolean = False
    'other app state properties go here in future...
End Class
Then all you need to do is create a single instance of MyAppState in the main form class (i.e. the class where you create all the other PictureBoxes), and pass that instance to all of the PictureBox instances through their respective New / constructor methods (so that the various PictureBoxes can keep a private reference to that 'state' instance...).

(i.e. - Using the 'grid' form example above creating a state instance and passing it to those different PictureBoxes):
Code:
Public Class Grid
    Private Const Columns As Integer = 8
    Private Const Rows As Integer = 8
    Private ReadOnly _grid(8, 8) As MyGridPictureBox
    Private ReadOnly _state As MyAppState = New MyAppState()

    Private Sub Init()
        For x = 0 To Columns - 1
            For y = 0 To Rows - 1
                _grid(x, y) = New MyGridPictureBox(x, y, _state)
                Controls.Add(_grid(x, y))
            Next
        Next

        Controls.Add(New MyDraggablePictureBox("Fred", 10, 1, _state))
        Controls.Add(New MyDraggablePictureBox("Barney", 10, 3, _state))
    End Sub
 End Class
So, if the draggable PictureBox has also got a private field called _state that has been picked up from its New / constructor method, then within your HandleMouseDown Subs you can do things like this:
Code:
Private Sub HandleMouseDown (sender As Object, args As MouseEventArgs) Handles Me.MouseDown
    If (Me._state.IsDragDropEnabled)
        DoDragDrop(Me._data, DragDropEffects.Move)
    End If
End Sub
Which of course would work because Me._state just refers to a single instance/object in memory belonging to the main form - when one part of the app changes a property on _state, then all the other places which refer to that same object will have access to those exact same properties.

In general, it's not a bad thing to pass references of objects from the main form through a New / constructor method - it's a pretty standard way of getting different parts of your app to talk to each other. Try not to overdo it too much though - you can easily end up creating huge long lists of parameters in a constructor, which can get a bit messy
0
quote
reply
winterscoming
Badges: 18
Rep:
?
#13
Report 9 months ago
#13
(Original post by New- Emperor)
Have you considered using a IDE like u it’s or somthing you got to use C# or Java but there are some really good online resource to help you out and it make making a games a lot more fun an easy. C# is the next step from VV and much more versatile.

Good luck.
These days there's actually no major difference between C# and VB.NET aside from the superficial syntax differences. (i.e. the fact that VB.NET uses keywords for a lot of things where C# uses various symbols and brackets)

Microsoft have evolved VB.NET so much that aside from a few minor caveats, VB.NET is now mostly just an alternative syntax for C#. In nearly all cases, a single line of C# code can be directly translated into a single line of VB.NET code by altering its syntax. The same is also true in nearly all cases from C# to VB.NET. (I can't think of the differences off the top of my head, but I'm fairly sure a few of them do exist).
0
quote
reply
New- Emperor
Badges: 19
Rep:
?
#14
Report 9 months ago
#14
(Original post by winterscoming)
These days there's actually no major difference between C# and VB.NET aside from the superficial syntax differences. (i.e. the fact that VB.NET uses keywords for a lot of things where C# uses various symbols and brackets)

Microsoft have evolved VB.NET so much that aside from a few minor caveats, VB.NET is now mostly just an alternative syntax for C#. In nearly all cases, a single line of C# code can be directly translated into a single line of VB.NET code by altering its syntax. The same is also true in nearly all cases from C# to VB.NET. (I can't think of the differences off the top of my head, but I'm fairly sure a few of them do exist).
True as that is mostly games are written in C# with unity or UE4 somthing to do with the library’s that come with the IDE.

But well done to the OP anyway this is a big achievement.
0
quote
reply
winterscoming
Badges: 18
Rep:
?
#15
Report 9 months ago
#15
(Original post by New- Emperor)
True as that is mostly games are written in C# with unity or UE4 somthing to do with the library’s that come with the IDE.

But well done to the OP anyway this is a big achievement.
I actually meant the VB.NET language itself rather than the .NET Framework But yes VB.NET isn't supported by Mono, so any framework like Unity which is based on Mono won't be usable with VB.NET

With that said, the Unity team are apparently working on moving away from Mono to use the .NET Standard instead, so if/when that work is eventually complete, it should mean you'd be able to use Unity with any of the supported .NET Standard languages including Visual Basic, F#, C++/CLR, etc.
0
quote
reply
X

Quick Reply

Attached files
Write a reply...
Reply
new posts
Latest
My Feed

See more of what you like on
The Student Room

You can personalise what you see on TSR. Tell us a little about yourself to get started.

Personalise

University open days

  • University of Lincoln
    Mini Open Day at the Brayford Campus Undergraduate
    Wed, 19 Dec '18
  • University of East Anglia
    UEA Mini Open Day Undergraduate
    Fri, 4 Jan '19
  • Bournemouth University
    Undergraduate Mini Open Day Undergraduate
    Wed, 9 Jan '19

Were you ever put in isolation at school?

The results of this poll are hidden until the poll closes.

Watched Threads

View All