# Too slow for cycle in Pygame

I'm using Pygame for Python 2 and I have the following code:

self.radius = 100
self.light.fill((0, 0, 0, 0))
alphas = pygame.surfarray.pixels_alpha(self.light)
for x, col in enumerate(alphas):
for y, pixel in enumerate(col):
pixel = 255 - f.distance(pygame.Rect(x, y, 1, 1), pygame.Rect(self.radius, self.radius, 1, 1))


Basically this code creates a new surface, makes it transparent so that it doesn't interfere with the background, draws a circle on it, and then makes two nested for cycles, going through all of the pixels. The problem is, these fors are too slow. How can I improve their performance?

• Can you explain what those 2 for loops are doing? What is "f"? Why do you need to process every pixel? What are you trying to accomplish? Maybe you chose the wrong way to do it. – Candid Moon _Max_ Mar 1 '17 at 0:45
• I'm trying to make a light in the game. To do it, I'm making a circle, and using those for loops to change all of the pixels' alpha, depending on the distance from the source, so that the light power will become lower and lower until it won't exist anymore when very distant from the center. – altermetax Mar 1 '17 at 13:28
• Create a texture offline that has all the images representing the shades you need to have and use that instead. Maybe you don't need 256 levels, maybe 16 or 32 would be enough. – Vaillancourt Mar 1 '17 at 14:18

When you are trying to do it in loops - its complexity is $$\O(n m)\$$, so you are asking your processor to go through 1920 * 1080 items on 1 thread, for example, its a resolution. Which makes it 2073600 times of CPU cycles, which is quite long. When GPU would take them one by one in 320 threads (it depends on card model) or more. Plus python is very slow in comparison to C or C++, so writing game on it might be quite difficult. Though python is written in C, so maybe there are shaders in pygame - you should check this out.
Can't you use semi-transparent texture for that? Also, you can try to find better algorithm that is probably $$\O(nlog_2(m))\$$. I would also limit the amount of pixels to process to only area that pixels can be lit.