Tuesday, April 27, 2010

2D Animation: Part 7 Using Custom Animations

Welcome to part 7 of the 2d sprite animation tutorial this will be essentially part 2 of using custom animations were I will go over using the new custom animations to allow you to move left, right, up and down with an idle state for each direction using just two animations, an eight frame animation for moving and a four frame animation for your idle state. I would suggest downloading the Dude sprite sheet in the source code at the bottom of the page and following along using your part 6 source code as it is the exact same for now. So lets declare our two main variables, our keyboard state and our dude.
Now that we have our dude animation lets load him in using our generic constructor and setting his position as usual. Now instead of just a name, row and frames where now going to add in an Animation Class which for typing reasons i named 'ani'. Now our animations are all the same just at different rotations so with each new animation we just have to change the rotation and add it to our dictionary just like this.
Don't forget to set the current animation to something otherwise it will not draw which is what were doing next, although its the same as before.
Now if you were to run the game so far you would notice that it draws the bottom facing animation and not the right facing animation even though we set it to that. This is because when we set our animations we used the same animation class so each time we changed it, it would change for all of them. Now we can fix this a couple of different ways, the way I am going to do is were we create a copy of our animation and use that in our animations and not the original. So for this all we have to do is create a copy method in our animation class that will return a copy of the current animation.
After we create this method lets just copy paste a ".Copy()" to the end of our "ani" for each of our animations in the Load method. The result will be as follows.
So now we have our dude correctly loading we just need to update and move him so lets do that now. This is all basic so I am not going to go over it in much detail I just want to mention one thing. The else statement at the very bottom is were we will be adding in our idle animation code which will be the next image.
So if you look at how we organized our animations you will see that our idle animations just have "Idle" added to the end of the direction so what we can do is say if your not pushing a direction, check to see if our current animation contains the phrase "Idle" otherwise add it to our animation and it will now correctly set it to the animations we want it to. Also don't forget to update the dude.
Now if you run it you will see him correctly animating and moving, but there is one problem that you may notice or rather eventually you will crash the game. The reason for this is because when we change our animation from a running to an idle were going from an 8 frame animation to a 4 frame animation without resetting the frame index. Essentially its trying to load rectangles that don't exist, so what were going to do is change the string Animation from a public string to a property. Explaining what a property is would not be part of this tutorial I would suggest looking it up or asking a question, for now just replace the public string Animation with the following. This changes the frame index to 0 while changing the current animation which is what we need it to do.
That is it for the final part of the 2d animation tutorial, at least for now, if I can think of more ideas I will make more tutorials. If you have any suggestions post a comment.

You are free to use or modify this source in any way it is for learning purposes

13 comments:

  1. Thanks very helpful ^_^

    ReplyDelete
  2. I did this and used two custom sprite sheets. One is 3 x 4, it works correctly, the other one is 1 x 8 (with four animations consisting of 2 frames each) I can't figure out how to animate it correctly. Also they are both flashing, another problem I can't figure out. Any thoughts would be appreciated, great tutorials but I can't figure this out. Thanks.

    ReplyDelete
  3. Looks like it's skipping a frame or something (thus the flashing).

    ReplyDelete
  4. If your creating a sprite sheet for 4 animations it should be a 2x4 sheet not a 1x8. If you could give me more information I could probably help but just that its flashing is not much.

    ReplyDelete
  5. Hey, very nice animation method and classes, love it! (using it in my game, ill put your name at the credits if you want :))

    But i am facing a problem.

    I want to use in my game sprite effects instead of particle effects. I have one animation for explosion with 9frames (in a spritesheet).

    I tried to do like i did with the player animations (SpriteAnimation explosion, load it and set the islooping to false).

    I want (for test, later ill change) for the explosion animation to run when i press X (set a firerate so the player cant fire 2 or more bullets at once). The problem is that the animation (if i press 2x very quickly) is not beginning at the first frame and looping till the 9 frame).

    How can i use an explosion animation using your animation method?

    Thank you

    ReplyDelete
  6. So you want the animation to play every time the player shoots ( x for a test ) and when the you push it twice real fast it just plays it once?

    If that is the case you can either check if the animation is already playing and if it is do nothing and just wait until its available again.

    Or you can create multiple instances of the animation and only update ones that are being used.

    Or you can create a modified version that allows you to have multiple instances of the same animation within one class to where it will keep track of multiple frame indexes and draw all of them instead of just one.

    Hope that helps.

    ReplyDelete
  7. It would help if the animation actually stopped when it reachs the end. Then the problem would be resolved...

    Because i press X (explosion starts), after the animation reaches the last frame, it stops updating and drawing too.

    if i press X again (explosion starts from frame 1 again), etc etc.

    But right now, its not doing nothing of the above...

    ReplyDelete
  8. Oh ya this tutorial was more or less designed for continuous animations. To set it up to work like this i would get a bool to represent whether or not the animation should draw (IsAlive or something) and use this in the draw method.

    if(IsAlive)
    spriteBatch.Draw(...);

    Then create a Reset function that will reset the frame index and anything else that needs to be reset. Then create a Start / Enable function to turn the animation back on to be drawn. Then call the reset and start function each time you want to turn the explosions back on. Or you could just create one function like Restart to do both of these if you don't think you will need them individually. There is much more you could do with sprite animations this was just a basic tutorial.

    I would also check whether or not the animation is alive in your update function would help there as well.

    Does that do what you want?

    ReplyDelete
  9. Yes, thank you :)

    ReplyDelete
  10. Great Tutorials!! You really give some nice design patterns for handling 2D animations through XNA.

    ReplyDelete
  11. Great tutorial! Thanks!

    ReplyDelete
  12. Thanks for the tutorials, very nice in handling animation. I've extended the Sprite Manager class to read a text file that contains the images rectangles information of the spriteseet and creates the animation dictionaries based on that. its usful since I found it hard to create a spriteseet exactly the way i want it and every image has different dimentions. A question I have is how to handle collision detection?
    would you add that to the sprite manager class?
    It would be greart if you'll post an articles on how to do it
    Thanks.

    ReplyDelete