Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

This lesson is for members only. Join us and get access to hundreds of tutorials and a community of expert Pythonistas.

Unlock This Lesson

Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

Adding Background Images

00:00 In this lesson, you’ll start adding some background images. Up to this point, the images you’ve used have only been for the player and the enemies, so now it’s time to make some background images. Let’s make some clouds.

00:13 The clouds will add another level of difficulty in that they obscure the player, briefly.

00:22 The steps are going to look really familiar. You’re going to create a Cloud class. You’re going to add an image of a cloud to it. You’ll create a method .update() that moves the cloud toward the left side of the screen, and then you’ll create a custom event and handler to create new cloud objects at a set time interval.

00:43 Then, you add the newly created cloud objects to a new Group called clouds. And the last step is to set it up so that it updates and draws the clouds in your game loop.

00:54 And this should sound familiar, because it’s going to look really similar to the Enemy class that you created. Let me have you start to code it. Again, you might remember what Enemy looks like as a class. Again, loading the image, setting the color key, getting the rectangle, finding its center, setting the speed, and then its .update(), which was moving it to the left. Well, it’s going to look really similar.

01:29 So again, you’re going to extend pygame.sprite.Sprite and use an image.

01:42 To extend it, you’re also going to set up the .__init__()

01:52 and set up super(). Okay. So, you’re going to create the Surface based upon pygame.image.load(). The directory is images/ and it’s cloud.png. Then run the method .convert(). Move this up a little bit.

02:12 Then you need to do the color key. One unique thing here is the clouds are white and the color key in this case is going to be black. Basically, that’s what should be transparent, is the black areas.

02:25 And you’re going to use that RLEACCEL again—oh, I need a comma there. Okay. And not unlike the enemies, you’re going to have a starting position that’s randomly generated.

02:38 So the self.rect = self.surf.get_rect() (get rectangle). The center is going to be a random integer—so from random.randint()and then you’re going to take the SCREEN_WIDTH + 20.

02:55 So between there and SCREEN_WIDTH + 100, and then one more random for the height from 0—that’s the top of the screen—to the bottom of the screen, which is the total SCREEN_HEIGHT. So again, this is going to place it off the screen in a variety of positions between 20 to 100 off to the right of the screen, and then this is anywhere from the top to the bottom of the screen. Okay.

03:21 That closes center. And then this is going to close the rectangle here. I need to move the cloud based on a constant speed, unlike the missiles, and remove it when it passes the left edge again.

03:36 So, this is the .update() method you’re creating for the Cloud. self.rect, move in place, .move_ip(), and it’s going to move at -5, 0, not moving up and down, and then check if self.rect—the rightmost edge of the rectangle, if that’s less than 0, then kill the Cloud. Nice.

04:00 And it looks really familiar—I hope—to you, to the Enemy that you created earlier. So now, after having done that, you need to create a custom event.

04:11 So, you might remember creating events here for adding an enemy, and it’s going to be really similar.

04:20 Okay. So ADDCLOUD will be equal to pygame.USEREVENThow could we make it unique? Well, let’s make it + 2. pygame.time, setting a timer.

04:33 This timer is going to pull the trigger on ADDCLOUD, and how about every second? So, 1000. Okay. 1000 milliseconds.

04:40 Then, you need to do your grouping. Okay. So here you have enemies. Let’s add clouds, and that is also a sprite.Group.

04:52 Great. Looks good. So what’s next? Well, while your event loop is running, you’re going to look for the new event, which will be “Hey, should we add a new cloud?” This should look pretty similar.

05:06 So, if the event pops up—elif event.type == ADDCLOUD,

05:14 that’ll not only create the new cloud, but add it to the sprite groups. So here’s new_cloud, it is an instance of Cloud. And clouds, use that .add() method to add a new_cloud. Ope, not enemycloud.

05:32 And then all_sprites—it’s a member of that group too, right? .add(new_cloud). Cool! All right, what’s left? Well, we’ve got to have it update. So, here’s enemies updating.

05:45 We could do that in the same block here. # Update enemy position and clouds. clouds.update() will update all the clouds. One thing you’re going to change, though, is we’re going to change the color. Fill the screen with a blue, so it’s actually like a sky, and those white clouds will now stand out.

06:03 So (135, 206, 250). Okay. Change the color of the sky to sky blue. Oops, let’s add a space for the formatting there. You’re updating the clouds. Going in reverse here, ha.

06:19 You create a new_cloud right here, in this event, if this ADDCLOUD event appears. Again, that should happen every second, right?

06:28 Just like this happens every quarter of a second. And then here, you created that new Group, and then here you created the custom event ADDCLOUD, USEREVENT, pygame.time, ADDCLOUD—looks good. Okay.

06:43 And then again, your Cloud class. Going to save. Okay. So python sky_dodge.py. That’s blue! Looks good. I see a cloud. I don’t see it moving. Something must be wrong. It looks like we may need to update something.

07:11 Oh, .update() is in the wrong spot, right? It needs to be back here.

07:18 All these lines should not be indented so much. Right? That’s why they’re not moving. Okay. So, lines 91 to 96 should be back here at this level like .__init__(),

07:37 so the .update() method should be here. That’s what I missed. Okay.

07:44 Again, you might notice that it’s the same here. Okay. So now let’s try again.

07:54 Yeah. There’s some moving clouds now. Looks good! And the clouds don’t cause collisions. They do obscure the jet though. Cool. Boom. Congratulations! You finished Section 3.

08:12 Now, you’re on to Section 4 where you’ll start enhancing the game in our first lesson, where you’ll learn how to control the game speed.

John Berliner on March 30, 2020

Really enjoyed this tutorial!

I didn’t see anything about setting or changing layer order, so is it just the case that sprites instantiated later automatically get drawn to a higher-ordered layer than sprites drawn earlier? (unless some call is made to change a sprite’s layer?)

Chris Bailey RP Team on March 30, 2020

Hi @John Berliner, The simple way of working with layers is the order you add them to a sprite.Group(). If you were for example to flip the order ofcloudsandenemies` the clouds would appear below the missiles. There are a few additions to PyGame to manage layers, beyond the order you add them to a group. Unfortunately today is a bad day to try to get at the documentation, it is down. Not sure why. Otherwise I would give you the exact link. But when its back up, there are a bunch of methods, and addition to sprites to control the layers and ordering.

John Berliner on April 15, 2020

Got it. Of course you can have multiple Sprite groups too, right? I’d assume Sprite groups added later appear “above” previously-added Sprite groups…I’ll experiment. Thanks—

Become a Member to join the conversation.