06 07


Delphi Graphics and Game Programming Exposed! with DirectX For versions 5.0-7.0:Sprite Techniques                       Search Tips   Advanced Search        Title Author Publisher ISBN    Please Select ----------- Artificial Intel Business & Mgmt Components Content Mgmt Certification Databases Enterprise Mgmt Fun/Games Groupware Hardware IBM Redbooks Intranet Dev Middleware Multimedia Networks OS Productivity Apps Programming Langs Security Soft Engineering UI Web Services Webmaster Y2K ----------- New Arrivals









Delphi Graphics and Game Programming Exposed with DirectX 7.0

by John Ayres

Wordware Publishing, Inc.

ISBN: 1556226373   Pub Date: 12/01/99














Search this book:
 



Previous Table of Contents Next We can do this by setting our threshold amount to a specific time interval, measured in milliseconds. Our current interval measurement would then be set to the system time of the last increment of the frame number. In the game loop, we then check to see if the amount of time indicated in the threshold has elapsed since the last increment of the frame number. If so, we increment the frame number and reset the current interval measurement. The following example demonstrates this technique. Listing 6-7: Accurate sprite animation timing type sprite class TSprite = class FXPos, FYPos, // tracks the current position FXVel, FYVel, // tracks the velocity FCurFrame, // tracks the current frame number FFrameNum: Integer; // tracks the number of frames FImages: IDirectDrawSurface4; // a pointer to the sprite images FCurTime, // tracks a timing value FTimeThreshold: LongWord; // holds the animation timing threshold end; procedure TfrmDXAppMain.FormActivate(Sender: TObject); var . . . begin . . . {initialize the sprite object} FSprite := TSprite.Create; FSprite.FXPos := DXWIDTH - 90; FSprite.FYPos := 215; FSprite.FXVel := -1; FSprite.FYVel := 0; FSprite.FCurFrame := 0; FSprite.FFrameNum := 5; FSprite.FImages := FImages; {retrieve the current system time to initialize the timing algorithm} FSprite.FCurTime := timeGetTime; {we want the sprite to animate every 100 milliseconds} FSprite.FTimeThreshold := 100; . . . end; procedure TfrmDXAppMain.DrawSurfaces; var . . . begin {erase the last frame of animation by using a simple color fill to ‘black out’ the entire backbuffer surface} FillChar(BltFx, SizeOf(TDDBltFx), 0); BltFx.dwSize := SizeOf(TDDBltFx); BltFx.dwFillColor := 0; FBackBuffer.Blt(nil, nil, nil, DDBLT_COLORFILL or DDBLT_WAIT, @BltFx); {increment the frame number and update the sprite’s position} with FSprite do begin {if the elapsed time since the last frame number increment is greater than our threshold amount...} if timeGetTime - FCurTime > FTimeThreshold then begin {animate the sprite by incrementing the frame number} Inc(FCurFrame); {make sure we roll over the frame number as necessary} if FCurFrame > FFrameNum then FCurFrame := 0; {store the current system time} FCurTime := timeGetTime; end; . . . end; Z-Order As stated above, the z-order of a sprite is its position along an imaginary third- dimensional axis. Some games may feature foreground sprites and background sprites, while others may have sprites that move closer to and farther from the user, scaling as appropriate in a pseudo three-dimensional viewpoint. In games like these, drawing sprites in the correct order becomes an important issue. However, actually accomplishing this illusion of depth is quite simple. Essentially, the application needs to draw the sprites starting with the farthest from the user and ending with the closest. As you draw the nearer sprites, their images will obscure those farther away, giving the illusion of depth. This is known as the painter’s algorithm; the technique is illustrated below. Figure 6-9:  The painter’s algorithm We’ve already implemented the painter’s algorithm in a very simplistic way by drawing the background behind the sprites before drawing them. In a more complex, real-world application, the z-order of the sprites themselves must be taken into account. We can accomplish this by simply adding another member to our sprite object for tracking this z-order. In practice, we’ll need to move the sprites and then sort them by z-order before drawing. The sorting step is necessary in order to draw the sprites in the correct order. Any well-documented, high-performance sorting algorithm will do. In the following example, we don’t employ any sort of real sorting algorithm for the sake of code simplicity. However, the example does demonstrate a simple z-ordering mechanism. Sprites that are moving downward have a higher, or closer, z-order than those moving upward. Implementing scaling to draw the sprites larger when they are closer and smaller when they are farther away would improve the illusion. Listing 6-8: Drawing sprites according to z-order type . . . {the sprite class} TSprite = record FXPos, FYPos, // tracks the current position FXVel, FYVel, // tracks the velocity Height, Width, // sprite frame height and width FCurFrame, // tracks the current frame number FFrameNum: Integer; // tracks the number of frames FImages: IDirectDrawSurface4; // a pointer to the sprite images FCurTime, // tracks a timing value FTimeThreshold: LongWord; // holds the animation timing threshold ZOrder: Integer; // the sprite depth end; var . . . Sprites: array[0..1] of TSprite; ZOrderIndex: array[0..1] of Integer; implementation . . . procedure TfrmDXAppMain.FormActivate(Sender: TObject); begin . . . {initialize the first spaceship} with Sprites[0] do begin Width := 61; Height := 56; FXPos := DXWIDTH div 2; FYPos := DXHEIGHT; FYVel := 3; FImages := FShip1; ZOrder := 0; end; {initialize the second spaceship} with Sprites[1] do begin Width := 60; Height := 74; FXPos := DXWIDTH div 2; FYPos := 0; FYVel := -3; FImages := FShip2; ZOrder := 1; end; . . . end; . . . procedure TfrmDXAppMain.DrawSurfaces; var iCount: Integer; Area: TRect; {this function moves a sprite} procedure MoveSprite(var Sprite: TSprite); begin Sprite.FYPos := Sprite.FYPos + Sprite.FYVel; if Sprite.FYPos<0 then begin Sprite.FYPos := 0; Sprite.FYVel := 0-Sprite.FYVel; {we’ve only got 2 z-order values, so flip it when the sprite hits a boundary} Sprite.ZOrder := 1-Sprite.ZOrder; end else if Sprite.FYPos>DXHEIGHT-Sprite.Height then begin Sprite.FYPos := DXHEIGHT-Sprite.Height; Sprite.FYVel := 0-Sprite.FYVel; Sprite.ZOrder := 1-Sprite.ZOrder; end; end; begin {erase the previous animation frame} Area := Rect(0, 0, DXWIDTH, DXHEIGHT); FBackBuffer.BltFast(0, 0, FBackground, Area, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); {move the sprites} for iCount := 0 to 1 do MoveSprite(Sprites[iCount]); {perform some really simplistic z-order sorting} if Sprites[0].ZOrder > Sprites[1].ZOrder then begin ZOrderIndex[0] := 0; ZOrderIndex[1] := 1; end else begin ZOrderIndex[0] := 1; ZOrderIndex[1] := 0; end; {now that the sprites are sorted per their z-order, draw them starting with the farthest sprite. this will result in a layered graphic with distant sprites being obscured by closer sprites} for iCount := 0 to 1 do FBackBuffer.BltFast(Sprites[ZOrderIndex[iCount]].FXPos, Sprites[ZOrderIndex[iCount]].FYPos, Sprites[ZOrderIndex[iCount]].FImages, Rect(0, 0, Sprites[ZOrderIndex[iCount]].Width, Sprites[ZOrderIndex[iCount]].Height), DDBLTFAST_SRCCOLORKEY or DDBLTFAST_WAIT); end; Previous Table of Contents Next Products |  Contact Us |  About Us |  Privacy  |  Ad Info  |  Home Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement.

Wyszukiwarka

Podobne podstrony:
terminarz roku 06 07 lato
terminarz roku 06 07 zima
III lek zagadnienia 06 07 popr
TI 01 06 07 T pl
plan zajec semestr 3 06 07
R 06 07
BO 06 07 Kontrakt
ARYTM KOL2 06 07 rozw

więcej podobnych podstron