Sprite Animation - PowerPoint PPT Presentation

1 / 52
About This Presentation
Title:

Sprite Animation

Description:

The DirectDraw component provides services through COM-based interfaces. ... Create at least a primary surface using IDirectDrawSurface ... – PowerPoint PPT presentation

Number of Views:68
Avg rating:3.0/5.0
Slides: 53
Provided by: abdennour8
Category:

less

Transcript and Presenter's Notes

Title: Sprite Animation


1
Sprite Animation
  • Lecture 5
  • Abdennour El Rhalibi

2
Architectural Overview of DirectDraw
  • DirectDraw enables a much higher level of
    efficiency and speed in graphics-intensive
    applications for Windows than is possible with
    GDI, while maintaining device independence.
  • DirectDraw provides tools to perform such key
    tasks as
  • Manipulating multiple display surfaces
  • Accessing the video memory directly
  • Page flipping
  • Back buffering
  • Managing the palette
  • Clipping
  • The DirectDraw component provides services
    through COM-based interfaces. In the most recent
    iteration, these interfaces are IDirectDraw7,
    IDirectDrawSurface7, IDirectDrawPalette,
    IDirectDrawClipper, and IDirectDrawVideoPort.

3
The Interfaces of DirectDraw
4
Using Interface Together
  • Create DirectDraw object
  • Retrieve a IDirectDraw7 interface
  • Create at least a primary surface using
    IDirectDrawSurface
  • Create a palette using IDrectDrawPalette
  • Initialize palette
  • Attach it to the surface
  • Create a single clipper and size it.
  • Draw on the primary surface.

5
DirectDraw Clipper
6
Creating a DirectDraw Object
  • LPDIRECTDRAW lpdd NULL
  • if (FAILED(DirectDrawCreate(NULL, lpdd, NULL))
  • // error
  • DirectDrawCreate parameters
  • lpGUID GUID of the display driver that we want
    use.
  • Usually, NULL the default hardware.
  • lpdd Pointer to a pointer receiving IDirectDraw
    interface pointer.
  • pUnkOuter advanced.. Just NULL

7
Getting an Interface Lift
  • LPDIRECTDRAW lpdd NULL
  • LPDIRECTDRAW lpdd7 NULL
  • if (FAILED(DirectDrawCreate(NULL, lpdd, NULL)))
  • // error
  • if (FAILED(lpdd-gtQueryInterface(IID_IDirectDraw7,
    (LPVOID )lpdd7)))
  • // error
  • lpdd-gtRelease( )
  • lpdd NULL
  • // use lpdd7

8
Cooperating with Windows - 1
  • Two modes
  • Full-screen mode
  • like an old DOS program
  • Entire screen is for DirectDraw
  • No GDI can be used
  • Easy to handle
  • Windowed mode
  • Game is one of the clients on Windows Desktop
  • Rather hard to control
  • Still have full access to 2D and 3D acceleration

9
Cooperating with Windows - 2
  • IDirectDraw7SetCooperativeLevel( )
  • HRESULT SetCooperativeLevel(HWND hWnd, DWORD
    dwFlags)
  • Control Flags
  • For full screen
  • DDSCL_ALLOWMODEX 320x200, 320x240, 320x400
  • DDSCL_ALLOWREBOOT CtrlAltDel rebooting
  • DDSCL_EXCLUSIVE
  • DDSCL_FULLSCREEN
  • For Windowed Mode
  • DDSCL_NORMAL

10
Cooperating with Windows - 3
  • Example
  • Game_Init( ) and Game_Shutdown( ).
  • int Game_Init(void parms NULL, int num_parms
    0)
  • if (FAILED(DirectDrawCreate(NULL, lpdd,
    NULL)))
  • if (FAILED(lpdd-gtQueryInterface(IID_IDirectDr
    aw4, )
  • lpdd4-gtSetCooperativeLevel(main_window_handle
    , DDSCL_NORMAL)
  • int Game_Shutdown(void parms NULL, )
  • if (lpdd4)
  • lpdd4-gtRelease( )
  • lpdd4 NULL

11
Getting into the Mode of Things
  • SetDisplayMode(DWORD dwWidth,
  • DWORD dwHeight,
  • DWORD dwBPP, // bits per pixel 8, 16,
    24, 32
  • DWORD dwRefreshRate, // 0 for default
  • DWORD dwFlags) // extra flags (advanced)
    0 for default
  • // 640x480 with 256 colors
  • lpdd4-gtSetDisplayMode(640, 480, 8, 0, 0)
  • // 800x600 with 16bit colors
  • lpdd4-gtSetDisplayMode(800, 600, 16, 0, 0)

12
Steps for 256 Color Mode
  • Create palette 256 PALETTENTRY
  • Create IDirectDrawPalette object
  • Attach the palette object to a drawing surface.
  • (Optional) You can change the palette entries.

13
Palette Data Structure
  • PALETTEENTRY palette256
  • // Black at palette0
  • palette0.peRed 0
  • palette0.peGreen 0
  • palette0.peBlue 0
  • palette0.peFlags PC_NOCOLLAPSE //
    preventing optimization by DirectX

  • .
  • // White at palette255
  • palette255.peRed 255
  • palette255.peGreen 255
  • palette255.peBlue 255
  • palette255.peFlags PC_NOCOLLAPSE
  • .

14
IDirectDrawPalette
  • Using IDirectDraw7CreatePalette( )
  • LPDIRECTDRAWPALETTE lpddpal NULL // palette
    interface
  • if (FAILED(lpdd4-gtCreatePalette(DDPCAPS_8BIT
    DDPCAPS_INITIALIZE DDPCAPS_ALLOW256,
  • palette, lpddpal, NULL)))
  • // error

15
Building a Display Surface
16
Sprite animation
17
New goodies
  • perform full-screen animation using 3 frames of
    animation
  • make the crow from example look like its flying
  • Use a timer to control rate at which frames are
    displayed

18
What is needed
  • add the following libraries
  • ddraw.lib
  • winmm.lib
  • Need 3 images
  • Middle.bmp
  • Up.bmp
  • Down.bmp

19
The Timer
  • class is CTimer, with constructor Ctimer()
  • file is Timer.h
  • int m_nStartTime records start time
  • virtual void start() starts the timer
  • virtual int time() returns time in ms
  • BOOL elapsed(int start, int interval)
  • returns TRUE if interval ms have elapsed since
    start
  • returns FALSE otherwise

20
The Timer class
class CTimer //game timer class protected
int m_nStartTime //time that timer was started
public CTimer() //constructor virtual
void start() //start the timer virtual int
time() //return the time in ms //has
interval ms elapsed since start? BOOL
elapsed(int start,int interval)
21
windows API function
include "timer.h" CTimerCTimer()
m_nStartTime(0) void CTimerstart()
m_nStartTimetimeGetTime() int
CTimertime() return timeGetTime()-m_nStartTime
int CTimerelapsed(int start, int
interval) //has interval elapsed from start?
int current_timetime() if(current_timegtstart
interval) start current_time return TRUE
else return FALSE
elapsed_time ?
22
Main.cpp
CBmpFileReader frame0,frame1,frame2 int
current_frame0 //current frame of
animation CTimer Timer //game timer BOOL
LoadImages() //load graphics from files to
surfaces if(!frame0.load("Right.bmp"))return
FALSE frame0.draw(lpPrimary) //draw to
primary surface if(!frame0.setpalette(lpPrimaryP
alette))return FALSE if(!frame0.setpalette(lpSe
condaryPalette))return FALSE
if(!frame1.load("Middle.bmp"))return FALSE
if(!frame2.load("Left.bmp"))return FALSE
return TRUE
all 3 images use same palette
23
Example1 vs Example2
while(TRUE) if(PeekMessage(msg,NULL,0,0,PM_N
OREMOVE)) if(!GetMessage(msg,NULL,0,0))ret
urn msg.wParam TranslateMessage(msg)
DispatchMessage(msg) else
if(!ActiveApp)WaitMessage()
while(TRUE) if(PeekMessage(msg,NULL,0,0,PM_N
OREMOVE)) if(!GetMessage(msg,NULL,0,0))ret
urn msg.wParam TranslateMessage(msg)
DispatchMessage(msg) else
if(ActiveApp) ProcessFrame() else
WaitMessage() //WinMain
24
ProcessFrame()
BOOL ProcessFrame() //process a frame of
animation ComposeFrame() //compose a frame in
secondary surface return PageFlip() //flip
video memory surfaces //ProcessFrame
25
BOOL ComposeFrame() static int
last_timeTimer.time() //Check that
current_frame stay in the range
if(current_framelt0)current_frame0
if(current_framegt3)current_frame3 //show a
frame switch(current_frame) case 0
frame0.draw(lpSecondary) break case 1
frame1.draw(lpSecondary) break case 2
frame2.draw(lpSecondary) break case 3
frame1.draw(lpSecondary) break //go to
next frame if(Timer.elapsed(last_time,100))
if(current_framegt4)current_frame0 return
TRUE
Why 4?
26
Oops
BOOL ProcessFrame() ComposeFrame() return
PageFlip() //flip video memory surfaces
switch(current_frame) case 0
frame0.draw(lpSecondary) break case 1
frame1.draw(lpSecondary) break case 2
frame2.draw(lpSecondary) break case 3
frame1.draw(lpSecondary) break
How does the page get to lpPrimay?
27
Sprite Animation
28
New Goodies
  • What is a sprite
  • how to set up a sprite file
  • what is blitting
  • transparent blitting in DirectDraw
  • separating an image from its properties
  • how to load draw multi-frame sprites
  • What happens if you try to draw outside the screen

29
sprite animation
  • a sprite is a small piece of artwork that moves
    across the screen
  • sprite animation is animating a sprite
  • sprites can have several frames of animation

30
blitting
  • drawing a sprite on a background
  • DirectDraw permits transparent blitting
  • designate one or more palette positions as
    transparent
  • draw sprites with holes in them so we can see the
    background

31
A Sprite file
multiple sprites in a single file allow the
artist to compare frames for consistency. All
artwork must be drawn with the same palette.
32
The Palette
  • Sprites.bmp uses same palette as Bckgnd.bmp
  • all of the artwork in a game must use the same
    palette
  • background color for Sprites.bmp is magenta
    (255,0,255)
  • important thing is not color but palette position
    must use same palette position to indicate
    transparent pixels

33
Messing up the transparency color
If the artwork is inconsistent with the program,
the sprite will be drawn with a block around it.
The same art tool used on two different
platforms may reverse the palettes on their
images.
34
transparent palette position
  • doesnt matter what color you put in transparent
    palette position since pixels are never drawn
  • best to use a color that isnt used elsewhere in
    the game so that the artist/tool doesnt use that
    palette position, expecting it to be drawn

35
The bounding box
  • The smallest rectangle that can fit around the
    sprite
  • in Sprites.bmp, all frames for a multi-frame
    sprite have same height/width
  • have to measure each sprite frame
  • for 640?480, top left pixel is 0, bottom right
    pixel is (639, 479)
  • bounding box
  • easier to identify top left bottom right
  • easier to see if you mess up!

36
This sprite is too large
If the sprite is too large, it may mess up a
neighboring sprite. if sprite is too small,
the sprite will be clipped along one or more
edges.
37
reading sprites from a file
CBmpFileReader
base class reads an image from a file. Derived
class reads a sprite (a rectangle) from a sprite
file the sprite file has multiple frames of
an image!
CBmpSpriteFileReader
38
draw first difference
class CBmpSpriteFileReader public
CBmpFileReader public //reuse everything in
base except draw() BOOL draw(LPDIRECTDRAWSURFA
CE surface, int width,int ht,int x,int y)
//draw sprite found in Sbmp.cpp similar to
CBmpFileReaderdraw, except src is set to
point y rows up from the bottom of the file, and
x pixels across. bmp files are store
upside-down src m_cImage
((m_BMPFileInfo.biHeight-1-y)m_BMPFileInfo.biWidt
hx)
39
draw second difference
BOOL draw(LPDIRECTDRAWSURFACE surface, int
width ,int ht, int x,int y) //draw
sprite Second difference for loop in draw only
moves ht rows of data, and each row has width
width, for(int i0 ilt ht i) //for each
row memcpy(dest,src,width) //copy
destddsd.lPitch src-m_BMPFileInfo.biWidth
//next row
40
BOOL CBmpFileReaderdraw (LPDIRECTDRAWSURFACE
surface) DDSURFACEDESC ddsd //direct draw
surface descriptor BYTE dest,src
//destination and source pointers int
src_width //width of source memset(ddsd,0,sizeof
(DDSURFACEDESC)) ddsd.dwSizesizeof(ddsd) if(F
AILED(surface-gtLock(NULL,ddsd,DDLOCK_WAIT,NULL)))
return FALSE dest(BYTE)ddsd.lpSurface
//destination srcm_cImage
((m_BMPFileInfo.biHeight-1)m_BMPFileInfo.biWidth)
//trim bmp if too wide if(m_BMPFileInfo.biWi
dthgtddsd.lPitch)src_widthddsd.lPitch else
src_widthm_BMPFileInfo.biWidth //move data to
surface for(int i0 iltm_BMPFileInfo.biHeight
i) memcpy(dest,src,src_width)
destddsd.lPitch src-src_width
surface-gtUnlock(NULL) return TRUE //draw
41
class CBaseSprite //simplest sprite
protected LPDIRECTDRAWSURFACE m_lpDDImage
//sprite image int m_nFrameCount //how many
frames used in sprite int m_nWidth,m_nHeight
//dimensions of sprite images void
CreateSurfaces() //create surfaces public
CBaseSprite(int frames,int w,int h)
//constructor CBaseSprite() //destructor
BOOL load(CBmpSpriteFileReader image,int frame,
int x,int y) virtual void draw(int
frame,int x,int y, LPDIRECTDRAWSURFACE
destination) //draw sprite void Release()
//release when game is over BOOL Restore()
//restore if user de-iconifies int
frame_count() //return number of frames int
height() //return height int width()
//return width
42
The constructor/destructor
extern LPDIRECTDRAW lpDirectDrawObject
CBaseSpriteCBaseSprite (int frames, int
width, int height) m_nFrameCount(frames),
m_nWidth(width), m_nHeight(height)
m_lpDDImagenew LPDIRECTDRAWSURFACEframes
for(int i0 iltframes i) m_lpDDImageiNULL
//create surfaces for sprite images
CreateSurfaces() CBaseSpriteCBaseSprite ()
deletem_lpDDImage
43
The plane example is 1 frame!This example is
from Main.cpp
BOOL LoadImages() //load graphics from files to
surfaces if(!background.load("bckgnd.bmp"))return
FALSE background.draw(lpBackground) //set
palettes in all surfaces if(!background.setpalet
te(lpPrimaryPalette))return FALSE
if(!background.setpalette(lpSecondaryPalette))retu
rn FALSE //load the plane sprite
if(!g_cSpriteImages.load("sprites.bmp"))return
FALSE planespritenew CBaseSprite(1,121,72)
if(!LoadPlaneSprite())return FALSE //load plane
images return TRUE
44
void CBaseSpriteCreateSurfaces()
DDSURFACEDESC ddsd //direct draw surface
descriptor ddsd.dwSizesizeof(ddsd) //required
field ddsd.dwFlagsDDSD_CAPSDDSD_HEIGHTDDSD_WI
DTH ddsd.ddsCaps.dwCapsDDSCAPS_OFFSCREENPLAIN
//offscreen ddsd.dwHeightm_nHeight
ddsd.dwWidthm_nWidth DDCOLORKEY ddck
//direct draw color descriptor
ddck.dwColorSpaceLowValue ddck.dwColorSpaceHighVa
lue TRANSPARENT_COLOR //set in Defines.h
for(int i0 iltm_nFrameCount i) //for each
frame if(FAILED(lpDirectDrawObject-gt
CreateSurface(ddsd,(m_lpDDImagei),NULL))) m_
lpDDImageiNULL //set the transparent
color m_lpDDImagei-gtSetColorKey(DDCKEY_SRCB
LT,ddck)
45
The Object class
  • Each object in the game is describe by Cobject
  • the class encapsulates everything about the
    object, including
  • its physical characteristics
  • its image
  • header file Objects.h

46
include "bsprite.h" class CObject //class for
a moving object private int m_nX,m_nY
//current location int m_nXspeed,m_nYspeed
//current speed int m_nLastXMoveTime //last
time the object moved CBaseSprite m_pSprite
//pointer to sprite public CObject()
void draw(LPDIRECTDRAWSURFACE surface) void
create(int x,int y,int xspeed,int yspeed,
CBaseSprite sprite) //create instance void
accelerate(int xdelta,int ydelta0) //change
speed void move() //make a move depending on
time and speed
47
The draw in CObject
// The object knows where to draw itself void
CObjectdraw(LPDIRECTDRAWSURFACE
surface) m_pSprite-gtdraw(0,m_nX,m_nY,surface)
48
The constructor
extern CTimer Timer CObjectCObject()
m_nXm_nYm_nXspeedm_nYspeed0
m_pSpriteNULL m_nLastXMoveTime0
49
Object creation
void CObjectcreate(int x,int y,int xspeed,int
yspeed, CBaseSprite
sprite) m_nLastXMoveTime0 //time m_nXx
m_nYy //location m_nXspeedxspeed
m_nYspeedyspeed //speed m_pSpritesprite
//image
50
Speeding up the object
void CObjectaccelerate(int xdelta,int ydelta)
m_nXspeedxdelta m_nYspeedydelta
51
void CObjectmove() //move object const int
XSCALE8 //to scale back horizontal motion
const int MARGIN100 //margin on outside of
page int xdelta //change in position int
timeTimer.time() //current time //horizontal
motion int tfactortime-m_nLastXMoveTime
//time since last move xdelta(m_nXspeedtfactor
)/XSCALE //x distance moved m_nXxdelta //x
motion if(xdeltam_nXspeed0)
m_nLastXMoveTimetime //wrap left
if(m_nXlt-MARGIN)m_nXSCREEN_WIDTHMARGIN
//wrap right if(m_nXgtSCREEN_WIDTHMARGIN)m_nX-M
ARGIN
52
ComposeFrame()
BOOL ComposeFrame() //compose a frame of
animation //draw background
lpSecondary-gtBltFast(0,0,lpBackground,NULL,
DDBLTFAST_NOCOLORKEYDDBLTFAST_WAIT) //move
objects plane.move() //draw objects
plane.draw(lpSecondary) return TRUE
//ComposeFrame
Write a Comment
User Comments (0)
About PowerShow.com