Button collision event vb.net - vb.net

I'm trying to make some buttons move around in a rapid manner. Each click of a specific button should "reward" the player with a certain quantity of points (both positive or negative). This is a similar idea to some of the aspects in some of the "idiot test games" you see online.
How can I perform collision checks with the buttons?
I know it's possible with picture boxes to perform event collisions, with the following code picObject1.bounds.intersectsWith(picObject2.bounds).
However, when I tried using that function for buttons, they didn't register as a collision. I do not know if that is because buttons don't have bounds (though that doesn't sound right) or due to some other hidden detail that I have missed.
Any pointers in the right direction would be extremely useful!

Handle the Click event for the buttons. The code might look something like this:
Public Class Form1
Private PlayerScore As Integer = 0
Private Buttons() As Button
Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load
Buttons = Enumerable.Range(0,10).
Select(Function(i)
i = New Button()
AddHandler i.Click, AddressOf ScoreClick
Me.Controls.Add(i)
Return i
End Function)
End Sub
Dim rnd As New Random()
Private Sub ScoreClick(ByVal sender As Object, ByVal e As EventArgs)
Dim button As Button = DirectCast(sender, Button)
PlayerScore += rnd.Next(-10, 10)
End Sub
End Class
Now just add a timer to to the form to move the buttons around.

Related

Improve UI responsiveness on windows form application

I am currently working on a project and decided to create a user interface for it using visual studio with a windows forms application(Visual Basic).
The problem I'm facing is that the user interface doesn't respond as quickly and smoothly as I'd like it to.
Mainly, I am using pictures as buttons to make the user form look more modern.
However, when I hover my mouse over a "button" it takes a while until the "highlighted button" appears.
P1 is the picture of the "normal button" and P2 is the picture of the "highlighted button".
Here is the short code I have for now:
Public Class Main
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
End Sub
Private Sub PictureBox1_MouseHover(sender As Object, e As EventArgs) Handles P1.MouseHover
P1.Visible = False
P2.Visible = True
End Sub
Private Sub P2_MouseClick(sender As Object, e As MouseEventArgs) Handles P2.MouseClick
'Call cmdInit()
'Call cmdConnectRobot()
'Call cmdUnlock()
End Sub
Private Sub Main_MouseHover(sender As Object, e As EventArgs) Handles Me.MouseHover
If P2.Visible = True Then
P2.Visible = False
P1.Visible = True
End If
End Sub
Private Sub P4_Click(sender As Object, e As EventArgs) Handles P4.Click
End Sub
End Class
Another problem I'm facing is that when I call other subs, the user form becomes unresponsive while the sub is running.
I researched and found that I could implement multi threading or async tasks but I'm a bit lost and would be extremely grateful if someone could guide me or point me in the right direction.
Thanks in advance!!
In this case your UI is responsive, however the MouseHover event is only raised once the mouse cursor has hovered over the control for a certain amount of time (default is 400 ms), which is what is causing the delay.
What you are looking for is the MouseEnter event, which is raised as soon as the cursor enters ("touches") the control:
Private Sub P1_MouseEnter(sender As Object, e As EventArgs) Handles P1.MouseEnter
P1.Visible = False
P2.Visible = True
End Sub
You can then use that together with the MouseLeave event on the second picture box to switch back to the non-highlighted image:
Private Sub P2_MouseLeave(sender As Object, e As EventArgs) Handles P2.MouseLeave
P1.Visible = True
P2.Visible = False
End Sub
However switching picture boxes like this is not optimal. I recommend you to look into how you can use Application Resources, then modify your code to only switch the image that one picture box displays.
Here are the basic steps:
Right-click your project in the Solution Explorer and press Properties.
Select the Resources tab.
To add an image either:
a. Drag and drop the image onto the resource pane.
b. Click the arrow next to the Add Resource... button and press Add Existing File....
Now, in your code add this right below Public Class Form1:
Dim ButtonNormal As Image = My.Resources.<first image name>
Dim ButtonHighlighted As Image = My.Resources.<second image name>
Replace <first image name> and <second image name> with the names of your button images.
Now you only need one picture box for the button:
Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
P1.Image = ButtonNormal
End Sub
Private Sub P1_MouseEnter(sender As System.Object, e As System.EventArgs) Handles P1.MouseEnter
P1.Image = ButtonHighlighted
End Sub
Private Sub P1_MouseLeave(sender As System.Object, e As System.EventArgs) Handles P1.MouseLeave
P1.Image = ButtonNormal
End Sub
I'll start by saying i'm not a programmer by trade, and i'm sure someone will point out better ways of doing these things, but in regards to the threading question it's fairly simple to implement.
Imports System.Threading
Public Class Form1
Dim WorkerThread As New Thread(AddressOf DoWork)
'WorkerThread' can be any name you like, and 'DoWork' is the name of the sub you want to run in the new thread, and is launched by calling:
WorkerThread.start()
However there is a catch, the new thread is not able to interact directly with the GUI, so you cannot change textbox text etc... I find the easiest way to get changes made to the GUI is to drag a timer onto your form, and have the new thread change variables (pre-defined just below Public Class Form1), then use the Timer1 Tick event to monitor the variables and update the GUI if there are any changes.

How to use the Paint event more than once on a form?

Okay, so I am trying to make a program that each time you click (doesn't matter where) a random colored, and sized circle appears where you happened to click. however, the only way I can add a shape is via Paint event. here is the code I have now:
Private Sub Form1_Paint(ByVal Sender As System.Object, ByVal e As System.Windows.Forms.PaintEventArgs) Handles MyBase.Paint
Using Brush1 As New SolidBrush(Color.Orange)
e.Graphics.FillEllipse(Brush1, MousePosition.X, MousePosition.Y, 100, 100)
End Using
End Sub
I need to know a line of code that I can use in a mouse click event, that will re-run this sub. I know how to change the size, and make it random, I just don't know how to run this sub multiple times, more precisely; run this sub once after each mouse click. If someone can help, I would appreciate it!
Just as Plutonix explained, a refresh is handled by calling the Invalidate method.
The thing you need to remember is that whatever is painted on a surface is not persistent, so you need to redraw the whole screen every time. There are, of course, many ways in which this can be optimized for performance purposes, as this process can be extremely CPU intensive; specially, since GDI+ is not hardware accelerated.
So, what you need to do is:
Record every click (x, y position) and store it
Since the radius of each circle is random, determine the radius when the user clicks the form, then store it along with the x, y position of the click
Then, have the Paint event re-draw each stored sequence of clicks (with their respective radii) and re-draw each circle over and over.
Here's an implementation that will do the trick. Just paste this code inside any Form's class to test it:
Private Class Circle
Public ReadOnly Property Center As Point
Public ReadOnly Property Radius As Integer
Public Sub New(center As Point, radius As Integer)
Me.Center = center
Me.Radius = radius
End Sub
End Class
Private circles As New List(Of Circle)
Private radiusRandomizer As New Random()
Private Sub FormLoad(sender As Object, e As EventArgs) Handles MyBase.Load
Me.SetStyle(ControlStyles.AllPaintingInWmPaint, True) ' Not really necessary in this app...
Me.SetStyle(ControlStyles.OptimizedDoubleBuffer, True)
Me.SetStyle(ControlStyles.ResizeRedraw, True)
Me.SetStyle(ControlStyles.UserPaint, True)
End Sub
Private Sub FormMouseClick(sender As Object, e As MouseEventArgs) Handles Me.MouseClick
circles.Add(New Circle(New Point(e.X, e.Y), radiusRandomizer.Next(10, 100)))
Me.Invalidate()
End Sub
Private Sub FormPaint(sender As Object, e As PaintEventArgs) Handles Me.Paint
Dim g As Graphics = e.Graphics
g.Clear(Color.Black)
Using p As New Pen(Color.White)
For Each c In circles
g.DrawEllipse(p, c.Center.X - c.Radius \ 2, c.Center.Y - c.Radius \ 2, c.Radius, c.Radius)
Next
End Using
End Sub
Here's what you'll get after a few clicks on the form

Animate Picturebox in VB

I am new to VB and just can't figure it out how to animate a button using the MouseHover Event..
I want to create a single loop for all the buttons(picturebox) in my project that will increase the button's size when the user rests the mouse on it.
Maybe something like:
For Each Form As Form In Application.OpenForms
For Each Control As Control In Form.Controls
Tks. Any help is appreciated.
Use Inherits to create a new button (or PictureBox) class for you purpose. Here is the code.
Public Class cuteButton
Inherits System.Windows.Forms.Button
Protected Overrides Sub OnMouseHover(e As EventArgs)
'
'Wite code here to change button size or whatever.
'
MyBase.OnMouseHover(e)
End Sub
End Class
A very simple way is to use a common MouseHover event to grow your buttons (which I guess is really a Picturebox with an image in it):
Private Sub CustomButton_Grow(sender As Object, e As System.EventArgs) Handles Picturebox1.MouseHover, Picturebox2.MouseHover
'Set a maximum height to grow the buttons to.
'This can also be set for width depending on your needs!
Dim maxHeight as single = 50
If sender.Height < maxHeight then
sender.Size = New Size(sender.Width+1,sender.Height+1)
End if
End Sub
Then you can reset all buttons in a snap using the MouseLeave event. If you want that part animated as well then you can to use a global shrink routine that constantly shrink all buttons but the one in MouseHover. Good luck!
This Will Work even if you have 10,000 button or picture box ....
I am Assuming that you only have 1 form and many Buttons ,,, you have to be specific on your question
This Code will work fine with Buttons, Picturebox ,text box
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
For Each cntrl As Control In Controls ' Looping for each Button as Control
If TypeOf cntrl Is Button Then
AddHandler cntrl.MouseEnter, AddressOf cntrl_MouseEnter ' Adding the event and handler
AddHandler cntrl.MouseLeave, AddressOf cntrl_MouseLeave ' Adding the event and handler
End If
Next
End Sub
'' Assuming you wanna eNlarge everytime the mouse Hover or Enter
Private Sub cntrl_MouseEnter(sender As Object, e As EventArgs)
CType(sender, Button).Size = New Point(CType(sender, Button).Size.Width + 50, CType(sender, Button).Size.Height + 50)
End Sub
'' Here it goes back normal size
Private Sub cntrl_MouseLeave(sender As Object, e As EventArgs)
CType(sender, Button).Size = New Point(CType(sender, Button).Size.Width - 50, CType(sender, Button).Size.Height - 50)
End Sub

e.target in VB.net

When using flash, I was able to get to the focus of an event by accessing the event's "target" attribute.
so if I remember, it was something similar to.
button1.addEventListener(mouse_click, doSomething);
doSomething(e: Event){
e.target.size = 50000;
}
And I'm looking for the equivalent in VB.
If you can give me it's common name across all languages, I'd be doubly grateful. I don't quite know what to search for aside from "event.target VB.net equivalent, and that's not returning anything.
Thanks in advance.
edit: for those new to flash. By focus, I mean the physical object that was clicked on. So the example given would be accessing the clicked button's size.
In VB you can wire up event handlers declaratively using the WithEvents keyword or imperatively using AddHandler.
Private WithEvents myButton
' OR
Public Sub New
Dim newButton = New Button()
AddHandler newButton.Click, AddressOf MyClickHandler
End New
'To consume it you declare a method as follows:
' The Handles clause is used when declaring WithEvents
Private Sub MyClickHandler(sender As Object, e As EventArgs) Handles myButton.Click
' The sender has a handle on the object that raised the event (aka the button)
Dim btn = DirectCast(sender, Button)
btn.Size = New Size(500, 500)
End Sub
Got it!
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.button.onclick.aspx#Y0
Sub GreetingBtn_Click(ByVal sender As Object, ByVal e As EventArgs)
'When the button is clicked,
'change the button text, and disable it.
Dim clickedButton As Button = sender
clickedButton.Text = "...button clicked..."
clickedButton.Enabled = False
End Sub
The first parameter (sender by default) references the focused object. You can access it as you would any other normal variable, but it's information won't appear in the auto complete list unless you set it "As" that specific data type.
So I ended up with this
Private Sub nw_btn_Click(ByVal sender As System.Windows.Forms.Button, ByVal e AsSystem.EventArgs) Handles nw_btn.Click
sender.Hide()
End Sub

How can I place/drop an image evertime you click the mouse button using vb.net?

I looked at "How do I place an image with a mouse-click in Javascript?" but it had a small snippet of Java; immensely larger than my knowledge of Java. And that is the closest I've come to finding an answer in the past week.
Here's what I would like to do (don't know if its even possible):
I have a panel and a toolstrip with 3 buttons. Each button represents a different image. I want to click on a button (once) and then move into the panel and everytime I click the mouse button it drops the image where ever I clicked. This only ends when either I click back on the same button or one of the other buttons. I do not want to drag an image into the panel each time. In other words the button stays depressed and the event/action stays active.
Any help would be greatly appreciated.
Here is an example application. It's just a form with a ToolStrip on it, along with a couple of buttons with an image added to each button. The key property for each button is CheckOnClick=True, which will keep the button pressed down.
There isn't a radio button like feature for ToolStrips, so you have to "uncheck" the other ToolStripButtons yourself, which I have handled in the ItemClicked event.
Public Class Form1
Private _ActiveImage As Image = Nothing
Private Class ImagePoint
Public Location As Point
Public Image As Image
Public Sub New(ByVal image As Image, ByVal location As Point)
Me.Image = image
Me.Location = location
End Sub
End Class
Private _Images As New List(Of ImagePoint)
Public Sub New()
InitializeComponent()
Me.DoubleBuffered = True
End Sub
Private Sub Form1_Paint(ByVal sender As Object, ByVal e As PaintEventArgs) Handles MyBase.Paint
For Each imageItem As ImagePoint In _Images
e.Graphics.DrawImage(imageItem.Image, imageItem.Location)
Next
End Sub
Private Sub ToolStrip1_ItemClicked(ByVal sender As Object, ByVal e As ToolStripItemClickedEventArgs) Handles ToolStrip1.ItemClicked
For Each toolButton As ToolStripButton In ToolStrip1.Items.OfType(Of ToolStripButton)()
If toolButton.CheckOnClick Then
If e.ClickedItem.Equals(toolButton) Then
_ActiveImage = e.ClickedItem.Image
Else
toolButton.Checked = False
End If
End If
Next
End Sub
Private Sub Form1_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs) Handles MyBase.MouseDown
If _ActiveImage IsNot Nothing AndAlso e.Button = MouseButtons.Left Then
_Images.Add(New ImagePoint(_ActiveImage, e.Location))
Me.Invalidate()
End If
End Sub
End Class
This example just uses a simple class to hold which image was placed at what location and the paint event just loops through the list and paints the image.
If deleting images is in your future, then you would have to call e.Graphics.Clear(Color.White) before painting any images.
For the button UI, check out the alternate style for radio buttons/check boxes. They have a "toggle button" mode which sounds like exactly what you need.
You could go through the motions of detecting mouse down events on the panel, getting the coordinates, creating an image control, and placing a copy of the image in it, but there's a better approach.
Fill the panel with a single image control (fill so that it handles resizes, the image control should always be the same size as the panel). Create a new Bitmap the same size as the image control and associate it with it (set the Image property). Obtain a Graphics object for the Bitmap (Graphics.FromImage() I think). Clear() it with the background color (Color.White?).
Preload your three images on startup and write the code to toggle between them, selecting the "active one" every time a different button is selected. On the mouse down event, you can get the coordinates of the click easily. Use myGraphics.DrawImage(...) to draw the active image at that location onto the Bitmap. You can then save the Bitmap to a file or do whatever you want with it. All of these concepts have lots of examples, Google them.
If you want to interact with the images after you "drop" them (like move them around again or something), then you will need to maintain a data structure that tracks what and where you've dropped. A simple class that has a Point and Image reference will be sufficient. Each drop should add an entry to a List(Of ...) these objects. You'll probably then need to write code such as "which image is under the current mouse location?". This can be accomplished by iterating through the list and doing point/rectangle intersection testing.
Private Sub ToolStripSound_Click(sender As Object, e As EventArgs) Handles ToolStripSound.Click
If ToolStripSound.Checked = False Then
ToolStripSound.Checked = True
Else
ToolStripSound.Checked = False
End If
End Sub
Private Sub ToolStripSound_CheckedChanged(sender As Object, e As EventArgs) Handles ToolStripSound.CheckedChanged
' ToolStripSound.Checked = True
If ToolStripSound.Checked = True Then
Me.ToolStripSound.Image = Global.Traffic_Lights.My.Resources.Resources.Oxygen_Icons_org_Oxygen_Status_audio_volume_high
Else
Me.ToolStripSound.Image = Global.Traffic_Lights.My.Resources.Resources.Oxygen_Icons_org_Oxygen_Status_audio_volume_muted
End If
End Sub