Im trying to make a ball bouncing around on the screen, which is mostly working apart from an annoying flicker everytime it moves.
Ive been searching for a while, and most sites tell you to enable double buffering, which slightly helps but it still flickers badly.
Does anyone have any advice on how to fix this?
Thanks :)
My Code:
Imports System.Drawing
Public Class Form1
Public gr As Graphics
Public XSpeed As Integer = 2
Public YSpeed As Integer = 2
Public ParticleCoord(1) As Integer
Public Blackbrush As New SolidBrush(Color.Black)
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
gr = Me.CreateGraphics()
YSpeed = CInt(Math.Ceiling(Rnd() * 10))
XSpeed = CInt(Math.Ceiling(Rnd() * 10))
ParticleCoord = {50, 50}
Timer.Enabled = True
End Sub
Private Sub ParticleMove(ByRef XSpeed, ByRef YSpeed)
If (ParticleCoord(0) < (12 + 1189) And ParticleCoord(0) > 12) And (ParticleCoord(1) < (12 + 449) And ParticleCoord(1) > 12) Then
ParticleCoord = {ParticleCoord(0) + XSpeed, ParticleCoord(1) + YSpeed}
gr.Clear(Color.White)
gr.FillEllipse(Blackbrush, (ParticleCoord(0) + XSpeed), (ParticleCoord(1) + YSpeed), 50, 50)
ElseIf (ParticleCoord(0) < (12 + 1189) And ParticleCoord(0) > 12) Then
YSpeed = -YSpeed
ParticleCoord = {ParticleCoord(0) + XSpeed, ParticleCoord(1) + YSpeed}
gr.Clear(Color.White)
gr.FillEllipse(Blackbrush, (ParticleCoord(0) + XSpeed), (ParticleCoord(1) + YSpeed), 50, 50)
ElseIf (ParticleCoord(1) < (12 + 449) And ParticleCoord(1) > 12) Then
XSpeed = -XSpeed
ParticleCoord = {ParticleCoord(0) + XSpeed, ParticleCoord(1) + YSpeed}
gr.Clear(Color.White)
gr.FillEllipse(Blackbrush, (ParticleCoord(0) + XSpeed), (ParticleCoord(1) + YSpeed), 50, 50)
Else
YSpeed = -YSpeed
XSpeed = -XSpeed
ParticleCoord = {ParticleCoord(0) + XSpeed, ParticleCoord(1) + YSpeed}
End If
End Sub
Private Sub Timer_Tick(sender As Object, e As EventArgs) Handles Timer.Tick
ParticleMove(XSpeed, YSpeed)
End Sub
End Class
As stated out in the comments, you should always use the Graphics
object from the Paint
-event. To invoke a redraw, call Invalidate()
on your control. Do not use Refresh()
(not that bad) or Application.DoEvents()
(very bad) to perform redraws.
Bonus: Pro-Tip for a very smooth drawing experience
Get rid of OnPaintBackground()
, see my other answer here.
With this, you'll get good rendering performance (for GDI+), I use this a lot. You can see it over here in a fun project I made to analyse WinForms control hierarchies: WinFormsCT on GitHub.