Sprites
Sprites are probably one of the most important parts of using Pygame. They aren't strictly necessary, but they can make your code simpler (cool) and faster (awesome!).
Thepygame.sprite.Sprite
class is a base class which gives basic functionality for game objects. Some functionality it provides by default:
- Batch rectangular and circular collision detection
- Batch updates
- Batch drawing
Some general steps for using Sprites:
- Extend the
pygame.sprite.Sprite
class - Call the superclass's init method
- Create the
update
method - Assign the
rect
,image
, and optionally theradius
attributesrect
is used for drawing (position / size) and rectangular collision detectionimage
is used for drawing: it's a Surfaceradius
is used for circular collision detection
- Add instances of your subclass into Groups
So what is a Group? A Group (pygame.sprite.Group
) is an object which represents a collection of Sprites. You can use groups to update each sprite in the group at the same time, or to draw each sprite in the group at the same time.
Perhaps the coolest built-in functionality of Groups, however, is thepygame.sprite.groupcollide
function. This allows you to specify two groups, and determine if any sprite from the first group is colliding with any sprite in the second group. We can specify lots of things for this:
- The two groups we want to check (
group1
andgroup2
) dokill1
anddokill2
: if one of these is True, any colliding Sprites in the respective group are removed automatically. This means no more confusing list modifications!collided
: this is a function which takes two Sprites and tells if they're colliding - this means we can specify how to detect collisions between groups. Usepygame.sprite.collide_rect
,pygame.sprite.collide_circle
, or a custom collision function!
collidegroup
returns aSprite_Dict
object - this is a dictionary which maps Sprites fromgroup1
to all the Sprites ingroup2
that it was colliding with. This allows us to do any necessary cleanup code for the removed objects.
Here's a quick Sprite example using Dots:
class Dot(pygame.sprite.Sprite):
def __init__(self, x, y):
super(Dot, self).__init__()
self.radius = random.randint(5, 20)
self.x, self.y = x, y
self.xSpeed = random.randint(-10, 10)
self.ySpeed = random.randint(-10, 10)
self.rect = pygame.Rect(x - self.radius, y - self.radius,
2 * self.radius, 2 * self.radius)
self.image = pygame.Surface((2 * self.radius, 2 * self.radius),
pygame.SRCALPHA) # make it transparent
self.image = self.image.convert_alpha()
r = random.randint(0, 255)
g = random.randint(0, 255)
b = random.randint(0, 255)
pygame.draw.circle(self.image, (r, g, b),
(self.radius, self.radius), self.radius)
def getRect(self): # GET REKT
self.rect = pygame.Rect(self.x - self.radius, self.y - self.radius,
2 * self.radius, 2 * self.radius)
def update(self, screenWidth, screenHeight):
self.x += self.xSpeed
self.y += self.ySpeed
if self.x < 0:
self.x = screenWidth
elif self.x > screenWidth:
self. x = 0
if self.y < 0:
self.y = screenHeight
elif self.y > screenHeight:
self.y = 0
self.getRect()
pygame.init()
screen = pygame.display.set_mode((500, 500))
clock = pygame.time.Clock()
dots = pygame.sprite.Group()
playing = True
while playing:
clock.tick(50)
for event in pygame.event.get():
if event.type == pygame.MOUSEBUTTONDOWN:
d = Dot(*event.pos)
dots.add(d)
elif event.type == pygame.QUIT:
playing = False
dots.update(500, 500)
screen.fill((255, 255, 255))
dots.draw(screen)
pygame.display.flip()
pygame.quit()
Check out the Sprites reference here.