---
Here's a basic example of how to implement 2D animation using Python and Pygame (an SDL wrapper for Python). I am going to be using the following sprite sheet, which is a 2D version of Serge from the game Chrono Cross (created by the user poxy at the chaos-project.com forums).
Looking at the above sprite sheet, the upper-left image will be our base image (frame 1). We will not use column three at all because the animation looks better without it. So we will be cycling through images 1, 2, and 4 in each row.
As for the coding, we are going to create a class called Serge that extends the pygame.sprite.Sprite class. First I'll show you the whole code, then we'll go through it piece by piece.
Now, let's talk about what is actually happening in this code.
Here's a breakdown of the first 14 lines:
Line 3: Our class Serge will extend the pygame.sprite.Sprite class.
Line 4: The position parameter will be used so that we can indicate the sprite's position when we draw it to the screen.
Line 5: We load our sprite sheet and assign it to sheet.
Line 6: We use the set_clip() method in order to display only frame 1 of our sprite sheet.
Line 7: We assign our current image to the clipped area.
Line 8: Create a rect object to correspond to our image.
Line 9: Assign position so that it corresponds to the upper-left pixel of our rect.
Line 10: Assign our current frame to 0; this variable will be used later to cycle through the frames.
Lines 11-14: Create 4 dictionaries to store the pixel coordinates for our walking animation frames.
Lines 16-20:
In order to animate our character, we need to repeatedly cycle through three frames. In lines 16-20 we create a method to handle this.
Lines 22-27:
We create a method to clip the area of each frame. First we have to check whether we are dealing with multiple frames (movement) or a single frame (standing). If the character is moving, the frames are handled by the get_frame() method. If the character is simply standing, the frame is handled directly by Pygame's built-in functions.
Lines 29-52:
Next, update() relies on the previous two methods by passing them the dictionaries (in the case of movement) or single frames and moving the sprite in the correct direction using the built-in pygame.sprite.Sprite rect.x and rect.y values. Then it sets the current image to the appropriate clipped area.
Lines 54-78:
Lastly, we create the method handle_event() to handle keypresses. Depending on what key is pressed, we pass a state (in this case a string) to the update() method which carries out all work described above. update() animates the character and moves him across the screen based on what key is pressed.
We can save this as serge.py. With all that out of the way, our main.py file is very simple.
In line 8 we create an instance of our Serge class called 'player', and position its upper-left pixel at the x-y coordinates (150, 150). We then create a simple main loop, call our event handler (line 19), make a blue background (line 20), and draw 'player' on the screen (line 21). In order to control the animation and movement speed, we set the clock.tick() value to 10.
Output:
If you run from source, the animation will be smoother. With some very basic tweaking and more advanced sprite sheets, you can greatly improve the quality of the animation by adding more frames, and using the code above you could easily add a running option.
Hopefully this gives you a general idea of how to implement sprite animation in Python and Pygame.