Nikos Korovesis
Nikos Korovesis

Reputation: 394

Pygame program is running slow. Why?

I'm making sort of a Tamagotchi project on pygame, and at this early stage the program is running really slow. Do you have any hints as to why? Also, is there any way to speed it up?

This is my code so far:

import pygame
import time

pygame.init()
def draw_grid(grid):
    for i in range(0,len(grid)):
        for j in range(0,len(grid[i])):
            area = (j*10, i*10, 8, 8)
            if grid[i][j] == 0:
                fill = True
                color = 0,0,0
            elif grid[i][j] == 1:
                fill = False
                color = 0,0,0
            elif grid[i][j] == 2:
                fill = False
                color = 255,0,0
            square = pygame.draw.rect(screen, color, area, fill)

def make_empty_grid(width,height):
    grid = []
    for i in range(height):
        zeros = []
        for j in range(width):
            zeros.append(0)
        grid.append(zeros)
    return grid

def draw_item(item, x, y):
    for i in range(0, len(item)):
        for j in range(0, len(item[i])):
            grid[i + x][j + y] = item[i][j]

size = width, height = 600, 400
#rects = 
screen = pygame.display.set_mode(size)

running = True

#beige background
background = 213, 230, 172 
black = 0, 0, 0
red = 255, 0, 0

image1 = [
         [1,0,1,1,1,0,1],
         [0,1,0,0,0,1,0],
         [1,0,1,0,1,0,1],
         [1,0,0,0,0,0,1],
         [1,0,1,1,1,0,1],
         [1,0,0,0,0,0,1],
         [0,1,1,1,1,1,0]
         ]

image2 = [
         [1,0,1,1,1,0,1],
         [0,1,0,0,0,1,0],
         [1,0,1,0,1,0,1],
         [1,0,0,0,0,0,1],
         [1,0,0,1,0,0,1],
         [1,0,0,0,0,0,1],
         [0,1,1,1,1,1,0]
         ]

bars = [
       [2,2,2,2,2,2,2,2,2,2],
       [2,2,2,2,2,2,2,2,2,2]
       ]


tamaPosX = 27
tamaPosY = 8

curImage = image1
while running:
    # Get the window input
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_LEFT:
                tamaPosX -= 1
            if event.key == pygame.K_RIGHT:
                tamaPosX += 1
            if event.key == pygame.K_UP:
                tamaPosY -= 1
            if event.key == pygame.K_DOWN:
                tamaPosY += 1

    screen.fill(background)

    grid = make_empty_grid(width,height)

    if curImage is image1:
        curImage = image2
    else:
        curImage = image1

    draw_item(curImage, tamaPosY, tamaPosX)
    draw_item(bars, 35, 1)

    draw_grid(grid)

    pygame.display.flip()

Upvotes: 0

Views: 2459

Answers (2)

cmd
cmd

Reputation: 5830

You don't need to recalculate your empty grid each time. Store it in a surface as a "background image", then you can just blit it to the screen each time instead of clearing it, recalculating it, and then blitting it. Also when drawing items just draw items not the whole screen. You can use display.update and pass the items rects old and new since they are the only things that are changing.

You should also store your items as surfaces or sprites instead of recalculating them every time through the loop too.

Upvotes: 1

JBGreen
JBGreen

Reputation: 544

You could try profiling the code:

https://docs.python.org/2/library/profile.html

Mostly I expect it's because you have many nested for loops. Some of them seem unnecessary. Nested for loops are not fast in Python.

Your width and height are constant, you don't really need to create a whole new empty grid at each tick.

import copy

empty_grid = [[0] * width for _ in range(height)]
def make_empty_grid():
    return copy.deepcopy(empty_grid)

Instead of copying your items into the grid, then drawing the grid, why not have draw_item call pygame.draw directly? As it is you are iterating over the entire grid twice - once to put the items in the grid, once the draw the grid.

Edit: That's maybe a bad suggestion, I see that even the grid elements with value 0 are drawn a different colour than the background. I'm not sure what you're doing.

Upvotes: 1

Related Questions