How to make drawing individual pixels efficient in pygame?

hbblue :

Im making a crappy off-brand of paint in pygame.

One problem I have run into is that it is hilariously inefficient.

With only a 500 by 500 picture it runs at like 14 FPS.

The picture is stored as a list with like this:

pic = [[white,white,white],[white,white,white],[white,white,white]]

and the code that displays it is:

def display(pic):
    for y in range(500):
        for x in range(500):
            screen.set_at((x,y),pic[y][x]) 

how would i make this work and be efficient.

Kingsley :

I'm surprised you were able to get 14 FPS.

I'm sure it would be more efficient to create a PyGame Surface, then use graphic-primitive functions to modify the surface. There's a whole bunch of line and shape functions - see the pygame docs. (Note: at the time of writing, https://pygame.org has been down for a few days, so the link goes to the internet archive cache of it).

import pygame

# Window size
WINDOW_WIDTH    = 500
WINDOW_HEIGHT   = 500
WINDOW_SURFACE  = pygame.HWSURFACE|pygame.DOUBLEBUF|pygame.RESIZABLE

DARK_BLUE = (   3,   5,  54 )
WHITE     = ( 255, 255, 255 )

### initialisation
pygame.init()
window = pygame.display.set_mode( ( WINDOW_WIDTH, WINDOW_HEIGHT ), WINDOW_SURFACE )
pygame.display.set_caption("Bad Mouse Paint")

# Drawing on
canvas = pygame.Surface( ( WINDOW_WIDTH, WINDOW_HEIGHT ) )
canvas.fill( DARK_BLUE )

### Main Loop
mouse_down = False
clock = pygame.time.Clock()
done = False
while not done:

    # Handle user-input
    for event in pygame.event.get():
        if ( event.type == pygame.QUIT ):
            done = True
        elif ( event.type == pygame.MOUSEBUTTONDOWN ):
            mouse_down = True
        elif ( event.type == pygame.MOUSEBUTTONUP ):
            mouse_down = False

    # Mouse Movement
    if ( mouse_down ):
        mouse_pos = pygame.mouse.get_pos()
        pygame.draw.circle( canvas, WHITE, mouse_pos, 5, 0 )

    # Update the window, but not more than 60fps
    window.blit( canvas, ( 0, 0 ) )
    pygame.display.flip()

    # Clamp FPS
    clock.tick_busy_loop(60)


pygame.quit()

The example above uses the surface canvas to accumulate the drawing operations. It is written to the screen in a single blit() operations.

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=387148&siteId=1