using colliderect in an array of random coordinates

Question:

Right now, my game blits all the images in random positions correctly and also gets the rect of the images correctly, but I can´t figure out how to use colliderect to make sure the images don´t overlap. How could it work for my code?

Also I´m trying to make the first text fade out and I don´t know why it doesn´t work for me.

Here is the code:

class GAME1:
    def __init__(self, next_scene):
        self.background = pygame.Surface(size)
        
        # Create an array of images with their rect
        self.images = []
        self.rects = []
        self.imagenes1_array = ['autobus.png','coche.png','barco.png','autobus2.png','grua.png','bici.png']
        for i in self.imagenes1_array:
            # We divide in variables so we can then get the rect of the whole Img (i2)
            i2 = pygame.image.load(i)
            self.images.append(i2)
            s = pygame.Surface(i2.get_size())
            r = s.get_rect()
            
            # Trying to use colliderect so it doesnt overlap
            if pygame.Rect.colliderect(r,r) == True:
                x = random.randint(300,1000)
                y = random.randint(200,700)
            
                self.rects.append(r)
        

    def start(self, gamestate):
        self.gamestate = gamestate

        for rect in self.rects:
            # Give random coordinates (we limit the dimensions (x,y))
            x = random.randint(300,1000)
            y = random.randint(200,700)
            rect.x = x
            rect.y = y

    def draw(self,screen):
        self.background = pygame.Surface(size)
        font = pygame.font.SysFont("comicsansms",70)
        
        # First half (Show image to remember)
        text1 = font.render('¡A recordar!',True, PURPLE)
        text1_1 = text1.copy()
        # This surface is used to adjust the alpha of the txt_surf.
        alpha_surf = pygame.Surface(text1_1.get_size(), pygame.SRCALPHA)
        alpha = 255 # The current alpha value of the surface.

        if alpha > 0:
            alpha = max(alpha-4, 0)
            text1_1 = text1.copy()
            alpha_surf.fill((255, 255, 255, alpha))
            text1_1.blit(alpha_surf, (0,0), special_flags = pygame.BLEND_RGBA_MULT)
        
        screen.blit(text1_1, (600,50))
       

        # Second half (Show all similar images)
        text2 = font.render('¿Cuál era el dibujo?',True, PURPLE)
        #screen.blit(text2, (500,50))
        
        for i in range(len(self.images)):
            #colliding = pygame.Rect.collidelistall(self.rects)
            screen.blit(self.images[i], (self.rects[i].x, self.rects[i].y))
    
    def update(self, events, dt):
        for event in events:
            if event.type == pygame.MOUSEBUTTONDOWN:
                for rect in self.rects:
                    if rect.collidepoint(event.pos):
                        print('works!')

Asked By: Diegunski12

||

Answers:

Use collidelist() to test test if one rectangle in a list intersects:

for i in self.imagenes1_array:
    s = pygame.image.load(i)
    self.images.append(s)
    r = s.get_rect()
    
    position_set = False 
    while not position_set:
        r.x = random.randint(300,1000)
        r.y = random.randint(200,700)    
        
        margin = 10
        rl = [rect.inflate(margin*2, margin*2) for rect in self.rects]
        if len(self.rects) == 0 or r.collidelist(rl) < 0:
            self.rects.append(r)
            position_set = True

See the minimal example, that uses the algorithm to generate random not overlapping rectangles:

import pygame
import random

pygame.init()
window = pygame.display.set_mode((400, 400))
clock = pygame.time.Clock()

def new_recs(rects):
    rects.clear()
    for _ in range(10):
        r = pygame.Rect(0, 0, random.randint(30, 40), random.randint(30, 50))
        
        position_set = False 
        while not position_set:
            r.x = random.randint(10, 340)
            r.y = random.randint(10, 340)    
            
            margin = 10
            rl = [rect.inflate(margin*2, margin*2) for rect in rects]
            if len(rects) == 0 or r.collidelist(rl) < 0:
                rects.append(r)
                position_set = True
rects = []
new_recs(rects)

run = True
while run:
    clock.tick(60)
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        elif event.type == pygame.KEYDOWN:
            new_recs(rects)          

    window.fill(0)
    for r in rects:
        pygame.draw.rect(window, (255, 0, 0), r)
    pygame.display.flip()

pygame.quit()
exit()
Answered By: Rabbid76
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.