Python Multimedia: Animation Examples using Pyglet

Exclusive offer: get 50% off this eBook here
Python Multimedia

Python Multimedia — Save 50%

Learn how to develop Multimedia applications using Python with this practical step-by-step guide

$26.99    $13.50
by Ninad Sathaye | August 2010 | Open Source

The previous article, Python Multimedia: Fun with Animations using Pyglet, introduced you to the fundamentals of developing animations using Python and Pyglet multimedia application development frameworks.

In this article by Ninad Sathaye, author of Python Multimedia Beginner's Guide, we will:

  • Work on a project, 'Bowling animation', where animations can be controlled using inputs from the keyboard.
  • Develop relevant code to create an animation using different regions of a single image.
  • Work on an exciting project that animates a car moving in a thunderstorm. This project deals with many important things covered throughout this article.

(For more resources on Python, see here.)

Single image animation

Imagine that you are creating a cartoon movie where you want to animate the motion of an arrow or a bullet hitting a target. In such cases, typically it is just a single image. The desired animation effect is accomplished by performing appropriate translation or rotation of the image.

Time for action – bouncing ball animation

Lets create a simple animation of a 'bouncing ball'. We will use a single image file, ball.png, which can be downloaded from the Packt website. The dimensions of this image in pixels are 200x200, created on a transparent background. The following screenshot shows this image opened in GIMP image editor. The three dots on the ball identify its side. We will see why this is needed. Imagine this as a ball used in a bowling game.

Python Multimedia: Animations Examples using Pyglet

The image of a ball opened in GIMP appears as shown in the preceding image. The ball size in pixels is 200x200.

  1. Download the files SingleImageAnimation.py and ball.png from the Packt website. Place the ball.png file in a sub-directory 'images' within the directory in which SingleImageAnimation.py is saved.
  2. The following code snippet shows the overall structure of the code.

    1 import pyglet
    2 import time
    3
    4 class SingleImageAnimation(pyglet.window.Window):
    5 def __init__(self, width=600, height=600):
    6 pass
    7 def createDrawableObjects(self):
    8 pass
    9 def adjustWindowSize(self):
    10 pass
    11 def moveObjects(self, t):
    12 pass
    13 def on_draw(self):
    14 pass
    15 win = SingleImageAnimation()
    16 # Set window background color to gray.
    17 pyglet.gl.glClearColor(0.5, 0.5, 0.5, 1)
    18
    19 pyglet.clock.schedule_interval(win.moveObjects, 1.0/20)
    20
    21 pyglet.app.run()

    Although it is not required, we will encapsulate event handling and other functionality within a class SingleImageAnimation. The program to be developed is short, but in general, it is a good coding practice. It will also be good for any future extension to the code. An instance of SingleImageAnimation is created on line 14. This class is inherited from pyglet.window.Window. It encapsulates the functionality we need here. The API method on_draw is overridden by the class. on_draw is called when the window needs to be redrawn. Note that we no longer need a decorator statement such as @win.event above the on_draw method because the window API method is simply overridden by this inherited class.

  3. The constructor of the class SingleImageAnimation is as follows:

    1 def __init__(self, width=None, height=None):
    2 pyglet.window.Window.__init__(self,
    3 width=width,
    4 height=height,
    5 resizable = True)
    6 self.drawableObjects = []
    7 self.rising = False
    8 self.ballSprite = None
    9 self.createDrawableObjects()
    10 self.adjustWindowSize()

    As mentioned earlier, the class SingleImageAnimation inherits pyglet.window.Window. However, its constructor doesn't take all the arguments supported by its super class. This is because we don't need to change most of the default argument values. If you want to extend this application further and need these arguments, you can do so by adding them as __init__ arguments. The constructor initializes some instance variables and then calls methods to create the animation sprite and resize the window respectively.

  4. The method createDrawableObjects creates a sprite instance using the ball.png image.

    1 def createDrawableObjects(self):
    2 """
    3 Create sprite objects that will be drawn within the
    4 window.
    5 """
    6 ball_img= pyglet.image.load('images/ball.png')
    7 ball_img.anchor_x = ball_img.width / 2
    8 ball_img.anchor_y = ball_img.height / 2
    9
    10 self.ballSprite = pyglet.sprite.Sprite(ball_img)
    11 self.ballSprite.position = (
    12 self.ballSprite.width + 100,
    13 self.ballSprite.height*2 - 50)
    14 self.drawableObjects.append(self.ballSprite)

    The anchor_x and anchor_y properties of the image instance are set such that the image has an anchor exactly at its center. This will be useful while rotating the image later. On line 10, the sprite instance self.ballSprite is created. Later, we will be setting the width and height of the Pyglet window as twice of the sprite width and thrice of the sprite height. The position of the image within the window is set on line 11. The initial position is chosen as shown in the next screenshot. In this case, there is only one Sprite instance. However, to make the program more general, a list of drawable objects called self.drawableObjects is maintained.

  5. To continue the discussion from the previous step, we will now review the on_draw method.
    def on_draw(self):
    self.clear()
    for d in self.drawableObjects:
    d.draw()

    As mentioned previously, the on_draw function is an API method of class pyglet.window.Window that is called when a window needs to be redrawn. This method is overridden here. The self.clear() call clears the previously drawn contents within the window. Then, all the Sprite objects in the list self.drawableObjects are drawn in the for loop.

    Python Multimedia: Animations Examples using Pyglet

  6. The preceding image illustrates the initial ball position in the animation.

  7. The method adjustWindowSize sets the width and height parameters of the Pyglet window. The code is self-explanatory:

    def adjustWindowSize(self):
    w = self.ballSprite.width * 3
    h = self.ballSprite.height * 3
    self.width = w
    self.height = h

  8. So far, we have set up everything for the animation to play. Now comes the fun part. We will change the position of the sprite representing the image to achieve the animation effect. During the animation, the image will also be rotated, to give it the natural feel of a bouncing ball.

    1 def moveObjects(self, t):
    2 if self.ballSprite.y - 100 < 0:
    3 self.rising = True
    4 elif self.ballSprite.y > self.ballSprite.height*2 - 50:
    5 self.rising = False
    6
    7 if not self.rising:
    8 self.ballSprite.y -= 5
    9 self.ballSprite.rotation -= 6
    10 else:
    11 self.ballSprite.y += 5
    12 self.ballSprite.rotation += 5

    This method is scheduled to be called 20 times per second using the following code in the program.

    pyglet.clock.schedule_interval(win.moveObjects, 1.0/20)

    To start with, the ball is placed near the top. The animation should be such that it gradually falls down, hits the bottom, and bounces back. After this, it continues its upward journey to hit a boundary somewhere near the top and again it begins its downward journey. The code block from lines 2 to 5 checks the current y position of self.ballSprite. If it has hit the upward limit, the flag self.rising is set to False. Likewise, when the lower limit is hit, the flag is set to True. The flag is then used by the next code snippet to increment or decrement the y position of self.ballSprite.

  9. The highlighted lines of code rotate the Sprite instance. The current rotation angle is incremented or decremented by the given value. This is the reason why we set the image anchors, anchor_x and anchor_y at the center of the image. The Sprite object honors these image anchors. If the anchors are not set this way, the ball will be seen wobbling in the resultant animation.
  10. Once all the pieces are in place, run the program from the command line as:

    $python SingleImageAnimation.py

    This will pop up a window that will play the bouncing ball animation. The next illustration shows some intermediate frames from the animation while the ball is falling down.

Python Multimedia: Animations Examples using Pyglet

What just happened?

We learned how to create an animation using just a single image. The image of a ball was represented by a sprite instance. This sprite was then translated and rotated on the screen to accomplish a bouncing ball animation. The whole functionality, including the event handling, was encapsulated in the class SingleImageAnimation.

Python Multimedia Learn how to develop Multimedia applications using Python with this practical step-by-step guide
Published: August 2010
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

Read more about this book

(For more resources on Python, see here.)

Project: a simple bowling animation

It's time for a small project. We will re-use most of the code we used in the Single Image Animation section and some more stuff to create an animation where a rolling ball hits a pin in a bowling game. Although this article covers animation, this project will give you a preliminary understanding on how to turn an animation into a game. This is not a real game as such, but it will involve some user interactions to control the animation.

Python Multimedia: Animations Examples using Pyglet

The starting position in the bowling animation, showing ball and pin images.

Time for action – a simple bowling animation

Let's develop the code for this application. As mentioned earlier, a big chunk of the code comes from the Single Image Animation section. So we will only discuss the new and modified methods needed to create a bowling animation.

  1. Download the Python source file BowlingAnimation.py from the Packt website. The overall class design is the same as the one developed in the Single Image Animation section. We will only discuss the new and modified methods. You can review the rest of the code from this file.
  2. Also, download the image files used in this project. These files are ball.png and pin.png . Place these files in a sub-directory images. The images directory should be placed in the directory in which the above Python source file is located.
  3. The __init__ method of the class is identical to that of class SingleImageAnimation. The only change here is that it initializes the following flags:

    self.paused = False
    self.pinHorizontal = False

    The flag self.pinHorizontal is used later to check if the pin is knocked out by the ball. Whereas, self.paused is used to pause or resume the animation depending on its value.

  4. The createDrawable object method is modified to create a sprite instance for the pin image. Also, the position of the ball and pin sprites are adjusted for our animation needs. The code is presented as follows:

    1 def createDrawableObjects(self):
    2 ball_img= pyglet.image.load('images/ball.png')
    3 ball_img.anchor_x = ball_img.width / 2
    4 ball_img.anchor_y = ball_img.height / 2
    5
    6 pin_img = pyglet.image.load('images/pin.png')
    7 pin_img.anchor_x = pin_img.width / 2
    8 pin_img.anchor_y = pin_img.height / 2
    9
    10 self.ballSprite = pyglet.sprite.Sprite(ball_img)
    11 self.ballSprite.position = (0 + 100,
    12 self.ballSprite.height)
    13
    14 self.pinSprite = pyglet.sprite.Sprite(pin_img)
    15 self.pinSprite.position = (
    16 (self.ballSprite.width*2 + 100,
    17 self.ballSprite.height) )
    18
    19 # Add these sprites to the list of drawables
    20 self.drawableObjects.append(self.ballSprite)
    21 self.drawableObjects.append(self.pinSprite)

    The code block 6-8 creates an image instance for the pin image and then sets the image anchor at its center. The Sprite instances representing ball and pin images are created on lines 10 and 14 respectively. Their positions are set such that the initial positions appear as shown in the earlier illustration. Finally these sprites are added to the list of drawable objects that are drawn in on_draw method.

  5. Next, let's review the moveObjects method. As before, this method is called every 0.05 seconds.

    1 def moveObjects(self, t):
    2 if self.pinHorizontal:
    3 self.ballSprite.x = 100
    4 self.pinSprite.x -= 100
    5
    6 if self.ballSprite.x < self.ballSprite.width*2:
    7 if self.ballSprite.x == 100:
    8 time.sleep(1)
    9 self.pinSprite.rotation = 0
    10 self.pinHorizontal = False
    11
    12 self.ballSprite.x += 5
    13 self.ballSprite.rotation += 5
    14
    15 if self.ballSprite.x >= self.ballSprite.width*2:
    16 self.pinSprite.rotation = 90
    17 self.pinSprite.x += 100
    18 self.pinHorizontal = True

    The if block, from lines 6 to 13, is called for when the x position of the ball sprite is between 100 pixels to twice the width of the self.ballSprite . On line 12, the x position of self.ballSprite is incremented by 5 pixels. Also, the sprite is rotated by 5 degrees. The combination of these two transforms creates an effect where we see the ball rolling horizontally, from left to right, inside the Pyglet window. As seen earlier, the center of the pin is located at x = self.ballSprite.width*2 + 100 and y = self.ballSprite.height.

    The if block from lines 15 to 18 is where the ball appears to have hit the pin. That is, the x coordinate of ball sprite center is about 100 pixels away from the center of the pin. The 100-pixel value is chosen to account for the ball radius. Therefore, once the ball hits the pin, the pin image is rotated by 90 degrees (line 16). This creates a visual effect where the pin appears to be knocked down by the ball. The x coordinate of the pin is incremented by 100 pixels so that, after the pin rotation, the ball and pin images don't overlap. You can do some more improvement here. Shift the y position of the pin sprite further down, so that the pin appears lying on the ground. In this if block, we also set the flag self.pinHorizontal to True. When the moveObjects method is called the next time, the first thing that is checked is whether the pin is vertical or horizontal. If the pin is horizontal, the original positions of the ball and pin are restored by the code on lines 2 to 4. This is a preparation for the next animation loop. On line 9, the pin is rotated back to 0 degree, whereas on line 10, the flag self.pinHorizontal is reset to False.

  6. With the code we developed so far, and with the remaining code from class SingleImageAnimation , if you run the program, it will show the bowling animation. Now let's add some controls to this animation. A flag, self.paused, was initialized in the constructor. It will be used here. Just like on_draw, on_key_press is another API method of pyglet.window.Window. It is overridden here to implement pause and resume controls.

    1 def on_key_press(self, key, modifiers):
    2 if key == pyglet.window.key.P and not self.paused:
    3 pyglet.clock.unschedule(self.moveObjects)
    4 self.paused = True
    5 elif key == pyglet.window.key.R and self.paused:
    6 pyglet.clock.schedule_interval(
    7 self.moveObjects, 1.0/20)
    8 self.paused = False

    The key argument is one of the keyboard keys pressed by the user. The if block from lines 2 to 4 pauses the animation when P key is pressed. The method self.moveObjects is scheduled to be called every 0.05 seconds. The scheduled callback to this method is canceled using the pyglet.clock.unschedule method. To resume the animation, the schedule_interval method is called on line 6. The self.paused flag ensures that the multiple keypresses won't have any undesirable effect on the animation. For example, if you press the R key multiple times, the code will just ignore the keypress events that follow.

  7. Refer to the file BowlingAnimation.py to review or develop the rest of the code and then run the program from the command line as:

    $python BowlingAnimation.py

    This will pop up a window in which the animation will be played. Press the P key on the keyboard to pause the animation. To resume a paused animation, press the R key. The next illustration shows a few intermediate frames in this animation.

Python Multimedia: Animations Examples using Pyglet

The preceding image is a screen capture of a running animation at different time intervals.

What just happened?

We completed a simple but exciting project where an animation of a bowl hitting a pin was developed. This was accomplished by moving and rotating the image sprites on the screen. Several methods from the SingleImageAnimation class were re-used. Additionally, we learned how to control the animation by overriding the on_key_press API method.

Animations using different image regions

It is possible to create an animation using different regions of a single image. Each of these regions can be treated as a separate animation frame. In order to achieve the desired animation effect, it is important to properly create the image with regions. In the following example, the animation will be created using such regions. We will also be using the default position parameters for each of the regions within that image. Thus, our main task in this section is simply to use these regions in their original form and create animation frames out of them. We will first see how the image looks. The following illustration shows this image.

Python Multimedia: Animations Examples using Pyglet

A single image file with an imaginary 'grid' on top of it appears in the previous image.

The horizontal dotted lines overlaying this image indicate how an imaginary image grid divides the image into different regions. Here we have four rows and just a single column. Thus, during the animation, each of these image regions will be shown as a single animation frame. Notice how the droplet images are drawn. In the first row, the four droplets are drawn at the top. Then in the next row, these images are slightly offset to the south-west direction compared to the droplets in the first row. This offset is increased further in the third and fourth rows.

Time for action – raindrops animation

Let's create an animation of falling raindrops by using different regions of a single image.

  1. Download the Python source file RainDropsAnimation.py and the image file droplet.png from the Packt website. As done before, place the image file in a sub-directory images. The images directory should be placed in the directory in which the Python source file is located.
  2. The __init__ method of the class RainDropsAnimation is presented.

    1 def __init__(self, width=None, height=None):
    2 pyglet.window.Window.__init__(self,
    3 width=width,
    4 height=height)
    5 self.drawableObjects = []
    6 self.createDrawableObjects()

    The code is self-explanatory. The class RainDropsAnimation inherits pyglet.window.Window. The constructor of the class calls the method that creates the Sprite instance for displaying the animation on the screen.

  3. Let's review the createDrawableObjects method.

    1 def createDrawableObjects(self):
    2 num_rows = 4
    3 num_columns = 1
    4 droplet = 'images/droplet.png'
    5 animation = self.setup_animation(droplet,
    6 num_rows,
    7 num_columns)
    8
    9 self.dropletSprite = pyglet.sprite.Sprite(animation)
    10 self.dropletSprite.position = (0,0)
    11
    12 # Add these sprites to the list of drawables
    13 self.drawableObjects.append(self.dropletSprite)

    The pyglet.image.Animation instance is created on line 5, by calling setup_animation method. On line 9, the Sprite instance is created for this animation object.

  4. The setup_animation method is the main worker method that uses regions within the image file to create individual animation frames.

    1 def setup_animation(self, img, num_rows, num_columns):
    2 base_image = pyglet.image.load(img)
    3 animation_grid = pyglet.image.ImageGrid(base_image,
    4 num_rows,
    5 num_columns)
    6 image_frames = []
    7
    8 for i in range(num_rows*num_columns, 0, -1):
    9 frame = animation_grid[i-1]
    10 animation_frame = (
    11 pyglet.image.AnimationFrame(frame,
    12 0.2))
    13 image_frames.append(animation_frame)
    14
    15 animation = pyglet.image.Animation(image_frames)
    16 return animation

    First, the instance of image is created on line 2. The ImageGrid is an imaginary grid placed over the droplet image. Each 'cell' or the 'image region' within this image grid can be viewed as a separate image frame in an animation. The ImageGrid instance is constructed by providing the image object and the number of rows and columns as arguments. The number of rows in this case is 4 and there is only a single column. Thus, there will be four such image frames in the animation corresponding to each of these rows in the ImageGrid. The AnimationFrame object is created on line 10. The code on line 8 increments the value of i from maximum to minimum region or cell of the imaginary grid. Line 9 gets the specific image region and this is then used to create the pyglet.image.AnimationFrame instance, as we did on line 10. The second argument is the time for which each frame will be displayed on the screen. Here, we are displaying each frame for 0.2 seconds. All such animation frame forms are stored in a list image_frames and then the pyglet.imae.Animation instance is created using this list.

  5. Refer to the file RainDropsAnimation.py to review the rest of the code and then run the program from the command line as:
    $python RainDropsAnimation.py

    This animation displays four image regions of a single image, one after another. The next illustration shows these four images.

    Python Multimedia: Animations Examples using Pyglet

    The four image frames that display different regions of a single image appear in the previous illustration. These four image frames are repeated in the animation loop.

What just happened?

We created an animation using different regions of a single image. Each of these regions was treated as a separate animation frame. The creation of an image used in this animation was briefly discussed. Among many other things, we learned how to create and use Pyglet classes such as ImageGrid and AnimationFrame.

Project: drive on a rainy day!

This project is essentially a summary of what we have learned so far in this article. Additionally, it will cover a few other things such as adding sound effects to an animation, showing or hiding certain image sprites while the animation is being played, and so on. In this animation, there will be a stationary cloud image. We will re-use the code from the raindrops animation section to animate falling rain. There will be an image sprite to animate lightning effect. Finally, a car cartoon will be shown passing by from left to right in this heavy rain. The following snapshot is an animation frame that captures all these component images.

Python Multimedia: Animations Examples using Pyglet

Time for action – drive on a rainy day!

It's time to write the code for this animation.

  1. Download the Python source file RainyDayAnimation.py. We will discuss some of the important methods from this file. You can go through the rest of the code from this file.
  2. Download the image files, droplet.png, cloud.png, car.png, and lightening.png from the Packt website. Place these image files in a sub-directory called images. The images directory should be placed in the directory where the Python source file is located.
  3. The constructor of the class is written as follows:
    1  def __init__(self, width=None, height=None):
    2 pyglet.window.Window.__init__(self,
    3 width=width,
    4 height=height,
    5 resizable=True)
    6 self.drawableObjects = []
    7 self.paused = False
    8
    9
    10 self.createDrawableObjects()
    11 self.adjustWindowSize()
    12 # Make sure to replace the following media path to
    13 # with an appropriate path on your computer.
    14 self.horn_sound = (
    15 pyglet.media.load('C:/AudioFiles/horn.wav',
    16 streaming=False) )

    The code is same as the one developed in the raindrops animation. The media file horn.wav is decoded on line 14. The flag streaming is set to False so that the media can be played multiple times during the animation. Make sure you specify an appropriate audio file path on your computer on line 15.

  4. Let's review the createDrawableObjects method:
    1 def createDrawableObjects(self):
    2
    3 num_rows = 4
    4 num_columns = 1
    5 droplet = 'images/droplet.png'
    6 animation = self.setup_animation(droplet,
    7 num_rows,
    8 num_columns)
    9
    10 self.dropletSprite = pyglet.sprite.Sprite(animation)
    11 self.dropletSprite.position = (0,200)
    12
    13 cloud = pyglet.image.load('images/cloud.png')
    14 self.cloudSprite = pyglet.sprite.Sprite(cloud)
    15 self.cloudSprite.y = 100
    16
    17 lightening = pyglet.image.load('images/lightening.png')
    18 self.lSprite = pyglet.sprite.Sprite(lightening)
    19 self.lSprite.y = 200
    20
    21 car = pyglet.image.load('images/car.png')
    22 self.carSprite = pyglet.sprite.Sprite(car, -500, 0)
    23
    24 # Add these sprites to the list of drawables
    25 self.drawableObjects.append(self.cloudSprite)
    26 self.drawableObjects.append(self.lSprite)
    27 self.drawableObjects.append(self.dropletSprite)
    28 self.drawableObjects.append(self.carSprite)

    The code block from lines 3 to 10 is identical to the one developed in the raindrops animation. The self.dropletSprite image is placed at an appropriate position. Next, we just create sprites to load images of clouds, lightning, and car in the Pyglet window. These sprites are placed at appropriate locations within the window. For example, the starting position of the car is off the screen. It is anchored at x = -500 and y = 0. The code block from lines 24 to 28 adds all the Sprite instances to self.drawableObjects. The draw() method of each one of these instances is called in on_draw method.

  5. To achieve the desired animation effect, we have to move around various sprites during the animation. This is done by scheduling a few methods to be called at specified time intervals. These methods update the coordinates of the sprite or toggle its visibility when the Pyglet window is redrawn. The code is illustrated as follows:

    # Schedule the method RainyDayAnimation.moveObjects to be
    # called every 0.05 seconds.
    pyglet.clock.schedule_interval(win.moveObjects, 1.0/20)

    # Show the lightening every 1 second
    pyglet.clock.schedule_interval(win.show_lightening, 1.0)

    We have already seen an example of the moveObjects method in earlier sections. In this project, we schedule another method, RainyDayAnimation.show_lightening, to be called every second. This method created an animation effect where lightning strikes every second at different positions.

  6. We will now review the method show_lightening.

    1 def show_lightening(self, t):
    2 if self.lSprite.visible:
    3 self.lSprite.visible = False
    4 else:
    5 if(self.lSprite.x == 100):
    6 self.lSprite.x += 200
    7 else:
    8 self.lSprite.x = 100
    9
    10 self.lSprite.visible = True

    self.lSprite is the sprite representing the lightning image. Our target is to create an animation effect where the lightning flashes for a moment and then disappears. This can be accomplished by toggling the Sprite.visible property. When this property is set to False, the lightning is not shown. When it is set to True, the else block 4-10 is executed. The position of self.lSprite is changed so that the lightning appears at different locations the next time this method is called.

  7. The moveObjects method is scheduled to be called every 0.05 seconds.

    1 def moveObjects(self, t):
    2 if self.carSprite.x <= self.cloudSprite.width:
    3 self.carSprite.x += 10
    4 else:
    5 self.carSprite.x = -500
    6 self.horn_sound.play()

    Every time it is called, it moves the position of the Sprite representing the car by 10 pixels in the positive direction of x axis. However, if the x coordinate of the self.carSprite exceeds its width, the car is reset to its original position. Also, at the starting position of the car, the horn sound is played.

  8. Review the rest of the code from file RainyDayAnimation.py. Make sure to replace the audio file path for self.horn_sound with an appropriate file path on your computer. Once everything is all set, run the program from the command line as:

    $python RainyDayAnimation.py

    This will pop up a window that will play the animation in which a fun car cruises along in a thunderstorm. The next illustration shows some intermediate frames from the animation.

    Python Multimedia: Animations Examples using Pyglet

    Intermediate frames from an animation where a car drives along on a rainy day appear in the preceding image.

What just happened?

The animation developed in this project used four different images. We learned how to add sound effects and change the visibility of the image sprites during the animation. Some of the images were translated or made intermittently visible to achieve the desired animation effect. Different regions of a single image were used to animate raindrops. Overall, this fun project covered most of the things we learned throughout this article.

Have a go hero – add more effects

  1. Additional sound effects—whenever lightning strikes in the animation, play a thunderstorm sound.
  2. In the code presented earlier, the lightning image position is toggled between two fixed locations. Use random module in Python to get a random coordinate between 0 to self.cloudSprite.width and use that as the x coordinate of self.lSprite.
  3. Add keyboard controls to change the speed of the car, the frequency of lightning, and so on.

Summary

In this article, we covered the following:

  • Wrote code to play a pre-created animation.
  • Learned things such as modifying the position of the Pyglet sprite, adding keyboard and mouse controls and adding sound effects to the animation.
  • Worked on a cartoon animation project 'Drive on a Rainy Day'. Here we applied several of the techniques learned throughout the article.

Further resources on this subject:


Python Multimedia Learn how to develop Multimedia applications using Python with this practical step-by-step guide
Published: August 2010
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

About the Author :


Ninad Sathaye

Ninad has more than 6 years of experience in software design and development. He is currently working at IBM India. Prior to IBM, he was a Systems Programmer at Nanorex Inc. based in Michigan, USA. At Nanorex, he was involved in the development of an open source, interactive 3D CAD software, written in Python and C. This is where he developed his passion for the Python programming language. Besides programming, his favorite hobbies are reading and traveling. Ninad holds a Master's of Science degree in Mechanical Engineering from Kansas State University, USA.

Books From Packt


Python 3 Object Oriented Programming
Python 3 Object Oriented Programming

Python Testing: Beginner's Guide
Python Testing: Beginner's Guide

Spring Python 1.1
Spring Python 1.1l

Matplotlib for Python Developers
Matplotlib for Python Developers

Expert Python Programming
Expert Python Programming

MySQL for Python: Database Access Made Easy
MySQL for Python: Database Access Made Easy

jQuery 1.4 Reference Guide
jQuery 1.4 Reference Guide

Agile Web Application Development with Yii1.1 and PHP5
Agile Web Application Development with Yii1.1 and PHP5


Your rating: None Average: 5 (1 vote)
^_^ Great by
^_^ Great

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
K
A
W
7
t
q
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software