Book Image

Instant Pygame for Python Game Development How-to

By : Ivan Idris
Book Image

Instant Pygame for Python Game Development How-to

By: Ivan Idris

Overview of this book

<p>Pygame is a library created to make multimedia software documenting easy to design. It adds functionality on top of the excellent SDL library. This allows you to create fully featured games and multimedia programs in the Python language. Pygame comes with functions and tools that will help you create a great user experience."Instant Pygame for Python Game Development How-to" is written in a concise and result-oriented format. Leading you through practical recipes, you'll find that this essential reference guide helps you to create visually appealing and thrilling games with a few clicks.This book starts with the basic instructions to install Pygame on different servers. It then goes into creating a sample game and explaining the features of drawing, animating, using fonts and Matplotlib with Pygame. The book then takes you through recipes to get access to some great sound and graphic effects. Giving you the steps to allow you to configure these games on Android and other networks, it ends with a walkthrough of the features of Sprites, OpenGL, and Simulation.</p>
Table of Contents (7 chapters)

Drawing sprites (Intermediate)


Sprite is a term from computer graphics meaning a two-dimensional visible object, that has been optimized for rendering. Pygame offers the Sprite class that deals with sprites. It can draw sprites on a Surface object. It also has collision functions. For complex games, we can group sprites together for easy management. Sprites are not thread safe, so you should take care when using multiple threads.

How to do it...

We will redo the animation demo, but this time with sprites and using Rect objects, which represent rectangles. A Rect object has left, top, width, and height attributes. We will use these and other attributes throughout the example. Also we will let the avatar spin when the mouse button is clicked. However, we will not care for now where we click exactly.

We will create a class that extends the Sprite class. Sprite classes have an update method which fires for each frame. All logic involving the movement of the sprite should be placed here.

  1. Constructor: First, we need to create the sprite and perform subclassing. All the initialization logic goes here. Further details for the functions can be found in the next section. We define an image, rectangle, and variables tracking the movement of the avatar:

    class Head(pygame.sprite.Sprite):
        def __init__(self):
            pygame.sprite.Sprite.__init__(self) 
            self.image, self.rect = load_image('head.jpg', -1)
            screen = pygame.display.get_surface()
            self.area = screen.get_rect()
            self.STEP = 9
            self.MARGIN = 12
            self.xstep = self.STEP 
            self.ystep = 0
            self.dizzy = 0
            self.direction = 'right'
  2. The update method: The update method calls helper methods that either cause the head to spin or move it in clockwise direction. The movement is achieved with this line:

    newpos = self.rect.move((self.xstep, self.ystep))
    

    The following line take care of the rotation:

    self.image = pygame.transform.rotate(self.original, self.degrees)
    

    Note

    You can find a short clip of the game on YouTube (https://www.youtube.com/watch?v=EFQlc_siPrI). A screenshot of the game is shown as follows:

    The complete code of the Sprite demo is listed as follows:

    import os, pygame
    from pygame.locals import *
    
    def load_image(name, colorkey=None):
        try:
            image = pygame.image.load(name)
        except pygame.error, message:
            print 'Cannot load image:', name
    
        image = image.convert()
    
        return image, image.get_rect()
    
    class Head(pygame.sprite.Sprite):
        def __init__(self):
            pygame.sprite.Sprite.__init__(self) 
            self.image, self.rect = load_image('head.jpg', -1)
            screen = pygame.display.get_surface()
            self.area = screen.get_rect()
            self.STEP = 9
            self.MARGIN = 12
            self.xstep = self.STEP 
            self.ystep = 0
            self.degrees = 0
            self.direction = 'right'
    
        def update(self):
            if self.degrees:
                self._spin()
            else:
                self._move()
    
        def _move(self):
            newpos = self.rect.move((self.xstep, self.ystep))
    
            if self.direction == 'right' and self.rect.right > self.area.right - self.MARGIN:
                self.xstep = 0
                self.ystep = self.STEP 
                self.direction = 'down'
    
            if self.direction == 'down' and self.rect.bottom > self.area.bottom - self.MARGIN:
                self.xstep = -self.STEP
                self.ystep = 0
                self.direction = 'left'
    
            if self.direction == 'left' and self.rect.left < self.area.left + self.MARGIN:
                self.xstep = 0
                self.ystep = -self.STEP
                self.direction = 'up'
    
            if self.direction == 'up' and self.rect.top < self.area.top + self.MARGIN:
                self.xstep = self.STEP
                self.ystep = 0
                self.direction = 'right'
    
            self.rect = newpos
    
        def _spin(self):
            center = self.rect.center
            self.degrees = self.degrees + 12
            if self.degrees >= 360:
                self.degrees = 0
                self.image = self.original
            else:
                self.image = pygame.transform.rotate(self.original, self.degrees)
            self.rect = self.image.get_rect(center=center)
    
        def hit(self):
            if not self.degrees:
                self.degrees = 1
                self.original = self.image
    
    
    def main():
        pygame.init()
        screen = pygame.display.set_mode((400, 400))
        pygame.display.set_caption('Sprite Demo')
    
        background = pygame.Surface(screen.get_size())
        background = background.convert()
        background.fill((250, 250, 250))
    
        if pygame.font:
            font = pygame.font.Font(None, 36)
            text = font.render("Hit the avatar!", 1, (0, 0, 200))
            textpos = text.get_rect(centerx = background.get_width()/2, centery = background.get_height()/2)
            background.blit(text, textpos)
    
        screen.blit(background, (0, 0))
        pygame.display.flip()
    
        clock = pygame.time.Clock()
        head = Head()
        sprite = pygame.sprite.RenderPlain(head)
    
        while True:
            clock.tick(60)
    
            for event in pygame.event.get():
                if event.type == QUIT:
                    return
                elif event.type == MOUSEBUTTONDOWN:
                   head.hit()
    
            sprite.update()
    
            screen.blit(background, (0, 0))
            sprite.draw(screen)
            pygame.display.flip()
    
    
    
    if __name__ == '__main__': 
       main()

How it works...

A more in-depth description of the various functions used in this demo is given as follows:

Function

Description

pygame.sprite.Sprite.__init__(self)

This creates sprites.

screen.get_rect()

This gets a Rect object.

pygame.display.get_surface()

This gets a Surface object.

self.rect.move((self.xstep, self.ystep))

This moves a rectangle given a x and y coordinate.

pygame.transform.rotate(self.original, self.degrees)

This rotates an image given a Surface object and angle in degrees. Positive values correspond with counter clockwise rotation, negative with clockwise rotation.

self.image.get_rect(center=center)

This gets the rectangle for the image given its center coordinates.

pygame.sprite.RenderPlain(head)

This renders the sprite.