3

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

D_00
  • 1,440
  • 2
  • 13
  • 32
  • 1
    Update takes an optional rect argument `pygame.display.update(rect_to_update)`. in the event nothing is passed, it updates everything. `update` should also generally only be called once at the end of the game loop. – TheLazyScripter Aug 13 '20 at 08:32
  • 1
    Does this answer your question? [How do I pass a rect into pygame.display.update() to update a specific area of the window?](https://stackoverflow.com/questions/48711791/how-do-i-pass-a-rect-into-pygame-display-update-to-update-a-specific-area-of-t) – Tomerikoo Aug 13 '20 at 08:46
  • Also related: https://stackoverflow.com/questions/29314987/difference-between-pygame-display-update-and-pygame-display-flip – Tomerikoo Aug 13 '20 at 08:52
  • **Sorry, I missed to say that I've tried to use Rect. On pygame 1.9.6 it works, but on pygame 2.0.0 it doesn't works. I'll "update" my question.** – D_00 Aug 13 '20 at 12:34

1 Answers1

3

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)
Cribber
  • 2,513
  • 2
  • 21
  • 60
  • I'll try to put some 1.9.6 code in 2.0.0 code because I need som pygame 2.0.0 skills: joystick updating, better speed and the flag `SCALED`... – D_00 Aug 14 '20 at 12:28
  • I'm sorry, but this solution didn't work until I upgraded `pygame` to 2.0.1. This issue was caused by a bug and not because I wasn't passing a `Rect` as an argument. I took a look at this question and I think I will delete the question, or add an answer related to the `pygame` bug fixes. – D_00 Apr 08 '21 at 08:48
  • But your answer works for other users who have the same problem as described in the answers whose question has been associated - so I will leave the post. – D_00 Apr 08 '21 at 08:52