Sprite Animation

Started by
5 comments, last by nanobyte 22 years, 8 months ago
I am using directx 8 to write my own sprite engine. But I have just one issue to work out and that is animation. I can load an animation sequence and draw it to the screen, the only problem is that it draws each frame on top of the other. For example: int explode[5] = { 1,2,3,4,5}; // animation sequence ship2.Update(); ship2.RenderAnimation(g_pBackSurface, 5, explode); Well, as you can imagine, this draws 5 explosions on top of each other! So my question is, how to I hide the frame before the next one is drawn? Here is the animation function: CSprite::RenderAnimation( LPDIRECT3DSURFACE8 pDestSurface, int numAnimations, int *data) { RECT SourceRect = { 0, 0, m_SpriteWidth, m_SpriteHeight }; POINT DestPoint = { m_x, m_y }; for(int num=0; num
Advertisement
I think the problem is that your rendering function is drawing each frame of animation during one pass of the main game loop. You need to do the following during each iteration of the game loop:
1) Update the frame (say from frame 2 to 3).
2) Display the current frame only (in this case frame 3)
3) Proceed with the rest of the game code.
well.... you cant draw an image over a previous one, you''ll have to "delete" the previous image and then draw the new one...

just refresh the hole screen, draw the background again and then draw the new image, like this:

while( !END_OF_GAME ){  draw_background();  draw_image()  ... all other stuff ...}


this way you''ll see just the current image on screen, and the older ones will be overlaped by the background.

basic but works

if you want something more efficent there are other ways to acomplish this, like the dirty rectangles algorithm and so on...


jakovo
Thanks, that worked! But, now is there a way to hide the animation after I''m done with it? or in other words how do I remove it from the screen after the animation sequence is complete? Thanks.
you need to get a game loop that runs over and over again according to a timer. The loop should handle input, gamestate, and rendering. In the rendering step you draw everything. You draw a background (or just clear the screen to a color such as black) and then you draw everything else. Each time through the loop you only draw one frame from each animation. Now if the animation stops just don''t draw the frame. Since you are clearing the frame every time if you don''t draw a new frame it will disappear. This way of doing things makes it easy to handle multiple objects, which is practically impossible with yours. So somehow organize all the things to be drawn, you could use a list representing everything to draw, a vector of vectors representing a grid of tiles, a std::map sorted by height, there are many ways so you should think about it long and hard and try different things. Then when it comes time to render iterate through whatever you are storing your stuff in and draw each picture.
after the animation is completed.
dont draw the sprite anymore.

for example inside your sprite class
create a member variable called bool bVisible;
then in your sprite::Draw() method check if the sprite is visible like this:

BOOL Sprite::Draw()
{
if( this->bVisible == FALSE )
return TRUE;
//

this way after the explosion is done animating
you can set bVisible to FALSE and it wont draw anymore
until you set it to TRUE again
Thanks everyone! I can sleep now! I promised myself I would not go to sleep until I figured out how to make sprite animation work After struggling for about an hour to set up all the functions right, I finally got everything to work correctly.

Here is the CSprite::Render

if(num SelectActiveSprite(data[num]);
Update();
Render(pDestSurface);
num++;
}
if(num == numAnimations)
visible = false;

So, for every frame, RenderAnimation() is called and num is updated once. Once it finishes, (num==numAnimations), visible is set to false and Render() is set not to draw if visible != true.


Thanks once again!

This topic is closed to new replies.

Advertisement