My counter adds 1 but doesn't update properly - vb.net

This is a slot machine program. I am trying to detect how many times the user clicks a button (spins). But I can't figure out why my counter only adding 1 to my clickLabel? I'm sure it's a simple fix but I'm drawing a blank.
Public Class MainForm
Private Sub clickHereButton_Click(sender As Object, e As EventArgs) Handles clickHereButton.Click
' simulates a slot machine
Dim randGen As New Random
Dim leftIndex As Integer
Dim centerIndex As Integer
Dim rightIndex As Integer
Dim counter As Integer = 1
clickHereButton.Enabled = False
For spins As Integer = 1 To 10
leftIndex = randGen.Next(0, 6)
leftPictureBox.Image = ImageList1.Images.Item(leftIndex)
Me.Refresh()
System.Threading.Thread.Sleep(50)
centerIndex = randGen.Next(0, 6)
centerPictureBox.Image = ImageList1.Images.Item(centerIndex)
Me.Refresh()
System.Threading.Thread.Sleep(50)
rightIndex = randGen.Next(0, 6)
rightPictureBox.Image = ImageList1.Images.Item(rightIndex)
Me.Refresh()
System.Threading.Thread.Sleep(50)
Next spins
If leftIndex = centerIndex AndAlso
leftIndex = rightIndex Then
MessageBox.Show("Congratulations!", "Winner", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
counter += 1
clickLabel.Text = counter.ToString()
clickHereButton.Enabled = True
clickHereButton.Focus()
End Sub
Private Sub exitButton_Click(sender As Object, e As EventArgs) Handles exitButton.Click
Me.Close()
End Sub
End Class

What's happening is you're always setting the counter to 1 everytime you click the button because it is inside the clickHereButton_Click. So even though you are incrementing it, at the beginning of your sub you are still setting it to 1.
Dim counter As Integer = 1
Private Sub clickHereButton_Click(sender As Object, e As EventArgs) Handles clickHereButton.Click
...
End Sub

Related

How can I make a timer slower and slower until it stops?

Can someone tell me what's wrong or what I need to add to make it run the way that I want? I need to make it slower, then slower again, then make it stop.
Heres what I have tried:
Dim A As Integer
If Timer.Interval = 1 Then
A = Timer.Interval + 1000
If Timer.Interval = 1000 Then
Timer.Enabled = False
End If
End If
I want to stop the timer after a specific time but I have button 1 and 2 its random and stop, if I push the button random it will select any on given list then if I push stop the selection of random is going stop delay like spinning wheel, the missing on my program is the delay selection after a seconds its like selecting random then it will slowly selecting then it will stop.
Here's the btnRandom.Click event handler:
Private Sub btnRandom_Click(sender As Object, e As EventArgs) Handles btnRandom.Click
If lstList1.Items.Count <= 1 Then
MessageBox.Show("Name must more than 1 to run the randomizer.", "Error Loading", MessageBoxButtons.OK, MessageBoxIcon.Warning)
Else
txtName.Enabled = False
btnRandom.Enabled = False
btnAdd.Enabled = False
btnRemove.Enabled = False
btnStop.Enabled = True
btnAdd.ForeColor = Color.FromArgb(64, 64, 64)
btnRemove.ForeColor = Color.FromArgb(64, 64, 64)
btnRandom.ForeColor = Color.FromArgb(64, 64, 64)
If btnRandom.Enabled = False Then
Timer2.Start()
lstList1.ClearSelected()
End If
End If
End Sub
And the Timer.Tick handler:
Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
If btnRandom.Enabled = True Then
Timer2.Enabled = False
End If
If btnRandom.Enabled = False Then
txtNameLabel.Text = lstList1.Items(Rnd() * (lstList1.Items.Count - 1))
lstList1.SelectedItem = txtNameLabel.Text
txtNameLabel.Text = lstList1.SelectedItem
End If
End Sub
If you want something to decelerate then you need to multiply the speed by a constant less than one, which in this case is equivalent to increasing the display time interval by a constant greater than one.
So, you can start something at one speed, and then add a deceleration by changing the amount the interval is changed by.
Something like this:
Public Class Form1
Dim sw As Stopwatch
Dim tim As Timer
Dim intervalMultiplier As Double = 1.0
Dim itemsToDisplay As List(Of String)
Dim itemIndex As Integer = 0
Private Sub tim_Tick(sender As Object, e As EventArgs)
' When intervalMultiplier > 1.0 the time between ticks will increase.
tim.Interval = CInt(tim.Interval * intervalMultiplier)
Label1.Text = itemsToDisplay(itemIndex)
If tim.Interval >= 1000 Then
tim.Stop()
End If
itemIndex = (itemIndex + 1) Mod itemsToDisplay.Count
End Sub
Private Sub StartTimer()
If tim Is Nothing Then
tim = New Timer()
AddHandler tim.Tick, AddressOf tim_Tick
End If
If sw Is Nothing Then
sw = Stopwatch.StartNew()
Else
sw.Restart()
End If
intervalMultiplier = 1.0
tim.Interval = 100
tim.Start()
End Sub
Private Sub bnStop_Click(sender As Object, e As EventArgs) Handles bnStop.Click
intervalMultiplier = 1.25
End Sub
Private Sub btnRandom_Click(sender As Object, e As EventArgs) Handles btnRandom.Click
' Your code to disable buttons etc. goes here.
StartTimer()
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
' Set up some data for this example.
itemsToDisplay = New List(Of String) From {"Capacitor", "Diode", "Inductor", "Resistor", "Transistor"}
End Sub
End Class

Forwarding the min and max values of BackgroundWorker to use the function correctly

I have been struggling for several days to find a solution on how to properly incorporate BackgroundWorker into my Feature and with that I have the ability to properly display the process development, process stop, report.
this is my code
Private Sub Frm_ImportLeumobileGK_FormClosing(sender As Object, e As Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
Me.BackgroundWorker1.CancelAsync()
Me.Timer1.Enabled = False
Me.DialogResult = DialogResult.Cancel
e.Cancel = True
End Sub
Private Sub Btn_OK_Click(sender As Object, e As EventArgs) Handles btn_OK.Click
ListView1.Items.Clear()
resetCounter()
BackgroundWorker1.RunWorkerAsync()
End Sub
Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim worker As BackgroundWorker = TryCast(sender, BackgroundWorker)
TestPut_All_CDRs_To_FakturaPos(worker, e,
MasterMandantConnectionString:=MasterMandantConnectionString,
StartDate:=dtp_Start.Value,
EndDate:=dtp_End.Value,
min_Nr:=tb_Min_Nr.Value,
max_Nr:=tb_Max_Nr.Value)
End Sub
Sub TestPut_All_CDRs_To_FakturaPos(worker As BackgroundWorker, e As DoWorkEventArgs, MasterMandantConnectionString As String, StartDate As Date, EndDate As Date, min_Nr As Integer, max_Nr As Integer)
Dim n As Integer = 0
Dim MobCdrs As List(Of String)
ProgressBar1.Maximum = (max_Nr - min_Nr)
For Mob_Nr = min_Nr To max_Nr
n += 1
If worker.CancellationPending Then
e.Cancel = True
Else
MobCdrs = TestPut_Mob_CDRs_To_FakturaPos(MasterMandantConnectionString:=MasterMandantConnectionString,
StartDate:=StartDate,
EndDate:=EndDate,
Mob_Nr:=Mob_Nr)
For Each currentError In MobCdrs
If (currentError <> "") Then
ListView1.Items.Add(currentError)
End If
Next
If n > ProgressBar1.Maximum Then
n = ProgressBar1.Maximum
End If
ProgressBar1.Value = n
End If
Next
ListView1.Items.Insert(0, getImportInfo(), 0)
labelInfo.Text = "Test successfully completed."
End Sub
Private Sub BackgroundWorker1_ProgressChanged(sender As Object, e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
ProgressBar1.Value = e.ProgressPercentage
End Sub
Private Sub Frm_FormClosing(sender As Object, e As Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
If BackgroundWorker1 IsNot Nothing Then
Me.BackgroundWorker1.CancelAsync()
Me.Close()
End If
End Sub
Using Documentation, I tried to apply BackgroundWorker to my "TestPut_All_CDRs_To_FakturaPos" function, unfortunately failed because I get on ProgressBar1.Maximum error = ***"System.InvalidOperationException: "Invalid cross threading operation: The ProgressBar1 control was accessed from a thread other than the thread it was created for."***Please suggest, where am I making an exception?
What you need to do is separate the user interface parts (like ListViews, MessageBoxes, etc.) from the backgroundworker.
The way to get the data into the BGW is to pass an object into its .Argument.
To get data out of it while it is running, use the ReportProgress event and pass whatever you want in the .UserState object.
To get data from it when it has finished, use the .Result property.
We won't be using any result in this case, but I will set it up as a Boolean in case you want to modify it. So, let's create classes to get the data in and out...
Private Class BgwArgs
Property StartDate As DateTime
Property EndDate As DateTime
Property MinNr As Integer
Property MaxNr As Integer
Property ConnStr As String
End Class
Private Class ProgressReportData
Property ErrorMessages As List(Of String)
End Class
The initial setup for the BGW is like this:
Private Sub Btn_OK_Click(sender As Object, e As EventArgs) Handles Btn_OK.Click
ListView1.Items.Clear()
ResetCounter()
Dim args As New BgwArgs With {.StartDate = dtp_Start.Value,
.EndDate = dtp_End.Value,
.MinNr = CInt(tb_Min_Nr.Value),
.MaxNr = CInt(tb_Max_Nr.Value),
.ConnStr = "your connection string"}
ProgressBar1.Minimum = 0
ProgressBar1.Maximum = 100
BackgroundWorker1.WorkerReportsProgress = True
BackgroundWorker1.WorkerSupportsCancellation = True
BackgroundWorker1.RunWorkerAsync(args)
End Sub
and then all the parts:
Private Sub BackgroundWorker1_DoWork(sender As Object, e As DoWorkEventArgs) Handles BackgroundWorker1.DoWork
Dim worker As BackgroundWorker = TryCast(sender, BackgroundWorker)
e.Result = TestPut_All_CDRs_To_FakturaPos(worker, e)
End Sub
Private Function TestPut_All_CDRs_To_FakturaPos(worker As BackgroundWorker, e As DoWorkEventArgs) As Boolean
Dim importedInfo As New List(Of String)
Dim args = CType(e.Argument, BgwArgs)
Dim masterMandantConnectionString = args.ConnStr
Dim startDate = args.StartDate
Dim endDate = args.EndDate
Dim min_Nr = args.MinNr
Dim max_Nr = args.MaxNr
Dim n As Integer = 0
Dim totalMobs = max_Nr - min_Nr + 1
For mob_Nr = min_Nr To max_Nr
n += 1
If worker.CancellationPending Then
e.Cancel = True
Else
Dim mobCdrs = TestPut_Mob_CDRs_To_FakturaPos(MasterMandantConnectionString:=masterMandantConnectionString,
StartDate:=startDate,
EndDate:=endDate,
Mob_Nr:=mob_Nr)
Dim pct = n * 100 \ totalMobs
Dim progReport As New ProgressReportData With {.ErrorMessages = mobCdrs.Where(Function(m) Not String.IsNullOrEmpty(m)).ToList()}
worker.ReportProgress(pct, progReport)
End If
Next
Return True
End Function
Private Sub backgroundWorker1_ProgressChanged(ByVal sender As Object, ByVal e As ProgressChangedEventArgs) Handles BackgroundWorker1.ProgressChanged
Dim progData = CType(e.UserState, ProgressReportData)
ProgressBar1.Value = e.ProgressPercentage
If progData.ErrorMessages IsNot Nothing Then
For Each m In progData.ErrorMessages
ListView1.Items.Add(m)
Next
End If
End Sub
Private Sub backgroundWorker1_RunWorkerCompleted(ByVal sender As Object, ByVal e As RunWorkerCompletedEventArgs) Handles BackgroundWorker1.RunWorkerCompleted
If (e.Error IsNot Nothing) Then
ProgressBar1.ForeColor = Color.Red
MessageBox.Show(e.Error.Message, "Exception", MessageBoxButtons.OK, MessageBoxIcon.Error)
ElseIf e.Cancelled Then
' Next, handle the case where the user cancelled the operation.
' Note that due to a race condition in the DoWork event handler, the Cancelled flag may not have been set, even though CancelAsync was called.
ProgressBar1.ForeColor = Color.HotPink
Else
ProgressBar1.ForeColor = Color.LawnGreen
ListView1.Items.Insert(0, GetImportInfo(), 0)
labelInfo.Text = "Test successfully completed."
' We could use e.Result here if something useful was returned in it.
' Dim flag = CType(e.Result, Boolean)
End If
End Sub
The progress percentage is calculated in the loop, as that's an easy way to get it done.
I couldn't test it, but hopefully there's enough there for you to get working code.
(I use Option Infer On and Option Strict On.)

How can I use collision detection with spawned arrays

Since I have been trying to make a space invaders style game I have been having trouble with collision detection with spawned objects in arrays (and having a bit of trouble with the bullets, they keep stopping and having another generate). I am new at coding and would like some help with these issues, or at least some links to some forums that had the same thread question.
here is my code:
Public Class Form1
'global variables
Dim intAmountOfEnemys As Short = 9
Dim intRowsOfEnemys As Integer = 0 '**
Dim intAmountOfBullets As Integer = 0
Dim picEnemysWave1(intAmountOfEnemys) As PictureBox
Dim lblBullets As New Label
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Welcome_Screen.Hide()
Call EnemyWaves(picEnemysWave1)
End Sub
Sub PlayerMovement(ByVal sender As Object, ByVal e As KeyEventArgs) Handles MyBase.KeyDown
If e.KeyCode = Keys.A Then
If picShip.Right <= 0 Then
picShip.Left = 1567
Else
picShip.Left -= 10
End If
ElseIf e.KeyCode = Keys.D Then
If picShip.Left >= 1567 Then
picShip.Left = -15
Else
picShip.Left += 10
End If
ElseIf e.KeyCode = Keys.Space Then
Do
BulletGeneration(lblBullets)
Loop Until Keys.Space
lblBullets.Left = (picShip.Left + 7)
End If
End Sub
#Region "Enemy waves, Movement, and Properties"
Sub EnemyWaves(ByRef picEnemysWave1() As PictureBox)
'Enemy Generator
Const srtENEMYSPACING_Y As Short = 155
For intCounterForEnemys As Integer = 0 To intAmountOfEnemys
Dim intEnemySpacing As Integer = srtENEMYSPACING_Y * intCounterForEnemys
picEnemysWave1(intCounterForEnemys) = New PictureBox
picEnemysWave1(intCounterForEnemys).Location = New Point(42 + intEnemySpacing, 1)
picEnemysWave1(intCounterForEnemys).Image = My.Resources.enemy
picEnemysWave1(intCounterForEnemys).Width = 124
picEnemysWave1(intCounterForEnemys).Height = 84
picEnemysWave1(intCounterForEnemys).Show()
Me.Controls.Add(picEnemysWave1(intCounterForEnemys))
Next intCounterForEnemys
End Sub``
Private Sub TmrAlien1_Tick(sender As Object, e As EventArgs) Handles TmrAlien1.Tick
For intRandom As Integer = 0 To 9
picEnemysWave1(intRandom).Top += 3
Dim intRandomNum As Integer = Rnd()
If intRandomNum > 0.66 Then
picEnemysWave1(intRandom).Left += 2 'goes left randomly
ElseIf intRandomNum < 0.33 Then
picEnemysWave1(intRandom).Left -= 2 'goes right randomly
End If
If picEnemysWave1(intRandom).Top <= 0 Then
TmrAlien1.Start()
End If
If picEnemysWave1(intRandom).Top >= 952 Then
TmrAlien1.Stop()
End If
Next intRandom
End Sub
#End Region
#Region "Bullet Generation, Movement, and Properties"
Sub BulletGeneration(ByRef lblBullets As Object)
'Generation of Bullets
For intBulletCounter As Integer = 0 To intAmountOfBullets
lblBullets = New Label
lblBullets.location = New Point(760, 785)
lblBullets.image = My.Resources.blast2
lblBullets.width = 32
lblBullets.height = 64
lblBullets.show()
Me.Controls.Add(lblBullets)
Next intBulletCounter
End Sub
Private Sub tmrBullets_Tick(sender As Object, e As EventArgs) Handles tmrBullets.Tick
lblBullets.Top -= 20
End Sub
#End Region
#Region "Collision Detection"
Sub BulletCollision(ByRef lblBullets As Label, ByRef intAmontOfEnemys As Integer)
For Each picEnemy As PictureBox In picEnemysWave1
If lblBullets.Bounds.IntersectsWith(picEnemy.Bounds) Then
picEnemy.Location = New Point(3900, 8700)
Exit For
End If
Next
'what Im trying
End Sub
#End Region

Issue with Progressbar in VB2012

I am trying to add a ProgressBar to my program. The program basically compares two values of time and when the values are equal a MessageBox appears to indicate that time is up. I need the ProgressBar to load based on the time difference of the two values. One of the values in a clock and the other is input by the user (similar to an alarm).
My code:
Imports System.Net.Mime.MediaTypeNames
Public Class Form1
Private hour As Integer = 0
Private minute As Integer = 0
Private second As Integer = 0
Public Sub show_time()
second += 1
If second = 59 Then
second = 0
minute += 1
If minute = 59 Then
minute += 1
hour += 1
End If
End If
Label3PrgressStdPC.Text = hour.ToString.PadLeft(2, "0") & ":"
Label3PrgressStdPC.Text &= minute.ToString.PadLeft(2, "0") & ":"
Label3PrgressStdPC.Text &= second.ToString.PadLeft(2, "0")
Label3PrgressStdPC.Refresh()
End Sub
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
show_time()
If TextBox1.SelectedText = TextBox1.Text Then Exit Sub
If TextBox1.Text = Label3PrgressStdPC.Text Then
Timer1.Stop()
MsgBox("time is up")
End If
End Sub
Private Sub Bn_start_St01_Click(sender As Object, e As EventArgs) Handles Bn_start_St01.Click
Timer1.Start()
Timer1.Enabled = True
Timer2.Start()
Timer2.Enabled = True
End Sub
**Private Sub ProgressBar1_Click(sender As Object, e As EventArgs) Handles ProgressBar1.Click
ProgressBar1.Maximum = , the max progrssbr will be determine by user input
ProgressBar1.Minimum = 0**
End Sub
**Private Sub Timer2_Tick(sender As Object, e As EventArgs) Handles Timer2.Tick
progresbar1.value = ,Not so sure how to write the logic here**
End Sub
End Class
Can anyone help me out i am really getting frustrated.....thanks
How about something like this...
Private Ticker As Timer = New Timer 'Create a timer
Private Start As DateTime 'Store when we start
Private Expire As DateTime 'and when we end
'Call this to get things going
Sub Begin(EndHour As Integer, EndMinute As Integer, EndSecond As Integer)
Start = DateTime.Now
'If input is a time today ...
Expire = DateTime.Now.Date.Add(New TimeSpan(EndHour, EndMinute, EndSecond))
'or just a number of hours/mins/secs from now...
Expire = DateTime.Now.Add(New TimeSpan(EndHour, EndMinute, EndSecond))
'When the timer fires, call Tick()
AddHandler Ticker.Elapsed, Sub() Tick()
Ticker.Enabled = True
Ticker.Interval = 1000
Ticker.Start
End Sub
Private Sub Tick()
If DateTime.Now < Expire Then
'Not Finished
Dim Elapsed = DateTime.Now.Subtract(Start)
Dim TotalMillis = Expire.Subtract(Start).TotalMilliseconds
Dim ProgressDouble = Elapsed.TotalMilliseconds / TotalMillis
'Me.Invoke is used here as the timer Tick() occurs on a different thread to the
'one used to create the UI. This passes a message to the UI telling it to
'update the progress bar.
Me.Invoke(Sub()
ProgressBar1.Value = CInt(ProgressDouble * ProgressBar1.Maximum)
Label3PrgressStdPC.Text = Elapsed.ToString
End Sub)
Else
'Done
MessageBox.Show("Done")
Ticker.Stop
End If
End Sub
See VB.NET Delegates and Invoke - can somebody explain these to me? for more information on Invoking.

Visual Basic: Make 1 button do 2 operations

So I need a button to complete two operations but in two steps. Here is the first buttons code:
First button (button6)
Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
p = Process.GetProcessesByName("SbieSvc")
If p.Count > 0 Then
Environment.Exit(0)
Else
End If
Dim antiProcess() As String = {"SbieSvc", "Sandboxiecrypto", "sbiectrl"}
For intI As Integer = 0 To antiProcess.GetUpperBound(0)
For Each x As Process In Process.GetProcessesByName(antiProcess(intI))
x.Kill()
Next
Next
''Sets the Channel''
If TextBox6.Text = "" Then
MsgBox("Please enter a Channelname!", MsgBoxStyle.Information, ("Error"))
GoTo Bottom
End If
Me.Data = Me.TextBox6.Text
Me.Method_1(String.Format("Channel set ({0})", Data))
If (Me.thread0 Is Nothing) Then
Me.thread0 = New Thread(New ThreadStart(AddressOf Method2)) With
{
.IsBackground = True
}
Me.thread0.Start()
End If
''Part Of Grab Urls Method''
Button6.Enabled = False
For i As Integer = 0 To TextBox5.Text Step 1
Dim t1 As New Thread(New ParameterizedThreadStart(Sub() GetUrls(TextBox6.Text)))
t1.Start()
Next
GC.SuppressFinalize(Me)
End Sub
Second button (button1)
Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
''start live viewers''
Button1.Enabled = False
For Each itemss In Urls.Items
Dim t1 As New Threading.Thread(Sub() LivePeepz(itemss))
t1.Start()
Next
End Sub
How would I make this code so that button6 will complete it's normal commands, then once done it begins button1's operation. I thought about doing this;
Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
p = Process.GetProcessesByName("SbieSvc")
If p.Count > 0 Then
Environment.Exit(0)
Else
End If
Dim antiProcess() As String = {"SbieSvc", "Sandboxiecrypto", "sbiectrl"}
For intI As Integer = 0 To antiProcess.GetUpperBound(0)
For Each x As Process In Process.GetProcessesByName(antiProcess(intI))
x.Kill()
Next
Next
''Sets the Channel''
If TextBox6.Text = "" Then
MsgBox("Please enter a Channelname!", MsgBoxStyle.Information, ("Error"))
GoTo Bottom
End If
Me.Data = Me.TextBox6.Text
Me.Method_1(String.Format("Channel set ({0})", Data))
If (Me.thread0 Is Nothing) Then
Me.thread0 = New Thread(New ThreadStart(AddressOf Method2)) With
{
.IsBackground = True
}
Me.thread0.Start()
End If
''Part Of Grab Urls Method''
Button6.Enabled = False
For i As Integer = 0 To TextBox5.Text Step 1
Dim t1 As New Thread(New ParameterizedThreadStart(Sub() GetUrls(TextBox6.Text)))
t1.Start()
Next
GC.SuppressFinalize(Me)
''start live viewers''
Button1.Enabled = False
For Each itemss In Urls.Items
Dim t1 As New Threading.Thread(Sub() LivePeepz(itemss))
t1.Start()
End Sub
But this doesn't work...Any ideas? Thanks. VB2012
Put your code in seperate functions e.g. Function1 would contain the code you intended for first button click. Function2 would have the code intended for second button click.
Then you have one button with an onClick event code that is
Private Sub Button1_Click(byVal sender as Object, byVal e as EventArgs) Handles Button1.Click
Function1()
Function2()
End Sub
Private Sub Button6_Click(sender As Object, e As EventArgs) Handles Button6.Click
FirstOperation()
SecondOperation()
End Sub
Private Sub FirstOperation()
'Button 6 Code
End Sub
Private Sub SecondOperation()
'Button 1 Code
End Sub