How do you assign values faster in PyGame

Viewed 46

Hey I have created a small program in pygame to just create noise (white and black pixels) and repeatedly replace over itself with more noise:

import pygame
import random

WIDTH = 1920
HIGHT = 1080

pygame.init()
screen = pygame.display.set_mode((WIDTH,HIGHT))
pygame.display.set_caption("Noise.py")

def update():
   for y in range(HIGHT):
      for x in range (WIDTH):
         pygame.event.get()
         num = random.randint(0,1)
         color = (0  ,0  ,0  ) if num == 1 else (255,255,255)
         screen.set_at((x, y), color)
      pygame.display.update()

def main ():
   running = True
   while running:

      for event in pygame.event.get():
         if event.type == pygame.QUIT:
            running = False
      
      update()

main()

The program works tough it is too slow to create the effect that I wanted (run at 30 to 60 fps). The only way I can for now make if a bit faster is by dropping the resolution though I would prefer not to.

Is there a way to assign individual pixel color in pygame faster? or even mabe a better way of going about this?

1 Answers

What is actually expensive here is that you are calling pygame.display.update() very frequently, probably more than you can even notice. Instead, you should limit that call to, say, at most 60 times per seconds. To do so, just keep track of the last time you called it in your update function and, if it's more than 1/60s ago, call pygame.display.update() and update the last time you called it.

Also, calling set_at directly on the screen object is somewhat wasteful, because it doesn't just set a value in a big array, it also triggers some flushing. So a better way to do that would be either to create a temporary Surface buffer in which you write the pixels, and then you blit it on the screen just before updating, or you can access it directly with a PixelArray, which provides a list-like API to a Surface, but then you have to manually "close" it (that is, flush it).

Related