programming4us
programming4us
MULTIMEDIA

Programming with DirectX : The 2D Resurgence - Handling Multiple Sprites

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
Drawing more than one sprite and keeping the code clean is going to require a change to the way the sprite information is stored. Previously, the sprite’s position and size were stored in a series of global variables.
float spritePosX = 320;
float spritePosY = 240;
float spriteWidth = 64;
float spriteHeight = 64;

Since you’re going to need this information for multiple sprites, this information is going to be moved to a structure.

Defining a GameSprite Structure

The GameSprite structure contains the sprite’s position and dimensions and is a much cleaner way of storing this information. Additionally, a new Boolean variable called visible is added. The visible variable is used to track whether the sprite is currently able to be seen on the screen. This enables the sprites to be shown or hidden. This is useful if sprites were being used for bullets or other items that have a limited lifetime.

// Sprite structure
typedef struct
{
    // sprite dimensions
    float width;
    float height;
    
    // sprite position
    float posX;
    float posY;
    
    BOOL visible;
} GameSprite;

Since you’ll need multiple sprites, an array of GameSprite structures should be created. The small snippet below creates an array of ten GameSprite structures.

#define MAX_SPRITES 10
GameSprite sprites[MAX_SPRITES] = {0};

Initializing the GameSprite Structures

Initializing the sprite data in the GameSprite structure is very similar to how you set up one sprite. Create a loop to allow all the sprites to be set up at one time.

In the following code, the ten GameSprite structures are initialized with a size of 64 × 64 and a random screen position. Each of the sprites also has its visible variable set to TRUE.

// Loop through and init the active sprites
for (int curSprite = 0; curSprite < MAX_SPRITES; curSprite++)
{
    
    // Set the width and height of the sprite
    sprites[curSprite].width = 64;
    sprites[curSprite].height = 64;
    
    // Create and set a random x, y position
    sprites[curSprite].posX = (float)(rand()%600);
    sprites[curSprite].posY = (float)(rand()%450);
    
    // This sprite is visible
    sprites[curSprite].visible = TRUE;
}

The Sprite Pool

Instead of associating a single D3DX10_SPRITE structure with each GameSprite, you’re going to employ a sprite pool. A sprite pool is an array of D3DX10_SPRITE structures where each structure is used on an as-needed basis. The structures are filled dynamically with information from the GameSprite objects each frame. These sprites are updated using the Update function. By using a sprite pool, the amount of dynamic allocations is kept down and places a restriction on the memory sprites can use.

Because the pool is pre-allocated, the size of the sprite pool array needs to be large enough to hold all the possible sprites that may be visible at one time. In the following code, there is enough space for thirty-two sprites to be allocated. An additional variable, numActiveSprites, is also being declared here. Since the number of sprites visible on the screen will be less than the number of available slots in the sprite pool, it is best to keep track of the number of sprites to be drawn. This variable comes in handy later when the function to draw the sprites is called.

// Maximum number of sprites possible in the pool
#define NUM_POOL_SPRITES 32

// Create the sprite pool array
D3DX10_SPRITE   spritePool[NUM_POOL_SPRITES];

// the number of active sprites
int numActiveSprites = 0;

Tip

Separating the game logic contained in the GameSprite from the rendering of the sprites in the pool allows for the drawing method to be changed without affecting the game logic.


Clearing the Sprites in the Pool

It is always a good idea to clear out all the items in the sprite pool to a default value before they’re used. Doing so keeps you from accidentally using garbage data.

// Loop through and set the defaults for the
// sprites in the pool
for (int i = 0; i < NUM_POOL_SPRITES; i++)
{
    // Texture for this sprite to use
    spritePool[i].pTexture = gSpriteTextureRV;
    spritePool[i].TextureIndex = 0;
    
    // top-left location in U,V coords
    spritePool[i].TexCoord.x = 0;
    spritePool[i].TexCoord.y = 0;
    
    // Determine the texture size in U, V coordinates
    spritePool[i].TexSize.x = 1;
    spritePool[i].TexSize.y = 1;
    
    spritePool[i].ColorModulate = D3DXCOLOR(1.0f, 1.0f, 1.0f, 1.0f);
}

All the sprites in the pool default to using the same texture in the pTexture variable.

Updating the Sprites

During the main loop, the information contained in each of the GameSprite structures needs to be copied to available sprites available in the sprite pool. Since the GameSprites do not have a specific sprite associated with them, they must be updated dynamically each frame. The UpdateScene function below sets up each sprite in the sprite pool with the correct information and keeps a running total of the number of sprites currently active.

In the following code sample, only sprites that have their visible variable set to TRUE are being updated.

/*******************************************************************
* UpdateScene()
* Updates the scene with the current sprite information
* Inputs - void
* Outputs - void
*******************************************************************/
void UpdateScene()
{
    D3DXMATRIX matScaling;
    D3DXMATRIX matTranslation;
    
    int curPoolIndex = 0;
    
    // Loop through the sprites
    for (int i = 0; i < MAX_SPRITES; i++)
    {
        // only update visible sprites
        if (sprites[i].visible)
        {
            // set the proper scale for the sprite
    D3DXMatrixScaling(&matScaling, sprites[i].width, sprites[i].height,
1.0f);
            // Move the sprite to spritePosX, spritePosY
            // SpriteWidth and SpriteHeight are divided by 2 to move the
            // translation point to the top-left sprite corner instead of
            // the center of the sprite.
            D3DXMatrixTranslation(&matTranslation,
                (float)sprites[i].posX + (sprites[i].width/2),
                (float)(windowHeight – sprites[i].posY - (sprites[i].
                height/2)), 0.1f);
            
            // Update the sprites position and scale
            spritePool[curPoolIndex].matWorld = matScaling * matTranslation;
            // Increment the pool index
            curPoolIndex++;
        }
    }
    
    // set the number of active sprites
    numActiveSprites = curPoolIndex;
}

					  

The UpdateScene function should be called before the Render function in the main game loop.

Drawing More Than One Sprite

Now that you have multiple sprites created and updating, how do you draw them? Well, you remember before where I mentioned that DrawSpritesImmediate was capable of drawing more than one sprite? The first parameter to the DrawSpritesImmediate function is a pointer to an array of D3DX10_SPRITE structures. Because the sprite pool is an array of this type, it can be passed directly into the DrawSpritesImmediate function.

Previously, a value of 1 had been passed into this function to draw only a single sprite. Now that there’s an array of sprites to draw, the number of active sprites should be passed in. The variable numActiveSprites contains the current number of valid sprites in the array.

The DrawSpritesImmediate function isn’t the only available function for drawing sprites. The ID3DX10Sprite object also includes the function DrawSpritesBuffered. The behavior of the two functions is slightly different.

The DrawSpritesImmediate function sends the sprites to the video hardware as soon as it is called.

The DrawSpritesBuffered function builds up a list of sprites to be drawn before actually sending them to the card. This is useful if you have functions where one or only a few sprites are needed each time. Once you’re ready to finally draw the sprites, calling the function Flush sends the sprites to the video card.

The following code sample shows an example usage of the DrawSpritesBuffered function.

/*******************************************************************
* Render
* All drawing happens in the Render function
* Inputs - void
* Outputs - void
*******************************************************************/
void Render()
{
    if (pD3DDevice != NULL)
    {
        
        // clear the target buffer
pD3DDevice->ClearRenderTargetView(pRenderTargetView, D3DXCOLOR(0.0f, 0.0f,
      0.0f, 0.0f));
        
        if (spriteObject != NULL)
        {
           HRESULT hr = spriteObject->SetProjectionTransform(&matProjection);
            
            // start drawing the sprites
            spriteObject->Begin(D3DX10_SPRITE_SORT_TEXTURE);
            
            // Draw all the sprites in the pool
            spriteObject->DrawSpritesBuffered(spritePool,
            numActiveSprites);
            
            // Finish up and send the sprites to the hardware
            spriteObject->Flush();
            spriteObject->End();
        }
        
        // display the next item in the swap chain
        pSwapChain->Present(0, 0);
    }
}
Other  
 
Top 10
Free Mobile And Desktop Apps For Accessing Restricted Websites
MASERATI QUATTROPORTE; DIESEL : Lure of Italian limos
TOYOTA CAMRY 2; 2.5 : Camry now more comely
KIA SORENTO 2.2CRDi : Fuel-sipping slugger
How To Setup, Password Protect & Encrypt Wireless Internet Connection
Emulate And Run iPad Apps On Windows, Mac OS X & Linux With iPadian
Backup & Restore Game Progress From Any Game With SaveGameProgress
Generate A Facebook Timeline Cover Using A Free App
New App for Women ‘Remix’ Offers Fashion Advice & Style Tips
SG50 Ferrari F12berlinetta : Prancing Horse for Lion City's 50th
- Messages forwarded by Outlook rule go nowhere
- Create and Deploy Windows 7 Image
- How do I check to see if my exchange 2003 is an open relay? (not using a open relay tester tool online, but on the console)
- Creating and using an unencrypted cookie in ASP.NET
- Directories
- Poor Performance on Sharepoint 2010 Server
- SBS 2008 ~ The e-mail alias already exists...
- Public to Private IP - DNS Changes
- Send Email from Winform application
- How to create a .mdb file from ms sql server database.......
programming4us programming4us
programming4us
 
 
programming4us