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)