bayman21
bayman21

Reputation: 59

How do I save a section of a pygame screen and blit it to another location?

I am making a program with a graph that scrolls and I just need to move a section of the screen.

If I do something like this:

import pygame

screen = pygame.display.set_mode((300, 300))

sub = screen.subsurface((0,0,20,20))

screen.blit(sub, (30,40))

pygame.display.update()

It gives the error message: pygame.error: Surfaces must not be locked during blit

I assume it means the child is locked to its parent surface or something but how else could I go about doing this?

Upvotes: 1

Views: 564

Answers (2)

Rabbid76
Rabbid76

Reputation: 210968

screen.subsurface creates a surface, which reference to the original surface. From documentation:

Returns a new Surface that shares its pixels with its new parent.

To avoid undefined behaviour, the surfaces get locked. You've to .copy the surface, before you can .blit it to its source:

sub = screen.subsurface((0,0,20,20)).copy()
screen.blit(sub, (30,40))

Upvotes: 2

sloth
sloth

Reputation: 101072

Just don't draw to the screen surface directly. Create a Surface for each part of your game/UI, and blit each of those to the screen.

import pygame

def main():
    pygame.init()
    screen = pygame.display.set_mode((640, 480))

    # create two parts: a left part and a right part
    left_screen = pygame.Surface((400, 480))
    left_screen.fill((100, 0, 0))

    right_screen = pygame.Surface((240, 480))
    right_screen.fill((200, 200, 0))

    x = 100
    while True:
        events = pygame.event.get()
        for e in events:
            if e.type == pygame.QUIT:
                return

        # don't draw to the screen surface directly
        # draw stuff either on the left_screen or right_screen
        x += 1
        left_screen.fill(((x / 10) % 255, 0, 0))

        # then just blit both parts to the screen surface
        screen.blit(left_screen, (0, 0))
        screen.blit(right_screen, (400, 0))

        pygame.display.flip()

if __name__ == '__main__':
    main()

Upvotes: 1

Related Questions