| DirectX SDK |
This section pertains only to application development in Visual Basic. See DirectDraw C/C++ Tutorials.
There are several steps involved before the simple sprite animation is displayed on the screen. Both the sprite surface and the background image are composed to the back buffer and then the back buffer is blitted to the primary surface. The animation is achieved by constantly moving the location of the destination rectangle when blitting the sprite surface to the back buffer. In Tutorial 2, the DoFrame procedure updates the location of the sprite surface and repaints the background image while the application is running. Additionally, there is some code to display the frames per second (fps) of the animation.
First a simple timer loop is implemented to calculate the angle of where to place the sprite:
t2 = Timer
If t1 <> 0 Then
a = a + (t2 - t1) * 100
If a > 360 Then a = a - 360
End If
t1 = t2
Next we make sure that we still retain control of the created surfaces. Surfaces can be lost and will need to be restored if another application takes control of the display adapter. The Tutorial 2 sample contains a simple function, ExModeActive, that tests the cooperative level of the DirectDraw object to determine whether or not we will have to restore the surfaces. This is shown in the following code:
Dim bRestore As Boolean
bRestore = False
Do Until ExModeActive
DoEvents
bRestore = True
Loop
DoEvents
If bRestore Then
bRestore = False
objDD.RestoreAllSurfaces
End If
Next, a small bit of code is implemented to display the frames per second of the sprite animation. This can be useful to help streamline your application and to find potential bottlenecks in your application.
'calculate FPS
i = i + 1
If i = 30 Then
tNow = Timer
If tNow <> tLast Then
fps = 30 / (Timer - tLast)
tLast = Timer
i = 0
Me.Caption = "DD Transparency Frames per Second =" + Format$(fps, "#.0")
End If
End If
Next we calculate the x and y coordinates of where to place the sprite:
x = Cos((a / 360) * 2 * 3.141) * Picture1.Width / 8 y = Sin((a / 360) * 2 * 3.141) * Picture1.Height / 8 x = x + Picture1.Width / 2 y = y + Picture1.Height / 2
The previous position of the sprite is held in a RECT type so we can repaint only the affected portion of the background surface. This increases the performance of the application because we do not have to constantly blit the entire surface. Then we determine the new position of the sprite and blit the sprite surface to the back buffer.
'Clean up background from last frame
'by only repainting the background where it needs to
Dim rClean As RECT
If lastX <> 0 Then
rClean.Left = lastX
rClean.Top = lastY
rClean.Right = lastX + ddsdSprite.lWidth
rClean.Bottom = lastY + ddsdSprite.lHeight
Call objDDBackBuffer.BltFast(lastX, lastY, objDDLakeSurf, rClean, DDBLTFAST_WAIT)
End If
lastX = x
lastY = y
'Blit the sprite to the backbuffer
'using the color key on the source
'wait for the blt to finish before moving one
Dim rtemp As RECT
rtemp.Left = x
rtemp.Top = y
rtemp.Right = x + ddsdSprite.lWidth
rtemp.Bottom = y + ddsdSprite.lHeight
objDDBackBuffer.Blt rtemp, objDDSpriteSurf, rSprite, DDBLT_KEYSRC Or DDBLT_WAIT
Finally, we obtain the rectangle coordinates of the picture box control by calling the DirectX7.GetWindowRect method and call the DirectDrawSurface7.Blt method to blit the back buffer to the primary surface.
Call objDX.GetWindowRect(Picture1.hWnd, rPrim) Call objDDScreen.Blt(rPrim, objDDBackBuffer, rBackBuffer, DDBLT_WAIT)