Animating Your Sprites

To follow the same pattern that was used in the previous chapter, you should now make a copy of this code so that it can be updated to show some animated sprites.

USING NON-SQUARE SURFACES

In Direct3D textures are normally required not only to be square, but to also have each side have a length that is a power of two. Most of the modern cards out today have support for textures that don't fit these parameters, but even those that do can suffer a performance loss for using "irregularly" shaped textures.

In the previous chapter, the animated sprites file was "enlarged" to be a square with a power-of-two length, with the remaining area being filled with "unused" data just to ensure that the texture could be loaded on most cards. DirectDraw does not enforce these rules on the surfaces it creates, thus the sprite in this example is of the exact size needed to hold the data.

The major changes will once again happen in the sprite class. The same constants that were used before can be used now:

 private const int NumberSpritesRow = 6; private const int NumberSpritesCol = 5; private const int SpriteSizeWidth = 50; private const int SpriteSizeHeight = 45; 

The source code included on the CD uses the file sprites.bmp for the sprites to be rendered, which is the same file used in the previous chapter, just with different dimensions and no alpha channel.

You will need to store the animation frame as well, which is a combination of a row and column. Add those variables to your sprite class:

 private int column = 0; private int row = 0; 

Now, you will need to update the constructor, to randomly place the sprite somewhere on the screen, with a random animation frame:

 public GraphicsSprite() {     xPosition = rnd.Next(Form1.ScreenWidth-SpriteSizeWidth);     yPosition = rnd.Next(Form1.ScreenHeight-SpriteSizeHeight);     xUpdate += (float)rnd.NextDouble();     yUpdate += (float)rnd.NextDouble();     column = rnd.Next(NumberSpritesCol);     row = rnd.Next(NumberSpritesRow);     if ((column % 3) == 0)         xUpdate *= -1;     if ((row % 2) == 0)         yUpdate *= -1; } 

The Draw method will also need updating:

 public void Draw(Surface backBuffer, Surface spriteSurface) {     backBuffer.DrawFast(xPosition, yPosition, spriteSurface,             new Rectangle(column * SpriteSizeWidth, row * SpriteSizeHeight,         SpriteSizeWidth, SpriteSizeHeight), DrawFastFlags.DoNotWait |         DrawFastFlags.SourceColorKey); } 

As you see, we calculate the source rectangle based on the animation frame and the sprite size. Once again, the sprite is drawn using the source color key transparency. Finally, you will need to make the Update method handle the animation as well. See Listing 17.3:

Listing 17.3 Updating Your Animated Sprites
 public void Update() {     // Update the current position     xPosition += (int)xUpdate;     yPosition += (int)yUpdate;     // See if we've gone beyond the screen     if (xPosition > (Form1.ScreenWidth - SpriteSizeWidth))     {         xUpdate *= -1;     }     if (yPosition > (Form1.ScreenHeight - SpriteSizeHeight))     {         yUpdate *= -1;     }     // See if we're too high or too the left     if (xPosition < 0)     {         xUpdate *= -1;     }     if (yPosition < 0)     {         yUpdate *= -1;     }     // Now update the column     column++;     if (column >= NumberSpritesCol)     {         row++;         column = 0;     }     if (row >= NumberSpritesRow)     {         row = 0;     } } 

With the sprite class finally updated, your main class should have a few compilation errors now. First, replace your sprite creation code:

 // Add a few sprites for(int i = 0; i < 100; i++)     ar.Add(new GraphicsSprite()); 

The last two items that need updating are both in the rendering code, but are removing the size parameter that is passed into the sprite methods. You can replace this method with the following:

 protected override void OnPaint(System.Windows.Forms.PaintEventArgs e) {     DirectXException.IgnoreExceptions();     foreach(GraphicsSprite gs in ar)         gs.Update();     backBuffer.ColorFill(0);     foreach(GraphicsSprite gs in ar)         gs.Draw(backBuffer, sprite);     primary.Flip(backBuffer, FlipFlags.DoNotWait);     this.Invalidate(); } 

As you can see, the differences between Direct3D and DirectDraw aren't as all-encompassing as some people seem to think. While it's true that porting a fully 3D application to DirectDraw is next to impossible, it would be relatively simple to port any 2D application from one to the other.



Managed DirectX 9 Graphics and Game Programming, Kick Start
Managed DirectX 9 Kick Start: Graphics and Game Programming
ISBN: B003D7JUW6
EAN: N/A
Year: 2002
Pages: 180
Authors: Tom Miller

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net