pygame.display.update updates the entire screen

Viewed 1952

I am creating a multiplayer game with splitted screen.

I start by drawing the first player on the left-hand side (spaceship, fire bombs, stars in the background (scrolling at half speed) and finally the background), then I update the first part of the screen, for the first player. Then I do the same things for the second player, on the other part of the screen.

But most of the images overlap thoughout the two half-screens. (see image below)

So, basically I need to update one part of the screen using pygame.display.update(), then the other part.

But the command doesn’t work, and updates the entire screen. And everything overlaps.

I've tried the following:

pygame.display.update(Rect((pos, 0), size))

pygame.display.update(Rect((pos, 0, size[0], size[1])))

pygame.display.update((pos, 0, size[0], size[1]))

pygame.display.update(pos, 0, size[0], size[1])

pygame.display.update((pos, 0), size)

But all of these are doing exactly the same thing, and they don't work as expected.

Rendering

1 Answers

When you are using pygame.display.update() there are two kinds of an optional argument, single rect (which defaults to None) and a list of rects. If no argument is passed, it updates the entire surface area - like display.flip() does.

update(rectangle=None) -> None
update(rectangle_list) -> None

To update only specific elements, either create a list of these elements if you want to update the same group at the same time

background_rects = [star_rect, star_rect, star_rect, some_other_rect]
foreground_rects = [player_rect, enemy1_rect, enemy2_rect, bullet1_rect, bullet2_rect]
pygame.display.update(background_rects)
pygame.display.update(foreground_rects)

or call update(rect) multiple times with the individual elements:

pygame.display.update(star1_rect)
pygame.display.update(star2_rect)
pygame.display.update(star3_rect)
pygame.display.update(character_rect)
pygame.display.update(enemy_rect)

Link to the documentation: https://www.pygame.org/docs/ref/display.html#pygame.display.update

There seems to be some (probably unintended as there is nothing about it in the docs) difference between the handling of pygame 1.9.6 and the 2.0.0.dev branches - below is a MRE which works with 1.9.6, but not with the 2.0.0.dev10 version. In 1.9.6 the difference in updating the display is easily visible. I suggest you install the stable 1.9.6 version if you need this exact functionality!

In case others want to try their luck, here is the MRE with which I tested:

import pygame
import time    
screen = pygame.display.set_mode((720, 480)) 

rect = pygame.Rect((10, 50), (32, 32))  
image = pygame.Surface((32, 32)) 
image.fill((0,100,0))

rect2 = pygame.Rect((10, 10), (32, 32)) 
image2 = pygame.Surface((32, 32)) 
image2.fill((100,100,0))

i = 0
while True:
    i += 1
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            quit()
            
    screen.blit(image, rect)
    screen.blit(image2, rect2)
    rect.x += 1 # we update the position every cycle
    rect2.x += 1  # we update the position every cycle
    
    # but update the rect on screen at different times:
    if i < 10:
        pygame.display.update() # both
    elif i > 50 and i < 75:
        pygame.display.update(rect2) # only rect2 
    elif i >= 100:
        pygame.display.update(rect) # only rect

    time.sleep(0.1)
Related