Creating Sprites
In this lesson, you’ll create the player as a sprite. Here’s how you use Sprite
objects with the current game to define the player. Insert this code after line 18:
16# Define constants for the screen width and height
17SCREEN_WIDTH = 800
18SCREEN_HEIGHT = 600
19
20# Define a Player object by extending pygame.sprite.Sprite
21# The surface drawn on the screen is now an attribute of 'player'
22class Player(pygame.sprite.Sprite):
23 def __init__(self):
24 super(Player, self).__init__()
25 self.surf = pygame.Surface((75, 25))
26 self.surf.fill((255, 255, 255))
27 self.rect = self.surf.get_rect()
28
29# Initalize pygame
30pygame.init()
You need to remove lines 59 to 72, which included creating the previous surf
object and displaying it. Those lines will be replaced with displaying the new player sprite. You also will be changing the background screen to be black. Here are the all the changes you will make during this lesson:
1# Import the pygame module
2import pygame
3
4# Import pygame.locals for easier access to key coordinates
5# Updated to conform to flake8 and black standards
6from pygame.locals import (
7 K_UP,
8 K_DOWN,
9 K_LEFT,
10 K_RIGHT,
11 K_ESCAPE,
12 KEYDOWN,
13 QUIT,
14)
15
16# Define constants for the screen width and height
17SCREEN_WIDTH = 800
18SCREEN_HEIGHT = 600
19
20# Define a Player object by extending pygame.sprite.Sprite
21# The surface drawn on the screen is now an attribute of 'player'
22class Player(pygame.sprite.Sprite):
23 def __init__(self):
24 super(Player, self).__init__()
25 self.surf = pygame.Surface((75, 25))
26 self.surf.fill((255, 255, 255))
27 self.rect = self.surf.get_rect()
28
29# Initialize pygame
30pygame.init()
31
32# Create the screen object
33# The size is determined by the constant SCREEN_WIDTH and SCREEN_HEIGHT
34screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))
35
36# Instantiate player. Right now, this is just a rectangle.
37player = Player()
38
39# Variable to keep the main loop running
40running = True
41
42# Main loop
43while running:
44 # Look at every event in the queue
45 for event in pygame.event.get():
46 # Did the user hit a key?
47 if event.type == KEYDOWN:
48 # Was it the Escape key? If so, stop the loop.
49 if event.key == K_ESCAPE:
50 running = False
51 # Did the user click the window close button? If so, stop the loop.
52 elif event.type == QUIT:
53 running = False
54
55 # Fill the screen with black
56 screen.fill((0, 0, 0))
57
58 # Draw the player on the screen
59 screen.blit(player.surf, player.rect)
60
61 # Update the display
62 pygame.display.flip()
For more information about the Sprite
class from the pygame
documentation, and additional information on sprites and using inheritance with super()
, check out the following resources:
Sprite
class frompygame
documentation- Sprites article on Wikipedia
- Supercharge Your Classes With Python super()
For more information about the RGB color model, check out the following resources:
00:00 Welcome to Section 3. In this lesson, you’re going to start creating some sprites. I’m going to take you back a little bit, though, to think about the goals of the game.
00:07 You’re going to create a player object that avoids incoming obstacles. It’s going to start on the left side of the screen, and then obstacles are going to randomly appear on the right and move left in a straight line. The player is going to be able to move up, down, right, and left and avoid those obstacles.
00:24 We’ve got to have it so that the player doesn’t move off the screen. And then the game ends when the player is hit by an obstacle or when the user closes the window.
00:33
What I want to focus on for sprites is that there’s going to be a lot of obstacles. Not only is there going to be a player on the screen, but all these obstacles coming at the player. And for that, you’re going to use sprites. A sprite is a 2D representation of something on the screen. It could be something as simple as this rectangle, like out of the game Pong, to something much more advanced—still 2-dimensional, like you’ve seen in many video games. And pygame
provides a Sprite
class.
01:01 If you haven’t studied much about object-oriented programming yet, I’ll include links to some other resources here on Real Python, but this’ll be a good introduction, in general, about object-oriented programming. Video games are a perfect way to practice using objects.
01:16
So, what are those advantages of it being a class? You’re going to be able to create multiple instances, meaning multiple objects. Instead of having to repeat lots of code, you’ll be able to create multiple instances of the same object by using this reusable Sprite
class.
01:36
The Sprite
class has nice built-in methods that are going to help you with your programming also, and they’re going to be reusable because they come with every single Sprite
. And then that class can be extended to customize and allow you to create new methods that are on top of that, and you’re going to explore that in your code also.
01:55 I’ve mentioned RGB color a couple of times now. Computers represent everything as numbers, and RGB is a color model that converts colors into numbers that the computer can then process.
02:05 RGB has three different color channels—red, green, and blue, equaling the RGB. The values per channel for each of these go from 0—being no level—to full level, full blast of 255.
02:24
And all the colors that are represented are some combination of those three numbers, then. Like, black would be (0, 0, 0)
—no level of any of the colors.
02:36
White would be full blast on all three colors—(255, 255, 255)
, mixing together to create white. And then something in the middle, like this cool purple color that I created. You can see here, the red and the blue creating the majority of the purple color are much higher than the green. How did I create that color? Well, I did a Google search because I needed to convert from RGB to hexadecimal for this slide program, and I found if I search “RGB to Hex” in Google, it provided this really cool color picker. And down at the bottom, you can see here that it provides an RGB value as you slide around the slider and pick a color. Pretty handy. Okay, I think that’s enough color theory.
03:18 Let’s create that player. A couple of quick things. I want to swap some code around in here. I think it might be good to have this whole top section be not only for importing and setting up those local constants that you’re going to use, but also—this is a set of constants that you’re going to use, and then we’re going to create the classes, so this initializing should happen below that. So go ahead and swap these.
03:45
Get rid of that extra line. Okay. On line 20, you’re going to create the player. The Player
class, if you will.
03:54
You’re going to do that by extending pygame.sprite
, the class Sprite
. Again, notice the difference there: a lowercase s
sprite
, and a capitalized class Sprite
there.
04:14
Okay. So here we go. class Player
—again, capital P
—is coming from sprite
, using the class of Sprite
.
04:23
That’s what it’s based upon and what you’re extending from. So, you’re going to set up an .__init__()
using double underscore (__
)—also known as dunder init—of itself.
04:32
And you’re going to use this handy feature that allows you to use a lot of the methods from the Sprite
class—and that is super()
.
04:40
It’s going to inherit a lot of those features, so here you’re going to take Player
, self
, and then you’re going to .__init__()
.
04:46
I’m going to include links to another article here on Real Python that discusses using super()
with classes in object-oriented programming, if you need to learn more about it. Okay, so now you’re going to set up the Surface
for self
—for this Player
.
05:01
That’s going to use pygame
—again you use Surface
. And in this case, again, give it a tuple, the size. This one’s going to be 75
by 25
, so width and height in pixels. So, it’s sort of a rectangle again, 3 by 1. And right here, you’re going to go ahead and fill it with a color, and we’re going to change the color scheme up a little bit.
05:20 I know we had white as a background before—we’re going to change it to black here in a moment. So, the fill here is going to be white, so your object on the screen will be white, the background will be black.
05:29
We’ll need to change that. And then we need to find the rectangle for it. To do that, you use the method .get_rect()
—get the rectangle from Surface
. Okay.
05:39
Then you’re initializing pygame
, creating the screen
object—again, using the SCREEN_WIDTH
and SCREEN_HEIGHT
. Then here’s your loop. Down here, you’re going to change this to be black, and black is (0, 0, 0)
. Okay. That’s line 54. We’re going to add a couple of things, though.
05:55
Before starting the game loop and using this variable for the main loop running
, you need to create a player. Sometimes this is called instantiating—that’s the term we’ll use here. At line 36, instantiate the player, and for the moment it’s going to just be a rectangle, but this will get more interesting as we go.
06:15
So, player
will be an instance of the class that you created called Player
. Great. So now, how do you draw player
onto the screen? So, that’s 36, 37. Down here, after we change the screen—.fill()
—you had created this Surface
and you’d passed it a tuple.
06:31
So, a lot of stuff—we’re going to modify it. Okay. Before you get to .flip()
here, I’m going to go ahead and clean this up a little bit. I’m going to remove the previous Surface
stuff.
06:41
I’m going to get rid of an extra line here on line 51. Okay. Just tightening that up a little bit. Okay. 55, 56—you’re filling the screen with black. 58, you’re going to draw the player on the screen. Now, it looks very similar—you’re going to use .blit()
. And it’s still the same screen
that you created before, but instead of surf
it’s player.surf
, right? He’s at .surf
. Oops, now I’ve got two.
07:07 And then here, we’ll start out with a tuple. Again, we’ll just throw it in here at half the width and half the height. And I’ll have you change that in a minute.
07:16 We’ll talk about how we’re going to use that rectangle feature, which is very, very useful. Okay. And the last step—so, that’s line 58. Here at line 61, this is where you’re updating the display—which isn’t going to change, I’m just going to change the comments on it.
07:30
Draw the player on the screen, doing the .blit()
, right? And then here, display
.
07:36
Go ahead and save. Okay. Now, run your code—sky_dodge.py
. And there you can see the screen is now black, and you have a single player
object, which is this Surface
, if you will. Great! That worked perfect.
07:50
So, what do you think would happen if you changed here at line 59, that instead of it blitting at the SCREEN_WIDTH
at half, the SCREEN_HEIGHT
half, that you took the actual rectangle that you were pulling out? Again, player
—remember you created a rectangle for it? That was up here. Again, it’s part of the class. Okay. Where will it show up?
08:13
What is this default location for the rectangle? I don’t know, let’s try it out! Again, down here in the terminal, running python sky_dodge.py
.
08:20
Okay. That puts it here in the upper-left corner, so the default for the player
rectangle location is going to be over here in this upper-left corner. And that’s okay! Again, you might remember we said that the game is going to have the player on the left, and objects coming in from the right. So, that’s the next step.
08:38 Let’s get this player moving. To accomplish that, you’ll start adding user input.
Become a Member to join the conversation.
the1howie on Oct. 31, 2024
Hi Chris, why do we need to send parameters to super()? Would it not suffice to use the parameterless super()? Thanks.