I create a pygame.PixelArray object uses the pygame main screen window surface object ( returned by the method pygame.display.set_mode() ), and when I assign color to each item of the pygame.PixelArray object in a loop it throws the error pygame.PixelArray IndexError: invalid index. This article will tell you how to fix it.
1. How To Reproduce The Error pygame.PixelArray IndexError: invalid index.
- Create the pygame main window surface object using the pygame.display.set_mode() method.
MAIN_WINDOW_SURFACE = pygame.display.set_mode((1000, 1000), pygame.RESIZABLE)
- Create the pygame.PixelArray object with the above pygame main window surface object like below.
pixel_array_obj = pygame.PixelArray(MAIN_WINDOW_SURFACE)
- Create a list to save each pixel coordinate, each list item is another list that contains only 2 numbers( pixel X coordinate & pixel Y coordinate).
def build_random_number_pair_list(): ret_list = [] # the main window surface width is 1000. x_number_list = list(range(0, 1000)) # the main window surface height is 1000. y_number_list = list(range(0, 1000)) x_number_list_len = len(x_number_list) for i in range(x_number_list_len): x = random.choice(x_number_list) y = random.choice(y_number_list) pair_list = [x, y] ret_list.append(pair_list) return ret_list
- Loop in the returned list above, and assign a color to each of the pixels in the pygame.PixelArray object.
pixels_list = build_random_number_pair_list() for pixel in pixels_list: color = get_random_color() pixel_array_obj[pixel[0], pixel[1]] = color
- The error occurred at the assigning color line, below is the error message.
pixel_array_obj[pixel[0], pixel[1]] = color ...... IndexError: invalid index
2. How To Fix The Error pygame.PixelArray IndexError: invalid index.
- The reason for this error is the pygame.PixelArray object’s shape is smaller than the pixel coordinate that is saved in the pixel coordinate list object ( pixels_list ).
- We can get the pygame.PixelArray object’s shape using the below code.
print('pixel_array_obj.shape = ', pixel_array_obj.shape) # below is the above code output in the console. pixel_array_obj.shape = (1000, 963)
- The pygame.PixelArray object’s shape is decided by the main window surface object’s shape, we can see this using the below source code.
print('MAIN_WINDOW_SURFACE.get_size = ', MAIN_WINDOW_SURFACE.get_size()) print('MAIN_WINDOW_SURFACE.get_width = ', MAIN_WINDOW_SURFACE.get_width()) print('MAIN_WINDOW_SURFACE.get_height = ', MAIN_WINDOW_SURFACE.get_height()) # below is the above source code output. MAIN_WINDOW_SURFACE.get_size = (1000, 963) MAIN_WINDOW_SURFACE.get_width = 1000 MAIN_WINDOW_SURFACE.get_height = 963
- So we should change the code in the build_random_number_pair_list() method like below.
def build_random_number_pair_list(): ret_list = [] x_number_list = list(range(0, MAIN_WINDOW_SURFACE.get_width())) y_number_list = list(range(0, MAIN_WINDOW_SURFACE.get_height())) x_number_list_len = len(x_number_list) for i in range(x_number_list_len): x = random.choice(x_number_list) y = random.choice(y_number_list) pair_list = [x, y] ret_list.append(pair_list) return ret_list
- Then the pixel’s coordinate x, y value will be limited to the main window screen surface pixel number range, and then the error will not happen again.
- I also found that if you do not pass the argument pygame.RESIZABLE to the method pygame.display.set_mode(), then the main window surface object’s width & height value will be the same as the first window size tuple argument.
# when you do not pass the pygame.RESIZABLE argument. MAIN_WINDOW_SURFACE = pygame.display.set_mode((1000, 1000)) # the pygame main window's size will like below. MAIN_WINDOW_SURFACE.get_size() = (1000, 1000)
- If you pass pygame.FULLSCREEN to create the pygame main window, the returned window size should be your computer’s screen resolution.
pygame.display.set_mode((1000, 1000), pygame.FULLSCREEN) MAIN_WINDOW_SURFACE.get_size() = (1280, 1024)
- Below are the window pixel shapes that are generated by other window modes.
MAIN_WINDOW_SURFACE = pygame.display.set_mode((1000, 1000), pygame.NOFRAME) MAIN_WINDOW_SURFACE.get_size() = (1000, 1000) **************************************************************************************** MAIN_WINDOW_SURFACE = pygame.display.set_mode((1000, 1000), pygame.DOUBLEBUF) MAIN_WINDOW_SURFACE.get_size() = (1000, 1000) **************************************************************************************** MAIN_WINDOW_SURFACE = pygame.display.set_mode((1000, 1000), pygame.HWSURFACE) MAIN_WINDOW_SURFACE.get_size() = (1000, 1000) **************************************************************************************** MAIN_WINDOW_SURFACE = pygame.display.set_mode((1000, 1000), pygame.SCALED) MAIN_WINDOW_SURFACE.get_size() = (1000, 1000) **************************************************************************************** MAIN_WINDOW_SURFACE = pygame.display.set_mode((1000, 1000), pygame.SHOWN) MAIN_WINDOW_SURFACE.get_size() = (1000, 1000) **************************************************************************************** MAIN_WINDOW_SURFACE = pygame.display.set_mode((1000, 1000), pygame.HIDDEN) MAIN_WINDOW_SURFACE.get_size() = (1000, 1000)