PyGame for Game Development: Font and Sprites - Sprites (
Page 4 of 4 )
Sprites are simply images that exist in the context of your background. They can be players, pickups or whatever. It's possible to simply load regular images and use them instead. Either way, you end up with the same thing. However, sprites simplify this, especially in more complicated situations where you have various images on the screen, and provide an object-oriented approach to it all.
Let's create a sprite by the name of StickMan based on this image:

We simply need to subclass pygame.sprite.Sprite, setting the image and the proper rectangle as an attribute. Then, we can blit it on to the screen:
import pygame
import sys
# Subclass pygame.sprite.Sprite
class StickMan(pygame.sprite.Sprite):
def __init__(self, position):
# Call pygame.sprite.Sprite.__init__ to do some internal
work
pygame.sprite.Sprite.__init__(self)
# Load the stickMan
self.image = pygame.image.load('stickMan.gif').convert()
# Create a rectangle
self.rect = self.image.get_rect()
# Position the rectangle
self.rect.x = position[0]
self.rect.y = position[1]
pygame.init()
screen = pygame.display.set_mode((256, 256))
pygame.display.set_caption('Sprite Example')
screen.fill((159, 182, 205))
# Create a StickMan sprite
character = StickMan((screen.get_rect().x, screen.get_rect().y))
# Blit the sprite
screen.blit(character.image, character.rect)
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
The sprite is rendered, but what if we want to move the sprite when a user presses a key? This requires waiting for the user to press a key, moving the sprite and erasing its old location. Let's extend our application to do this:
import pygame
import sys
class StickMan(pygame.sprite.Sprite):
def __init__(self, position):
pygame.sprite.Sprite.__init__(self)
# Save a copy of the screen's rectangle
self.screen = pygame.display.get_surface().get_rect()
# Create a variable to store the previous position of the
sprite
self.old = (0, 0, 0, 0)
self.image = pygame.image.load('stickMan.gif').convert()
self.rect = self.image.get_rect()
self.rect.x = position[0]
self.rect.y = position[1]
def update(self, amount):
# Make a copy of the current rectangle for use in erasing
self.old = self.rect
# Move the rectangle by the specified amount
self.rect = self.rect.move(amount)
# Check to see if we are off the screen
if self.rect.x < 0:
self.rect.x = 0
elif self.rect.x > (self.screen.width - self.rect.width):
self.rect.x = self.screen.width - self.rect.width
if self.rect.y < 0:
self.rect.y = 0
elif self.rect.y > (self.screen.height - self.rect.height):
self.rect.y = self.screen.height - self.rect.height
pygame.init()
screen = pygame.display.set_mode((256, 256))
pygame.display.set_caption('Sprite Example')
screen.fill((159, 182, 205))
character = StickMan((screen.get_rect().x, screen.get_rect().y))
screen.blit(character.image, character.rect)
# Create a Surface the size of our character
blank = pygame.Surface((character.rect.width, character.rect.height))
blank.fill((159, 182, 205))
pygame.display.update()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
# Check for movement
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
character.update([-10, 0])
elif event.key == pygame.K_UP:
character.update([0, -10])
elif event.key == pygame.K_RIGHT:
character.update([10, 0])
elif event.key == pygame.K_DOWN:
character.update([0, 10])
# Erase the old position by putting our blank Surface on it
screen.blit(blank, character.old)
# Draw the new position
screen.blit(character.image, character.rect)
# Update ONLY the modified areas of the screen
pygame.display.update([character.old, character.rect])
The first change in the StickMan class is the addition of screen. This is simply a copy of the screen's rectangle and is used to check whether the sprite has gone off the screen. We also add old, which is also a rectangle. When the sprite is updated, we store its old rectangle here so that our program knows what to erase. The update method simply moves the sprite and checks to see if it has gone partially off the screen. If it has, then it's bumped back on to the screen.
Further down, we define blank, a Surface object that is blitted over the old position of the character sprite each time the sprite moves. We then check for keyboard input, moving the sprite ten pixels in the appropriate direction if the user has pressed one of the arrow keys. This is done by calling the update method described above. Next, we erase the old position by blitting blank over it, and we draw the new position. Finally, we make a call to update. However, note that we supply a list as an argument. The list contains character's old and new positions. By doing this, we tell PyGame only to update those areas of the screen. If we were to update the whole screen, then PyGame would have to redraw everything. This simply wastes resources since we have no need to update the entire screen when only two things have changed.