Archived

This topic is now archived and is closed to further replies.

nanobyte

Sprite Animation

Recommended Posts

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

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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.

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
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

Share this post


Link to post
Share on other sites
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!

Share this post


Link to post
Share on other sites