Search code examples
listrandompygamerect

Cannot figure out how to choose a random image AND its rect from a list in Pygame


hoping to get some help on an issue within Pygame. I'm trying to fill a grid with random encounters, shown by their image (mob, trap, loot etc) however I can't figure out how to list both an image AND its Rect in a list.

I have managed to display and fill the grid with random images when I press a button however I need the Rects of these images so I can detect collisions with my player_img. When I pre-set the Rect of one encounter and chose that from a list of 'itself' I could print 'collision' when this Rect collided with my player_img Rect. An image will always have the same Rect for a specific square of the grid however it obviously defeats the purpose of 'random encounters' if the grid is always filled in the same fashion.

This is the code that chooses a random image and displays it within a square of the grid, however this image has no Rect.

display_surface.blit(random.choice(square2_list), (416, 592))

This piece of code chooses an image from a list of just itself so that I then have the Rect for that specific encounter, hence can check collisions. However as I said before, I would like to have these encounters appear randomly on the grid, not in the same position each time.

display_surface.blit(random.choice(square2_list), mob1Rect)

My list of encounters for square 2 of the grid looks like this:

square2_list = [mob1_img, event_img, blank_img, trap_img, loot_img]

I tried formatting the list like this after defining each Rect but was just met with errors:

square2_list = [(mob1_img, mob1Rect), (event_img, eventRect), (blank_img, blankRect), (trap_img, trapRect), (loot_img, lootRect)]

I hope I have made some kind of sense and If anyone can provide any assistence it would be greatly appreciated!


Solution

  • If you have a list of tuples, random.choice will return a tuple. A list of tuples can be created using the built-in zip function:

    images = [mob1_img, event_img, blank_img, trap_img, loot_img]
    rects = [mob1Rect, eventRect, blankRect, trapRect, lootRect]
    square2_list = zip(images, rects)
    
    random_image, random_rect = random.choice(square2_list)
    display_surface.blit(random_image, random_rect)  
    

    A tuple can also be unzipped using the asterisk (*) operator:

    display_surface.blit(*random.choice(zip(images, rects)))
    

    Alternatively, you can also select a random element by its index:

    random_index = random.randrange(len(images))
    display_surface.blit(images[random_index], rects[random_index])