Pygame FG (7) – Framerate speed 2

With this code we can make our frame rate go very faster using the Group class and blits.

The structure of the code

Changes in the update function

The images are updated all at once every 180 frames… to make them not go too fast. They are updated at once with the Group class, to save frame rate. Also, to clear the screen we do not color all of it, but just the rectangles occupied by the images of the three sprites with the function hide_sprites below:

The hide_sprites function

This will blit the rectangles to delete the previous images of the sprites, all at once

def hide_sprites():
    screen.blits(blit_sequence=((dsprites["pwalk"].cover, pwalkpos),
        (dsprites["prun"].cover, prunpos),
        (dsprites["pjump"].cover, pjumppos)))

You can see I do not used blit, but blits, for more surfaces at once.

Alternative to hide_sprites (to refresh all the page)

If you want you can use screen.fil((0,0,0)) into the update method of sprite in alternative to screen.blits of the three Surface object that covers just the sprites… maybe you could lose some framerate, I am not so sure, I will check this in another post

    def update(self):
        "This animate the sprite"
        self.countframe += 1
        # the more is the number the more the animation is slow
        if self.countframe == 200:
            print(clock.get_fps())
            # restart the counter
            self.countframe = 0
            # The new animation image is flipped after 4 frames
            self.current += 1
            # check if the images of the animations are ended
            if self.current >= len(self.sprites):
                # if so it goes back to the initial image
                self.current = 0
            # and now it shows the next image or the initial one
            self.image = self.sprites[self.current]
            # Use hide sprites for higher performances
            # hide_sprites()
            screen.fill((0, 0, 255))
            g.draw(screen)

The whole code

# Pygame first gamet - tutorial 4
import pygame as pg
import sys
from glob import glob


class Sprite(pg.sprite.Sprite):
    def __init__(self, pw, ph, folder, action):
        "loads all the image that starts with 'action' in position pw, ph"
        super().__init__()

        self.pw = pw
        self.ph = ph
        self.current = 0
        self.countframe = 0
        self.folder = folder
        self.action = action
        self.order_images()
        self.position_sprite()

    def order_images(self):
        "take the list of images (load_images()) and order them"
        lst = self.load_images()
        img = [f for f in lst if len(f) == len(lst[0])]
        img.extend([f for f in lst if len(f) != len(lst[0])])
        self.sprites = [pg.image.load(x) for x in img]
        self.image = self.sprites[self.current]
        self.size = self.image.get_size()
        self.cover = pg.Surface(self.size)
        self.cover.fill((0, 128, 0))

    def load_images(self):
        "Load images that starts with action"
        lst = glob(f"{self.folder}\\{self.action}*")
        return lst

    def position_sprite(self):
        self.rect = self.image.get_rect()
        self.rect.topleft = [self.pw, self.ph]

    def update(self):
        "This animate the sprite"
        self.countframe += 1
        # the more is the number the more the animation is slow
        if self.countframe == 180:
            print(clock.get_fps())
            # restart the counter
            self.countframe = 0
            # The new animation image is flipped after 4 frames
            self.current += 1
            # check if the images of the animations are ended
            if self.current >= len(self.sprites):
                # if so it goes back to the initial image
                self.current = 0
            # and now it shows the next image or the initial one
            self.image = self.sprites[self.current]
            hide_sprites()
            g.draw(screen)


def window(title, w=400, h=400):
    "Create the screen + title and the clock object for the frame"
    screen = pg.display.set_mode((w, h))
    pg.display.set_caption(title)
    return screen, pg.time.Clock()


def quitbutton():
    "Look for the key events"
    global loop
    for event in pg.event.get():
        if event.type == pg.QUIT:
            loop = 0


def clear_screen():
    pass
    # screen.fill((0, 64, 128))


def refresh_screen():
    pg.display.flip()
    clock.tick()


def group_all_sprites(thegroup, sprites):
    "Iterate all the sprites in the dsprites"
    for s in sprites:
        thegroup.add(sprites[s])


def hide_sprites():
    screen.blits(blit_sequence=((dsprites["pwalk"].cover, pwalkpos),
        (dsprites["prun"].cover, prunpos),
        (dsprites["pjump"].cover, pjumppos)))


def sprites_init():
    global pwalkpos, prunpos, pjumppos

    pwalkpos = 100, 60
    prunpos = 150, 60
    pjumppos = 200, 60
    dsprites = {
        "pwalk" : Sprite(pwalkpos[0], pwalkpos[1], "cat", "Walk"),
        "prun": Sprite(prunpos[0], prunpos[1], "cat", "Run"),
        "pjump": Sprite(pjumppos[0], pjumppos[1], "dog", "Jump"),
    }
    return dsprites


def game_init():
    global g, fonts, screen, clock, loop, dsprites
    pg.init()
    dsprites = sprites_init()
    g = pg.sprite.Group()
    group_all_sprites(g, dsprites)
    # fonts = create_fonts([32, 16, 14, 8])
    screen, clock = window("Game", w=500, h=500)
    screen.fill((0, 128, 0))
    loop = 1


def update_screen():
    "The while loop updates"
    quitbutton()
    g.update()
    refresh_screen()


game_init()
while loop:
    update_screen()

pg.quit()
sys.exit()

 

Published by pythonprogramming

Started with basic on the spectrum, loved javascript in the 90ies and python in the 2000, now I am back with python, still making some javascript stuff when needed.