Pygame Zero With Mu

Introduction to Pygame Zero

1. Goals

This tutorial is adapted from the Introduction to Pygame Zero tutorial on Pygame Zero's website. Videos are present in case you need a little extra help completing some of the steps. The objectives for this tutorial are to:

2. Starting Mu

Make sure to start Mu in Pygame Zero mode. If not, then any code associated with the Pygame Zero module will not run, and you will get an error message.

Now you can go ahead and save your file. Wherever you save your file now, is where Mu will create your asset folders.

3. Download Assets

We need to download the following images and sound file before we can begin. Download the assets and place them in their proper folders. If you need help watch the video below the files. The images are from Kenny.

alien image alien hurt image image for eep sound file

4. Hints

As a general rule the import statements should come first, followed by variables and the general game functions, then the draw function, and finally the update function. You also need to make sure that there is only one version of a function.

You can click on the blue down arrows to reveal extra information or hints.

5. Creating a Window

We will start by creating a window with a width of 500 pixels and height of 500 pixels. Enter and play the following code.

WIDTH = 500
HEIGHT = 500

What do you notice? If everything went correctly, you should have noticed a black window pop up with the dimensions of 500px by 500px. The window is black because we have not actually drawn anything to the screen yet. We wil do that next. Update your code with the draw function.

WIDTH = 500
HEIGHT = 500

def draw():
    screen.fill((51, 133, 255))

The draw function is called by Pygame Zero whenever it needs to paint the screen. Within the draw function we have a screen.fill() method call that fills the screen with a solid color. In this case we have filled the screen with a bluish color. The color is specified with a tuple containing the red, green, and blue values for the color we want. Each value can range from 0 to 255. Try changing the values and see what happens or use a color picker to choose a value you like. You can also pass a hex value for the color as a string.

Next we will draw a sprite to the screen.

6. Drawing the Sprite

We have done a few things here. We have loaded the sprite by creating an instance of the Actor Class, passed it the filename of our image we want to be our sprite, and saved it as the variable alien. Now we can access various attributes of the Actor class using the variable alien.

In the code below we use the attributes pos and height of our sprite. alien.pos sets the position of the center our alien sprite to the x and y coordinates given by the tuple (100, 56). By using HEIGHT = alien.height + 20 we set the height of our window to the height of the alien sprite plus 20 pixels.

alien = Actor('alien')
alien.pos = (100, 56)

WIDTH = 500
HEIGHT = alien.height + 20

def draw():
    alien.draw()

Notice that we have changed the draw() function. We have removed the screen.fill() method and added the alien.draw() method. This draws our sprite to the screen. Our window should now look like the image below.

alien sprite

Try changing the color of the background by adding back the screen.fill() method to the draw function. What do you notice if you place it after alien.draw().

I discuss the code changes and adding a background color in the video below.

7. Moving the Sprite

Before continuing remove the screen.fill() method from the draw() function.

Now that we have our sprite on the screen we can make it move. We are going to have our alien move across the screen starting just left of the screen out of view.

Position the alien just left of the screen by changing its topright atribute. Change the alien.pos line to read:

alien.topright = (0, 10)

Run the code to make sure it works. You shouldn't be able to see the alien. Try changing the X value in the tuple for its position and see what you notice. Don't forget to change it back to 0 before you proceed.

Now we are going to create the update() function. The update() function is called once every frame. Place the update function at the bottom of the file.

def update():
    alien.left = alien.left + 10

When you run the code, hopefully you noticed two things. Click the arrow to the right once you have thought about it.

  1. The alien is leaving a trail of aliens behind it.
  2. The alien goes off the right hand side of the screen and does not return.

Let's begin by fixing the first problem. Whenever the update() function updates the position of the alien by shifting it 10 pixels to the right, Pygame Zero will call the draw() function. This will draw the alien at the new shifted location, but we have not removed the old alien. We can get rid of the old alien by using screen.clear(). Go ahead and place screen.clear() in the correct location within the draw() function and test your code.

Compare your output to the video below and fix your code if your output does not match.

Now we are going to make our alien return back to the left edge once it is off the screen. This will make it look like the alien is looping across the screen.

To do this we will need to add some code to our update() function. See if you can replace the two question marks in the code below with their correct values.

def update():
    alien.left = alien.left + 10
    if alien.left > ? :
        alien.right = ?

Once you think your code is working correctly, click the arrow to check your code.

def update():
    alien.left = alien.left + 10
    if alien.left > WIDTH:
        alien.right = 0

The video below explains how our new code works.

8. Interacting with the Alien

Now that we have an alien moving across the screen, it would be nice to be able to interact with it. We are going to add a function to handle mouse clicks.

Add the following code to your program in the appropriate location.

def on_mouse_down(pos):
    if alien.collidepoint(pos):
        print("Eek!")
    else:
        print("You missed me!")

Now each time we click on the alien, you should see "Eek!" printed to the console below your code. Whenever we miss you should see "You missed me!".

The on_mouse_down() function is an event handler. Each time the mouse is clicked, the function is called with the mouse pointer position as an argument. The conditional if alien.collidepoint(pos): checks if the alien collided with the position of the mouse pointer.

9. Keeping Score

Before moving on make sure your code is well organized and add any comments you think will be helpful later on. This would also be a good time to save your code as another version. You can do this by using Crtl-Shift-s. This will let you save a copy of your program with a different name. I encourage you to do this frequently.

I'm going to leave the score keeping exercise up to you. You need to add code to your on_mouse_down() function so that you can keep score. Your code will need to:

  1. Initialize a variable alien.score to 0 outside of the on_mouse_down() function
  2. Increase your score and print the updated score to the console when you click on the alien
  3. Decrease the score and print the updated score to the console when you miss the alien
  4. Include a background color. You will no longer need screen.clear()

Show me your progress once you have finished adding your score keeping features so that I can check your code and give you feedback.

10. Progress Check

Before continuing, make sure your game has the following features.

The video below demonstrates each of the features your game should have so far.

11. Adding Sounds

In this section we will add a sound effect that is triggered when you click on the alien. To do this we will use the sounds object and its play() method to play the eep.wav sound file.

We do this by using the pattern sounds.sound_file_name.play(). In our case since we are using the sound file eep.wav, our line of code would be sounds.eep.play(). Click here for more information on how to use the sounds object.

Go ahead and add sounds.eep.play() to the on_mouse_down() function so that eep.wav plays when you click on the alien.

12. Animating the Alien

Make sure to save your code as a new version before beginning this section. We will be changing our code around quite a bit and you might need your previous code if all does not go well. Since we will be using an animation to indicate whether we have clicked on the alien or not, we can delete our print("Eek!") and print("You missed me!") lines.

Let's start working on our animation by setting the alien image to alien_hurt.png when we click on the alien. Place alien.image = "alien_hurt" in the on_mouse_down() function so that the image changes when we click on the alien.

Once you play it, what do you notice? Check your answer by clicking the down arrow.

Hopefully you noticed that once you click the alien, it changes to 'hurt' but does not change back to 'normal'. The video below shows how your game should behave at this point.

This is another good save point. In order to fix our problem with getting the alien back to 'normal' we will need to do some reorganizing (refactoring).

We are going to start by creating a function to handle changing our alien to "normal" and another to change our alien to "hurt". Below is our function to change our alien to "normal".

def change_to_normal():
    alien.image = "alien"

The above code is setting the image attribute for alien to alien.png

Next we need to make our function change the alien to "hurt". This is a little trickier. We need this function to change the alien to "hurt" and back to "normal" after a period of time. While we are at it, let's add our sounds.eep.play() method to the hurt function. This way one function will handle everything related to when we click on the alien. Define the change_to_hurt() function below the change_to_normal() function. So far your change_to_hurt()function should look like the code below.

def change_to_hurt():
    sounds.eep.play()
    alien.image = "alien_hurt"

Right now the code only plays the "eep" sound and changes our alien to "hurt", but does not change it back to "normal". To do this we will use our change_to_normal() function along with clock.schedule_unique() to change our alien back to "normal" one second after the alien is clicked. This is done by scheduling the change_to_normal() function to run one second after the change_to_hurt() function is called. To do this, add the following line to your change_to_hurt() function.

clock.schedule_unique(change_to_normal, 1.0)

We have all of the functions we need to make our code work, but we have not actually called them anywhere.

We need to call the change_to_hurt() function in the on_mouse_down() function where we check if the alien has been clicked. Since the change_to_hurt() function takes care of the "eep" sound and changing our alien to "hurt", replace the sounds.eep.play() and alien.image = "alien_hurt" lines in the on_mouse_down() function with the change_to_hurt() function

13. Progress Check

Below is a list of the new features we have added. Before continuing make sure your game can now do the following

14. Print to Screen

The score is currently being printed to the console. Next on our list is to display our score on our game screen. We will use the Screen's draw.text() method. When doing this we need to be aware of a few things.

  1. Our screen.draw.text() needs to go in the draw function
  2. The draw() function knows to update the text on the screen whenever the alien.score changes
  3. We don't need our print(alien.score) statements in the on_mouse_down() function anymore because of Item 2.
Use the information provided in this link to change your code so that the score is drawn to the game screen.

Try to get your score to display on the game screen similar to the example in the video below. The background color does not matter.

15. Customize

If you've made it this far, you should be proud of yourself. Now you get a chance to customize your game. Below are some ideas to help get you started.

  1. Add background music
  2. Have the speed change as your score changes
  3. Change the alien image to something you like
  4. Add a background image instead of a solid color
  5. Change the path of the alien during gameplay
  6. You can lose or win the game
  7. Game has a start "button"