I would like to show a gif inside a Picture Box for 2 seconds on a separate thread from the main thread. I am running a timer that moves a Picture Box with an Image on the main thread.
To test I created a Picture Box and added same Image I start the background thread with a button click. The obvious ERROR or Issue is that the supposed Background Thread slows the Main Thread.
Creating and Implementing a Threads seems to offer two options BackgroundWorker and Task.Run.
I looked at this Code Magazine Article which offered way more options than I am grasping: Code Magazine Article
Also looked at this Article could not convert the C# code to VB YES I used a code converter: Stephen Cleary
My code is posted below for the Background Thread No need to post the Timer Tick Code.
Question what am I missing or what am I doing wrong OR is this just not possible?
Private Sub myThreadMethod()
'Await
'Async
Dim myThread As New Thread(AddressOf myThreadMethod)
myThread.IsBackground = True
myThread.Start()
If Me.InvokeRequired = True Then
Me.Invoke(Sub()
'PbT.Location = New Point(128, 132)
PbT.Left -= 1
PbT.Top += 2
End Sub)
'If PbT.Bounds.IntersectsWith(btnBot.Bounds) Then
'TextBox1.Invoke(Sub() TextBox1.Text =
End If
If PbT.Location.Y > 500 Then
PbT.Invoke(Sub() PbT.Location = New Point(350, 230))
Thread.Sleep(9000)
myThread.Abort()
End If
End Sub
Answer to Question was added to by Craig and Answered by James_Duh
Public Class frmStart
Dim running As Boolean = False
Dim stopWatch As Stopwatch = New Stopwatch
Private Sub frmStart_MouseMove(sender As Object, e As MouseEventArgs) Handles Me.MouseMove
Cursor.Clip = New Rectangle(Me.Location, Me.Size)
btnLPad.Left = e.X
btnCPad.Left = e.X + 28
btnRPad.Left = e.X + 56
End Sub
Private Sub tmrMove_Tick(sender As Object, e As EventArgs) Handles tmrMove.Tick
Static direction As New Point(0, 4)
Static endTime As DateTime = DateTime.Now.AddYears(1)
If DateTime.Now > endTime Then
PbT.Visible = False
endTime = DateTime.Now.AddYears(1)
End If
If _buttons.All(Function(x) x.Button.Visible = False) Then
pbOne.Top = 300
PbT.Visible = False
tbAns.Visible = True
stopWatch.Stop()
Dim ts = stopWatch.Elapsed
Dim elapsedTime = $"{ts.Minutes:0} Min {ts.Seconds:00} Sec"
tbAns.Text = elapsedTime
running = False
direction = New Point(0, 4)
tmrMove.Stop()
MsgBox("You Win")
stopWatch.Reset()
'================
tbAns.Visible = False
ResetButtons()
End If
If pbOne.Bounds.IntersectsWith(btnLPad.Bounds) Then
direction = New Point(-2, -3)
End If
If pbOne.Bounds.IntersectsWith(btnRight.Bounds) Then
Static spC As Integer = 1
spC += 1
direction = If(spC Mod 2 = 0, New Point(-3, 2), New Point(-5, 1))
End If
If pbOne.Bounds.IntersectsWith(btnLeft.Bounds) Then
direction = New Point(4, 2)
End If
If pbOne.Bounds.IntersectsWith(btnCPad.Bounds) Then
direction = New Point(direction.X, -4)
End If
If pbOne.Bounds.IntersectsWith(btnRPad.Bounds) Then
Static spA As Integer = 1
spA += 1
direction = If(spA Mod 2 = 0, New Point(1, -5), New Point(-3, -4))
End If
If pbOne.Bounds.IntersectsWith(btnTop.Bounds) Then
Static spE As Integer = 1
spE += 1
direction = If(spE Mod 2 = 0, New Point(-3, 2), New Point(4, 2))
End If
If pbOne.Bounds.IntersectsWith(btnBot.Bounds) Then
tmrMove.Stop()
running = False
pbOne.Top = 200
PbT.Visible = False
MsgBox("Press S to Start")
End If
pbOne.Left += direction.X
pbOne.Top += direction.Y
For Each x In _buttons
If pbOne.Bounds.IntersectsWith(x.Button.Bounds) Then
endTime = DateTime.Now.AddSeconds(2.0)
x.Button.Visible = False
x.Button.Location = New Point(350, -30)
PbT.Location = New Point(x.Location.X + 20, 31)
PbT.Visible = True
direction = New Point(3, 3)
End If
Next
End Sub
Private Sub frmStart_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
If running AndAlso e.KeyCode = Keys.P Then
tmrMove.Stop()
End If
If e.KeyCode = Keys.S Then
If Not running Then
stopWatch.Start()
running = True
End If
tmrMove.Interval = 1
tmrMove.Start()
End If
End Sub
Public Sub frmStart_KeyPress(sender As Object, e As KeyPressEventArgs) Handles Me.KeyPress
'Form Property KeyPreview needs to be set to True
'=================================================
If Asc(e.KeyChar) = 27 Then
Const message As String = "YES" & " Exit Program" + vbCrLf + vbNewLine + "NO" & " Read Directions"
Const caption As String = "Exit OR Return"
Dim result = MessageBox.Show(message, caption, MessageBoxButtons.YesNo, MessageBoxIcon.Question)
If result = DialogResult.Yes Then
Application.Exit()
ElseIf result = DialogResult.No Then
frmInfo.Show()
Close()
End If
End If
End Sub
Private _buttons As (Button As Button, Location As Point)() = Nothing
Private Sub frmStart_Load(sender As Object, e As EventArgs) Handles MyBase.Load
If _buttons Is Nothing Then
_buttons =
{
(btnB1, New Point(29, 32)),
(btnB2, New Point(110, 32)),
(btnB3, New Point(191, 32)),
(btnB4, New Point(272, 32)),
(btnB5, New Point(353, 32)),
(btnB6, New Point(434, 32)),
(btnB7, New Point(515, 32)),
(btnB8, New Point(596, 32)),
(btnB9, New Point(677, 32))
}
End If
ResetButtons()
End Sub
Private Sub ResetButtons()
For Each x In _buttons
x.Button.Visible = True
x.Button.Location = x.Location
Next
End Sub
End Class
This Code above was from Enigmativity and FIXES a number of issues. See his comments about the Stopwatch and playing the gif. As well the game plays 70% Faster with his code
Trying to reproduce this NOT seeing your Timer tick code I wrote my own
Understanding the GAME design of Breakout will help for anyone trying to follow Vectors steps need to show the gif for X amount of Seconds
First you need to Stopwatch integrated into the Timer
Second you need to know when to set the END time in Seconds Logic would require this happens when the BALL IntersectsWith the BRICK
So we write a Function called Fire see code below
NO need to have a gif for each BRICK so now we need to move our one and only gif to the correct BRICK and let it run for X Seconds We also need to make the gif Visible WHY you might ask if Enabled and Visible they run for ever It was easier to just manage Visibility
You also need code inside the Timer Tick method to make the gif Invisible after X Seconds
Excuse my lack of declarative variables
pbOne = the BALL & btnB1 = BRICK & PbT = Picture Box with the gif
Public Function Fire() As Integer
'Set Stopwatch 5 sec in the future
nT = CDbl(DateTime.Now.AddSeconds(5).ToString("ss"))
Return CInt(nT)
End Function
Private Sub tmrMove_Tick(sender As Object, e As EventArgs) Handles tmrMove.Tick
'nS is Rolling Time
nS = CDbl(DateTime.Now.ToString("ss"))
If nS > nT Then
PbT.Visible = False
End If
If pbOne.Bounds.IntersectsWith(btnB1.Bounds) Then
btnB1.BackColor = Color.Red
btnB1.Visible = False
Fire()
Y = btnB1.Location.Y
X = btnB1.Location.X
PbT.Location = New Point(X + 20, Y)
PbT.Visible = True
btnB1.Location = New Point(350, -30)
rndNUM = 8
End If