using colliderect in an array of random coordinates

Viewed 78

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!')

1 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()
Related