Turn on thread page Beta
    • Thread Starter
    Offline

    3
    ReputationRep:
    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.
    Offline

    18
    ReputationRep:
    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
    • Thread Starter
    Offline

    3
    ReputationRep:
    I want to be able to change the backcolor or the image of each picturebox in the grid when the mouse clicks on it.
    Offline

    18
    ReputationRep:
    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)
    • Thread Starter
    Offline

    3
    ReputationRep:
    Thanks , it works perfectly .
    • Thread Starter
    Offline

    3
    ReputationRep:
    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?
    Offline

    18
    ReputationRep:
    (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?
    • Thread Starter
    Offline

    3
    ReputationRep:
    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: 47
Size:  14.5 KB
    Offline

    18
    ReputationRep:
    (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: 47
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
    • Thread Starter
    Offline

    3
    ReputationRep:
    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 ?
    Offline

    19
    ReputationRep:
    (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.
    Offline

    18
    ReputationRep:
    (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
    Offline

    18
    ReputationRep:
    (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).
    Offline

    19
    ReputationRep:
    (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.
    Offline

    18
    ReputationRep:
    (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.
 
 
 

University open days

  1. University of Cambridge
    Christ's College Undergraduate
    Wed, 26 Sep '18
  2. Norwich University of the Arts
    Undergraduate Open Days Undergraduate
    Fri, 28 Sep '18
  3. Edge Hill University
    Faculty of Health and Social Care Undergraduate
    Sat, 29 Sep '18
Poll
Which accompaniment is best?
Help with your A-levels

All the essentials

The adventure begins mug

Student life: what to expect

What it's really like going to uni

Rosette

Essay expert

Learn to write like a pro with our ultimate essay guide.

Uni match

Uni match

Our tool will help you find the perfect course for you

Study planner

Create a study plan

Get your head around what you need to do and when with the study planner tool.

Study planner

Resources by subject

Everything from mind maps to class notes.

Hands typing

Degrees without fees

Discover more about degree-level apprenticeships.

A student doing homework

Study tips from A* students

Students who got top grades in their A-levels share their secrets

Study help links and info

Can you help? Study help unanswered threadsRules and posting guidelines

Groups associated with this forum:

View associated groups

The Student Room, Get Revising and Marked by Teachers are trading names of The Student Room Group Ltd.

Register Number: 04666380 (England and Wales), VAT No. 806 8067 22 Registered Office: International House, Queens Road, Brighton, BN1 3XE

Write a reply...
Reply
Hide
Reputation gems: You get these gems as you gain rep from other members for making good contributions and giving helpful advice.