Introduction
Do you have a lottery habit?, If so, that is good, for me. This is a take off of the "Georgia State Lottery Mega Millions". It has tumbling animation for the five white balls
and the same for the mega ball. It's free and won't break your wallet. It displays, in a DataGridView
, all the winning numbers from the beginning of the year to
date. I suppose you could use this to query the most called numbers for a slight advantage into the game.
Background
I've seen all sorts of lottery programs but none with tumbling animation, at least I haven't so far. The only one I did see was a VB 5 example and I did use and upgrade
the class file that was used for the VB5 version. I do not know who the author is as the example was printed and is three days older than dirt, but I still have it.
The Animation
The animation takes place in two different events. The tumbleTimer_Tick
event and the pnlTumble_Paint
event. I originally was going
to use a PictureBox
control for the animation but was schooled in why not to use it and was pointed in the direction of the Panel
control.
The PictureBox
is for showing images. That is it. The PictureBox
has extra baggage that we do not need. The code for the tumbleTimer_Tick
and the pnlTumble_Paint
events are very straightforward and we do follow the "Windows Event Driven Rules".
Private Sub tumbleTimer_Tick(sender As Object, _
e As System.EventArgs) Handles tumbleTimer.Tick
_showGraphic = True
pnlTumble.Invalidate()
End Sub
We simply set a Boolean
to True
and Invalidate
the Panel
that we are using for the animation. The Paint
Event is where
the meat of the animation takes place. Inside the Panel
, we draw a rectangle that holds the circle and the centered text. We do this 56 times.
We clear the Panel
by painting everything black, dispose of the graphics, and start over again.
Private Sub pnlTumble_Paint(sender As Object, _
e As System.Windows.Forms.PaintEventArgs) Handles pnlTumble.Paint
Dim i As Integer = 0
Dim xPos As Integer
Dim yPos As Integer
Dim rr As New Random
Dim rect As New Rectangle
For i = 1 To 56
xPos = rr.Next(1, 300)
yPos = rr.Next(1, 400)
rect.Height = 50
rect.Width = 50
rect.Location = New Point(xPos, yPos)
e.Graphics.FillEllipse(Brushes.White, rect.X, rect.Y, 50, 50)
Dim f As Font = New Font("Arial", 12, FontStyle.Bold)
Dim StringSize As SizeF = e.Graphics.MeasureString(i.ToString(), f)
e.Graphics.DrawString(i.ToString(), f, Brushes.Black, _
(rect.Left + 25) - (StringSize.Width / 2), _
(rect.Top + 25) - (StringSize.Height / 2))
Next
e.Graphics.Clear(Color.Black)
e.Graphics.Dispose()
End Sub
Clicking for a Ball
When you click to get the first ball, you would think that it is coming from the tumbling animation, but in all actuality, the animation
is just a facade (pronounced "f·säd") for what is actually going on. In the btnNextBall_Click
event, we first get the current count
of selected balls; if all the balls are grabbed, then we start over, then we select the next unique ping-pong ball GrabNext(PPBalls)
, then we do some UI cosmetics.
GrabNext(PPBalls)
is where we get random numbers for our ping-pong balls. The class clsRandom
has just two properties, three subs, and six variables.
The properties are...
The Subs are...
Shuffle(dX As Double)
Zap()
Stir(dX As Double)
The variables are...
Const SIZE
MinInt Integer
MaxInt Integer
BJP(SIZE - 1) Double
RSP Integer
PJP Integer
The Shuffle
sub is called in the Form_Load
event which calls the Zap
sub and the Stir
sub.
The code for the btnNextBall_Click
event and the GrabNext(ByVal Ary())
sub follows...
Private Sub btnNextBall_Click(sender As Object, _
e As System.EventArgs) Handles btnNextBall.Click
If btnNextBall.Text = "Re-Start" Then
btnNextBall.Text = "Next Ball"
tumbleTimer.Start()
End If
Dim i As Integer
i = PPBalls(0)
If i = 5 Then
For i = 0 To 5
PPBalls(i) = 0
Next
Exit Sub
End If
GrabNext(PPBalls)
If PPBalls(0) = 5 Then
btnNextBall.Text = "Re-Start"
tumbleTimer.Stop()
pnlTumble.Hide()
pnlMegaTumbler.Show()
tumbleMegaTimer.Start()
btnNextBall.Location = New Point(593, 546)
btnNextBall.Enabled = False
btnNextBall.Visible = False
btnMegaBall.Location = New Point(594, 547)
btnMegaBall.Enabled = True
btnMegaBall.Visible = True
End If
End Sub
Private Sub GrabNext(ByVal Ary())
Dim i As Integer
Dim j As Integer = 0
Ary(0) = Ary(0) + 1
i = Ary(0)
Do
Ary(i) = r.Randomint
DisplayBall(Ary(i))
If i > 1 Then
For j = 1 To (i - 1)
If Ary(i) = Ary(j) Then
Ary(i) = 0
End If
Next
End If
Loop Until Ary(i)
End Sub
I was going to get off track and write a little about "Windows Event Driven Rules" but after
doing some searching on the subject, I found that this is another article in itself. So I'll stick to the "Windows Event Driven" subs that follow.
The DisplayBall()
sub is a long-dragged-out If
, ElseIf
, End If
statement. We call the Panel.Invalidate()
command,
which in turn calls the Panel.Paint
event. This follows the Windows Event Driven Rules. More on this
subject can be found on Wikipedia or by doing a Google Search which displays quite a few links on the subject.
Private Sub DisplayBall(ByVal ii As Integer)
myBall = Nothing
If ii = 1 Then
myBall = 1
_showGraphic = True
Me.pnl1.Invalidate()
ElseIf ii = 2 Then
myBall = 2
_showGraphic = True
Me.pnl2.Invalidate()
ElseIf ii = 55 Then
myBall = 55
_showGraphic = True
Me.pnl55.Invalidate()
ElseIf ii = 56 Then
myBall = 56
_showGraphic = True
Me.pnl56.Invalidate()
End If
Private Sub pnl1_Paint(sender As Object, e As System.Windows.Forms.PaintEventArgs) _
Handles pnl1.Paint, pnl2.Paint, pnl3.Paint, pnl4.Paint, pnl5.Paint, _
pnl6.Paint, pnl7.Paint, pnl8.Paint, pnl9.Paint, _
pnl10.Paint, pnl11.Paint, pnl12.Paint, pnl13.Paint, _
pnl14.Paint, pnl15.Paint, pnl16.Paint, pnl17.Paint, _
pnl18.Paint, pnl19.Paint, pnl20.Paint, pnl21.Paint, _
pnl22.Paint, pnl23.Paint, pnl24.Paint, pnl25.Paint, _
pnl26.Paint, pnl27.Paint, pnl28.Paint, pnl29.Paint, _
pnl30.Paint, pnl31.Paint, pnl32.Paint, pnl33.Paint, _
pnl34.Paint, pnl35.Paint, pnl36.Paint, pnl37.Paint, _
pnl38.Paint, pnl39.Paint, pnl40.Paint, pnl41.Paint, _
pnl42.Paint, pnl43.Paint, pnl44.Paint, pnl45.Paint, _
pnl46.Paint, pnl47.Paint, pnl48.Paint, pnl49.Paint, _
pnl50.Paint, pnl51.Paint, pnl52.Paint, pnl53.Paint, _
pnl54.Paint, pnl55.Paint, pnl56.Paint
If _showGraphic Then
Dim rect As New Rectangle
rect.Height = 40
rect.Width = 40
rect.Location = New Point(0, 0)
e.Graphics.FillEllipse(Brushes.White, rect.X, rect.Y, 40, 40)
Dim f As Font = New Font("Arial", 10, FontStyle.Bold)
Dim StringSize As SizeF = e.Graphics.MeasureString(myBall.ToString(), f)
e.Graphics.DrawString(myBall.ToString(), f, Brushes.Black, _
(rect.Left + 20) - (StringSize.Width / 2), _
(rect.Top + 20) - (StringSize.Height / 2))
e.Graphics.Dispose()
End If
End Sub
The MegaBall subs are pretty much the same as the white ball subs displayed above, except on a smaller scale as we are calling only one ball.
If there is anything in this article that sounds somewhat redundant, it probably is, so please do not leave a message stating this as I already know.