11 06


Delphi Graphics and Game Programming Exposed! with DirectX For versions 5.0-7.0:Special Effects                       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 Basic Theory Each transition effect may be implemented in wildly differing ways or with only subtle, minor differences, depending on the desired effect. In this example, let’s use three simple effects that are relatively easy to implement yet provide cool animation effects. Specifically, these transition effects will be melt, crawl, and dissolve. Melt This is the classic melting screen effect made popular by id software’s Doom. It works by first drawing the next scene image to the back buffer, and then drawing the closing scene one column at a time into the back buffer. An array of integers, one entry per column of pixels, is used to track the vertical offset of the start of the pixel column. By starting some columns before others, we can create the illusion of the foreground screen melting away to reveal the next scene. Figure 11-5:  The melt effect Crawl This is a variation of the dissolve effect below. Starting from one side of the screen, we use two variables to track a beginning and ending column (or row), spaced some arbitrary distance apart. At each frame of the animation, we increment both the beginning and ending columns (or rows). These define an area into which several pixels from the next scene are drawn. Their coordinates are chosen at random and copied into the back buffer at the same position. Past the ending column (or row), the “exposed” portion of the next scene is drawn. The effect appears to eat away at the foreground image, revealing the image of the next scene underneath. Figure 11-6:  The crawl effect Dissolve This is a common effect that makes one image appear to dissolve, revealing the image beneath it. It works by randomly choosing a pixel from the next image and copying it to the back buffer (over the previous image) at the same position. However, it is rather slow to use the entire screen area for the range of random pixel selection. Thus, we constrain the random pixel selection to an 8 × 8 pixel area, and then replicate that throughout the entire image. In other words, the screen is divided into 8×8 blocks. The next pixel is chosen from the first 8×8 area, and we use this coordinate as an offset for each 8×8 block throughout the screen. This creates a fast, effective dissolve effect. Figure 11-7:  The dissolve effect The following listing demonstrates a simple implementation of these three effects. Press the spacebar to move from one image to the next. Listing 11-5: Transition effects interface . . . type TTransitionType = (transMelt, transCrawl, transDissolve); . . . var . . . {holds the scene images} ScreenBackgrounds: array[0..2] of IDirectDrawSurface4; {tracks which background image is used next} NextBackground: Integer; {tracks the next transition effect to be used} NextTransition: TTransitionType; implementation . . . procedure TfrmDXAppMain.FormCreate(Sender: TObject); begin . . . {initialize the next background} NextBackground := 0; {initialize the next transition effect} NextTransition := transMelt; NextTransition := transMelt; end; . . . procedure TfrmDXAppMain.FormActivate(Sender: TObject); begin . . . {load the palette} FPalette := DDLoadPalette(FDirectDraw, ExtractFilePath(ParamStr(0))+ ‘begin.bmp’); {set the palette} FPrimarySurface.SetPalette(FPalette); {load the three images to be used in the transition effect animations} ScreenBackgrounds[0] := DDLoadBitmap(FDirectDraw, ExtractFilePath( ParamStr(0))+‘begin.bmp’); ScreenBackgrounds[1] := DDLoadBitmap(FDirectDraw, ExtractFilePath( ParamStr(0))+‘middle.bmp’); ScreenBackgrounds[2] := DDLoadBitmap(FDirectDraw, ExtractFilePath( ParamStr(0))+‘end.bmp’); {copy the first image to the screen} DestRect := Rect(0, 0, DXWIDTH, DXHEIGHT); FPrimarySurface.BltFast(0, 0, ScreenBackgrounds[0], DestRect, DDBLTFAST_NOCOLORKEY OR DDBLTFAST_WAIT); FBackBuffer.BltFast(0, 0, ScreenBackgrounds[0], DestRect, DDBLTFAST_NOCOLORKEY OR DDBLTFAST_WAIT); . . . end; . . . procedure TfrmDXAppMain.FormKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin if Key = VK_ESCAPE then Close; {if the spacebar was pressed...} if Key = Ord(‘ ’) then begin {move to the next transition} NextTransition := Succ(NextTransition); {rollover the transition effect if necessary} if Ord(NextTransition) > Ord(transDissolve) then NextTransition := transMelt; {perform the transition effect} CoolScreenTransition(NextTransition); end; end; procedure TfrmDXAppMain.CoolScreenTransition(TransitionType: TTransitionType); var HeadCol, TailCol: Integer; iCount, iCount2, iCount3: Integer; Block, DestRect: TRect; RandBlock, RandBlock2: Integer; Worms: array[0..DXWIDTH-1] of Integer; StillGoing: Boolean; begin {move to the next image} Inc(NextBackground); {rollover the image index, if necessary} if NextBackground > 2 then NextBackground := 0; {copy the foreground image into the back buffer} DestRect := Rect(0, 0, DXWIDTH, DXHEIGHT); FBackbuffer.BltFast(0, 0, FPrimarySurface, DestRect, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); case TransitionType of transMelt : begin {initialize the starting offsets for each column of pixels} for iCount := 0 to DXWIDTH-1 do Worms[iCount] := 0; {initialize the loop variable} StillGoing := TRUE; {begin the effect} while StillGoing do begin {assume that the effect will stop} StillGoing := FALSE; {for each column of pixels...} for iCount := 0 to DXWIDTH-1 do begin {if this column has not yet started to move...} if Worms[iCount] = 0 then {...give the column a 25% chance of starting} if Random(4) = 1 then Worms[iCount] := 1; {if this column has not yet reached to bottom, but is in motion...} if (Worms[iCount]<DXHEIGHT-1)and(Worms[iCount]>0) then begin {...there is still at least one column still ‘alive’, so the effect has not yet stopped} StillGoing := TRUE; {copy this column of pixels into its new position} Block := Rect(iCount, Worms[iCount], iCount+1, DXHEIGHT-3); FBackBuffer.BltFast(iCount, Worms[iCount]+3, FBackBuffer, Block, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); {copy the same column from the next scene above the currently moving column} Block := Rect(iCount, 0, iCount+1, Worms[iCount]+3); FBackBuffer.BltFast(iCount, 0, ScreenBackgrounds[NextBackground], Block, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); {move the column down a bit} Worms[iCount] := Worms[iCount]+3; end; end; {the back buffer now contains the next frame of the animation, so copy it to the screen} DestRect := Rect(0, 0, DXWIDTH, DXHEIGHT); FPrimarySurface.BltFast(0, 0, FBackbuffer, DestRect, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); end; {the animation is over, so copy the final image to both the front and back buffers to erase the last remains of the animation sequence} Block := Rect(0, 0, DXWIDTH, DXHEIGHT); FBackbuffer.BltFast(0, 0, ScreenBackgrounds[NextBackground], Block, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); FPrimarySurface.BltFast(0, 0, ScreenBackgrounds[NextBackground], Block, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); end; transCrawl : begin {begin tracking the beginning and ending columns} HeadCol := 0; TailCol := -10; {while the ending column is still on the screen...} while TailCol < (DXWIDTH div 5)-1 do begin {iterate through the columns of pixels between the beginning and ending column} for iCount := TailCol to HeadCol do {if this column is on the screen...} if iCount > -1 then for iCount2 := 0 to 20 do begin {choose a random block of pixels} RandBlock := Random(DXHEIGHT div 5); {copy this block of pixels from the next image into the destination at the same coordinates} Block := Rect(5*iCount, 5*RandBlock, 5*iCount+5, 5*RandBlock+5); FBackBuffer.BltFast(Block.Left, Block.Top, ScreenBackgrounds[NextBackground], Block, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); end; {if the ending column is on the screen...} if TailCol > -1 then begin {make sure we copy the entire column of pixels from the next image into the destination so that the final image will be complete} Block := Rect(5*TailCol, 0, 5*TailCol+5, DXHEIGHT); FBackBuffer.BltFast(Block.Left, Block.Top, ScreenBackgrounds[NextBackground], Block, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); end; {increment the beginning and ending columns} Inc(HeadCol); Inc(TailCol); {copy this frame of animation to the screen} Block := Rect(0, 0, DXWIDTH, DXHEIGHT); FPrimarySurface.BltFast(0, 0, FBackbuffer, Block, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); {pause for a short period} Sleep(20); end; {the animation is over, so copy the final image to both the front and back buffers to erase the last remains of the animation sequence} Block := Rect(0, 0, DXWIDTH, DXHEIGHT); FBackbuffer.BltFast(0, 0, ScreenBackgrounds[NextBackground], Block, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); FPrimarySurface.BltFast(0, 0, ScreenBackgrounds[NextBackground], Block, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); end; transDissolve : begin {we will copy 100 blocks of pixels for this effect} for iCount := 0 to 100 do begin {choose a random block of pixels from our 8×8 area} RandBlock := Random(8); RandBlock2 := Random(8); {this will be mirrored throughout the screen relative to each segmented 8×8 block of pixels} for iCount2 := 0 to 15 do for iCount3 := 0 to 12 do begin {copy the relative block of pixels from the next image into the back buffer} Block := Rect((5*RandBlock)+(iCount2*8*5), (5*RandBlock2)+(iCount3*8*5), (5*RandBlock)+(iCount2*8*5)+5, (5*RandBlock2)+(iCount3*8*5)+5); FBackBuffer.BltFast(Block.Left, Block.Top, ScreenBackgrounds[NextBackground], Block, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); end; {copy this frame of animation to the screen} Block := Rect(0, 0, DXWIDTH, DXHEIGHT); FPrimarySurface.BltFast(0, 0, FBackbuffer, Block, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); {pause for a short period} Sleep(20); end; {the animation is over, so copy the final image to both the front and back buffers to erase the last remains of the animation sequence} Block := Rect(0, 0, DXWIDTH, DXHEIGHT); FBackbuffer.BltFast(0, 0, ScreenBackgrounds[NextBackground], Block, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); FPrimarySurface.BltFast(0, 0, ScreenBackgrounds[NextBackground], Block, DDBLTFAST_NOCOLORKEY or DDBLTFAST_WAIT); end; end; 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:
11 06 2 MIĘDZY TEORIĄ A PRAKTYKĄ
2010 11 06 WIL Wyklad 06

więcej podobnych podstron