Animating Card Backs
In the Fun ’n Games program, clicking the Card Backs button draws 13 card backs plus the X and O cards. The program then turns on the timer and animates cards in the background. Try to find the animated card in Figure 7-12.
Figure 7-12. Fun with cards.
Only 4 of the 13 card backs in CARDS32.DLL are animated, and another changes color. To keep this animation working smoothly, you must manage variables for the x position, the y position, the card back, and the animation state. It’s not a simple loop.
Let’s look at the normal loop that draws the cards initially:
Private Sub cmdBack_Click()
Dim ordScale As Integer
ordScale = ScaleMode: ScaleMode = vbPixels
SetTimer eatCardBacks
Cls
Dim x As Integer, y As Integer, ecbBack As ECardBack
ecbBack = ecbCrossHatch ‘ First card back
‘ Draw cards in 4 by 4 grid
For x = 0 To 3
For y = 0 To 3
cdtDraw Me.hDC, (dxCard * 0.1) + (x * dxCard * 1.1), _
(dyCard * 0.1) + (y * dyCard * 1.1), _
ecbBack, ectBacks, QBColor(Random(0, 15))
ecbBack = ecbBack + 1
Next
Next
ScaleMode = ordScale
End Sub
The timer loop does essentially the same thing, although its use of static variables makes it look different. Fun ’n Games handles other animation tasks too; AnimateBacks is one of several subs called by the Timer event procedure:
Sub AnimateBacks()
Static x As Integer, y As Integer
Static ecbBack As ECardBack, iState As Integer
‘ Save scale mode and change to pixels
Dim ordScale As Integer
ordScale = ScaleMode: ScaleMode = vbPixels
‘ Adjust variables
If ecbBack < ecbCrossHatch Or ecbBack > ecbO Then
ecbBack = ecbCrossHatch
x = 0: y = 0
End If
If x = 4 Then x = 0
If y = 4 Then y = 0: x = x + 1
Select Case ecbBack
Case ecbCrossHatch
‘ Change color of crosshatch
cdtDraw Me.hDC, (dxCard * 0.1) + (x * dxCard * 1.1), _
(dyCard * 0.1) + (y * dyCard * 1.1), _
ecbBack, ectBacks, QBColor(Random(0, 15))
Case Else ‘ecbRobot, ecbCastle, ecbBeach, ecbCardHand
‘ Step through animation states
If cdtAnimate(Me.hDC, ecbBack, _
(dxCard * 0.1) + (x * dxCard * 1.1), _
(dyCard * 0.1) + (y * dyCard * 1.1), iState) Then
iState = iState + 1
Exit Sub ‘ Don’t move to next card until final state
End If
iState = 0
‘ Case Else
‘ Ignore other cards
End Select
‘ Move to next card
ecbBack = ecbBack + 1
y = y + 1
‘ Restore
ScaleMode = ordScale
End Sub
Timer loops can be used for a lot more than animation. Think about how to apply them to all your background tasks. Consider doing calculations and file processing while you’re handling user input, for instance. In fact, once you become accustomed to thinking in terms of timer loops, you can end up performing tasks in the background that used to be carried out in the foreground.