Home Boy
Home Boy

Reputation: 19

How do I blit a background only once in pygame?

I am making a platformer and I've run into a problem wwhen blitting the background. In my current code, the game loop draws the background on the game window every frame, which makes the game really laggy when I want to use any background that isn't just a solid color. My question is how do I blit the background only once (if it's possible) so that the game wouldn't slow down so much.

Here are some parts of my Game class that lead to blitting the image:

class Game:
    def __init__(self):
        pg.init()
        pg.mixer.init()
        self.bg = pg.image.load("background.jpg")
        self.screen = pg.display.set_mode((WIDTH, HEIGHT))
        pg.display.set_caption(TITLE)
        self.clock = pg.time.Clock()
        self.running = True
        self.font_name = pg.font.match_font(FONT_NAME)
        self.pillarhp = 100


    def new(self):
        self.run()

    def run(self):
        self.clock.tick(FPS)
        self.playing = True
        while self.playing:
            self.clock.tick(FPS)
            self.events()
            self.update()
            self.draw()


    def draw(self):
        now = pg.time.get_ticks()
        self.screen.blit(self.bg, [0, 0])
        self.screen.blit(self.island, [0,0])
        self.all_sprites.draw(self.screen)
        self.draw_text("Score: " + str(self.score), 20, BLACK, 40, 20)
        self.draw_text("Pillar HP: " + str(self.pillarhp), 20, BLACK, 40, 50)
        pg.display.flip()

Upvotes: 1

Views: 843

Answers (2)

Deux
Deux

Reputation: 21

This is relatively old but I found this to be working best , as explained in the pygame documentation https://www.pygame.org/docs/tut/tom_games2.html:

Blitting is one of the slowest operations in any game, so you need to be careful not to blit too much onto the screen in every frame. If you have a background image, and a ball flying around the screen, then you could blit the background and then the ball in every frame, which would cover up the ball's previous position and render the new ball, but this would be pretty slow. A better solution is to blit the background onto the area that the ball previously occupied, which can be found by the ball's previous rectangle, and then blitting the ball, so that you are only blitting two small areas.

Upvotes: 1

skrx
skrx

Reputation: 20438

Call the convert method of the background surface, e.g.

self.bg = pg.image.load("background.jpg").convert()

That will improve the performance.

For images with per-pixel transparency, you can use the convert_alpha method, but images which you convert with the convert method will be blitted much faster.

Upvotes: 1

Related Questions