PyGame Basics
Game object - sprites
In the old days where speed is essential in games, we have to be judicious with how may images we use and their loading time for a game.
Images are all placed together in one big image containing the seperate images required for a section of the game, called sprites. That way, the game only need to load the image once, and the different segments are displayed seperately depending on game play.
Now that we have our game loop, let's make our game object oriented to make it easier to extend.
First we create our ball object.
class Ball(pygame.sprite.Sprite):
"""Bounce a ball around the screen."""
def __init__(self):
pygame.sprite.Sprite.__init__(self) # call Sprite intializer
self.screen = pygame.display.get_surface()
self.image = pygame.image.load("ball.png")
self.rect = self.image.get_rect()
self.speed = [2, 2]
def update(self):
"""move the ball"""
self._move()
def _move(self):
"""move the ball across the screen, reverse speed at the ends"""
self.rect = self.rect.move(self.speed)
if self.rect.left < 0 or self.rect.right > WIDTH:
self.speed[0] = -self.speed[0]
if self.rect.top < 0 or self.rect.bottom > HEIGHT:
self.speed[1] = -self.speed[1]
We create our ball object and inherited the sprite object and all it's preset functions. It is just a wrapper function that will allow us to utilise it as a game object easily.
Ball object
To utilise our ball object, we create a Ball instance and add it to pygame's sprite stack:
class Game():
def __init__(self):
pygame.init() # initialise pygame libraries
self.size = WIDTH, HEIGHT
self.display = pygame.display.set_mode(self.size)
self.disp_surf = self.init_display()
self.running = True if self.disp_surf else False
self.font = pygame.font.Font(pygame.font.get_default_font(), 36)
self.ball = Ball()
self.allsprites = pygame.sprite.RenderPlain((self.ball))
return
Rendering sprites
Because ball is a sprite object, we can just update it's settings, and let pygame take care of the drawing of the sprite.
Note the order in which the images are drawn, or in this case transferred onto the screen, matters.
def render(self):
'''Render surface'''
# background
self.disp_surf.fill(BLACK)
# draw text
text = "Bouncing Ball"
self.draw_text(text, GREEN, (int(WIDTH / 2), int(HEIGHT / 2)))
# Blit everything to screen
self.display.blit(self.disp_surf, (0,0))
# draw ball
self.allsprites.update()
self.allsprites.draw(self.display)
# update display
pygame.display.flip()
return
Mouse Pointer
Let's ramp up our little game, by adding a hand as a mouse pointer.
Get a hand image, make it about 50x50 px.
def init_display(self):
pygame.display.set_caption('Bouncing Ball')
pygame.mouse.set_visible(0)
# Create surface
disp_surf = pygame.Surface(self.size)
return disp_surf.convert()
Add create our mouse object.
class Hand(pygame.sprite.Sprite):
"""moves a hand icon on the screen, following the mouse"""
def __init__(self):
pygame.sprite.Sprite.__init__(self) # call Sprite initializer
self.image = pygame.image.load("hand.png")
self.rect = self.image.get_rect()
def update(self):
"""move the fist based on the mouse position"""
pos = pygame.mouse.get_pos()
self.rect.center = pos
And add to our sprite stack.
class Game():
def __init__(self):
pygame.init() # initialise pygame libraries
self.size = WIDTH, HEIGHT
self.display = pygame.display.set_mode(self.size)
self.disp_surf = self.init_display()
self.running = True if self.disp_surf else False
self.font = pygame.font.Font(pygame.font.get_default_font(), 36)
self.ball = Ball()
self.hand = Hand()
self.allsprites = pygame.sprite.RenderPlain((self.ball, self.hand))
Test it out and play with it. 😀