Using Pygame Sprite Class

How to use pygame sprite class

import pygame
from pygame.sprite import Sprite

class BadSprite(Sprite):
    def __init__(self, position):
        Sprite.__init__(self)
        self.image = pygame.load.image("image file.bmp").convert()
        self.rect = self.image.get_rect(topleft=position)

This is wrong. I see this to much.

        self.image = pygame.load.image("image file.bmp").convert()

First this is loading a new image everytime it called. This means you are creating another copy. Reading from hard drive. Storing it in memory.

You never want more than one copy of the same image. Images should always be reference. This can be handle with an image handler. I just going to show how to handle them with dicts. Then you just pass it to the sprite class. This will reference your image.

class GoodSprite(Sprite):
    def __init__(self, image, position):
        Sprite.__init__(self)
        self.image = image
        self.rect = self.image.get_rect(topleft=position)

Right way of doing it.

Example

import math
import pygame
import random
from statemachine import State
from pygame.sprite import Sprite, Group

class MySprite(Sprite):
    def __init__(self, image, position):
        Sprite.__init__(self)
        self.image = image
        self.rect = self.image.get_rect(topleft=position)

class Example(State):
    def __init__(self):
        self.create_images()
        self.sprites = Group()

        w, h = State.machine.rect.size
        for i in range(5):
            x = random.randint(50, w - 50)
            y = random.randint(50, h - 50)
            sprite = MySprite(self.images['wierd'], (x, y))
            # Add sprite to group
            sprite.add(self.sprites)

        for i in range(3):
            x = random.randint(50, w - 50)
            y = random.randint(50, h - 50)
            # Using same sprite class
            sprite = MySprite(self.images['triangle'], (x, y))
            # Add sprite to group
            sprite.add(self.sprites)


    def create_images(self):
        self.images = {}

        surface = pygame.Surface((40, 50), pygame.SRCALPHA)
        surface.fill((0, 0, 0, 0))
        rect = pygame.Rect(0, 0, 10, 40)
        surface.fill(pygame.Color('firebrick'), rect)
        rect.x = 30
        surface.fill(pygame.Color('firebrick'), rect)
        rect.x = 10
        rect.w = 20
        surface.fill(pygame.Color('dodgerblue'), rect)
        rect = pygame.Rect(15, 40, 10, 50)
        surface.fill(pygame.Color('lawngreen'), rect)
        self.images['wierd'] = surface

        surface = pygame.Surface((30, 30), pygame.SRCALPHA)
        points = (0, 0), (15, 30), (30, 0)
        pygame.draw.polygon(surface, pygame.Color("orange"), points)
        self.images['triangle'] = surface

    def on_draw(self, surface):
        surface.fill(pygame.Color('black'))
        self.sprites.draw(surface)

def main():
    pygame.init()
    # caption, width, height, center
    State.machine_setup("Sprite Example", 800, 600, True)
    State.machine.flip(Example())
    State.machine.mainloop()

if __name__ == '__main__':
    main()