By using this module
to its full potential, you can easily manage and draw your game
objects. The sprite classes are very optimized, so it's likely your
game will run faster with the sprite module than without.
This module not only
allow you to draw the images, but also do many operations on them
like animations, grouping etc.. Also it provides collision detection
power to your game development process. You need not write the whole
collision detection code by yourself.
The sprite module
provides two classes:
-
Sprite
-
Group
The Sprite class is
designed to be a base class for all your game objects while the Group
class is container for the sprites. For example if you are creating a
menu for your game, all the buttons in the menu are sprites. And the
menu itself is a sprite group.
In this post let’s
see an example of sprite class:
Let’s animate the
ship in our previous example with some water ripples around it. Like
in following video
In the above video
what we see our ship is not moving right now but having the water
around it is moving. To create this animation we’ll use the sprite
module of pygame. Till now our ship was only an image but now we’ll
turn it into a game object. To do so we’ll have to create a class
Ship extending class pygame.sprite.Sprite as follows:
class
Ship(pygame.sprite.Sprite):
def
__init__(self):
super(Ship,
self).__init__()
In sprite class we
need to assign the image of sprite as “self.image =
image_to_assign”
now, we have to
display a ship, and a set of water ripple frames around it. That
means our main image is ship and we have to blit the water ripples
along with the ship.
So we’ll assign
self.image=ship and create an array for animation frames as
“self.animFrames” and store the ripple images in this array. In
this way we have what we need to create our animation.
Now we have to
display this animation. Here, if we display all the ripple frames at
a time, we can’t call it animation; we want to animate it show
frame by frame. That means we’ll need a timer and an index to store
current frame. And also a position to display our sprite and its
animation. So let’s modify our sprite class:
class
Ship(pygame.sprite.Sprite):
index = 0
def
__init__(self, texture, animFrames, x=0, y=0, width=1, height=1):
super(Ship,
self).__init__()
self.image =
texture
self.animFrames = animFrames
self.currentFrame = self.animFrames[0]
self.x = x
self.y = y
self.rect =
self.image.get_rect()
self.width =
self.rect.width
self.height
= self.rect.height
Here we are
providing texture of ship and animation frames as well as the rect
details to sprite from parameters.
To keep the
animation updating let’s write the update method:
def update(self):
if
self.isAnimating:
self.animate()
and to implement the
animation functionality, let’s add the following methods:
def
startAnimation(self):
self.isAnimating = True
def
animate(self):
self.index
+= 1
if
self.index >= len(self.animFrames):
self.index = 0
self.currentFrame = self.animFrames[self.index]
time.sleep(0.01)
def
stopAnimation(self):
self.isAnimating = False
Here the time.sleep
provides us the delay of displaying the next animation frame. Now we
have done everything our update method is properly updating the
sprite according to animation but to display the animation on the
screen, we’ll have to use the draw method of sprite class:
def draw(self,
surface):
surface.blit(self.currentFrame, (self.x-self.width,
self.y-self.height*0.2))
surface.blit(self.image, ((self.x), (self.y)))
Here we are drawing
the animation frame first and on top of the animation frame we are
drawing the ship. Because we want the water ripple under the ship.
Now we have
successfully created the Ship class we only have to instantiate it on
our previous window and run the code
so as usual first
load images:
We already have
loaded the ship. We only need to load animation frames
shipAnimFrames_str =
["ripple0.png", "ripple1.png", "ripple2.png",
"ripple3.png", "ripple4.png"]
shipAnimFrames = []
i = 0
while i <
len(shipAnimFrames_str):
shipAnimFrames.append((pygame.image.load(shipAnimFrames_str[i])))
i += 1
ShipSprite =
Ship(ship, shipAnimFrames, winWidth*0.45, winHeight*0.75)
ShipSprite.startAnimation()
and inside the game
loop
call the update()
and draw() of ShipSprite
as
ShipSprite.update()
ShipSprite.draw()
save the code and
run it to get output like above.
The complete code for the above is as follows:
Similarly you can
use the background image also as sprite rather than a surface. By
making it sprite you can convert this whole code into an endless
travel for your ship as shown in following video.
You can get the
complete source code for this endless travel in the following
repo.
In the coming post let’s see what more we can do with sprites like
collision detection, grouping, other animations etc.. so stay tuned.