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.
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.
Then, you add the newly created
cloud objects to a new
clouds. And the last step is to set it up so that it updates and draws the
clouds in your game loop.
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.
So again, you’re going to extend
pygame.sprite.Sprite and use an image.
To extend it, you’re also going to set up the
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.
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.
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.
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
100 off to the right of the screen, and then this is anywhere from the top to the bottom of the screen. Okay.
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.
So, this is the
.update() method you’re creating for the
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
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.
ADDCLOUD will be equal to
pygame.USEREVENT—how could we make it unique? Well, let’s make it
pygame.time, setting a timer.
This timer is going to pull the trigger on
ADDCLOUD, and how about every second? So,
Then, you need to do your grouping. Okay. So here you have
enemies. Let’s add
clouds, and that is also a
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.
So, if the event pops up—
elif event.type == ADDCLOUD,
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
clouds, use that
.add() method to add a
new_cloud. Ope, not
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
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.
(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.
You create a
new_cloud right here, in this event, if this
ADDCLOUD event appears. Again, that should happen every second, right?
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—looks good. Okay.
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.
.update() is in the wrong spot, right? It needs to be back here.
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
.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.
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 ofclouds
andenemies` 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.
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—
I’m still having issues with the speed of the enemies and clouds. I fixed the player but the enemies and clouds are just streaks across the screen. Any way to fix it?(:
Hi harrisonstewart2004, The next lesson covers the most common way to control the speed of the game and included in that the enemies. Adding a clock and setting the tick to a slower framerate should solve it.
Become a Member to join the conversation.
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?)