1
votes

So in my pygame game I finally managed to get rid of the errors but the collision still doesn't work. I want player to collide with the squares. Here's the code for the sprites.

class Player(pygame.sprite.Sprite):

    def __init__(self, x, y, image):
        pygame.sprite.Sprite.__init__(self)
        self.image = pygame.image.load('Tri.png')
        self.image = pygame.transform.scale (self.image, (int(width/16), int(width/15)))
        self.rect = self.image.get_rect()
        self.width, self.height = self.image.get_size()
        self.rect.x = x
        self.rect.y = y


    def update(self):
        mx, my = pygame.mouse.get_pos()
        self.rect.x = mx - self.width/2
        self.rect.y = (height * 0.8)

        if self.rect.x <= 0 - self.width/2 + 10:    
            self.rect.x += 10
        if self.rect.x + self.width >= width:
            self.rect.x = width - self.width

        self.rect.topleft = self.rect.x, self.rect.y


    def draw(self, screen):

        if bgColour == black:
            self.image = pygame.image.load('Tri2.png')
            self.image = pygame.transform.scale (self.image, (int(width/16), int(width/15)))
        else:
            self.image = pygame.image.load('Tri.png')
            self.image = pygame.transform.scale (self.image, (int(width/16), int(width/15)))
        self.width, self.height = self.image.get_size()

        gameDisplay.blit(self.image, self.rect)
        self.rect.topleft = self.rect.x, self.rect.y




#Class for the squares to dodge
class Square(pygame.sprite.Sprite):
    def __init__(self, box_x, box_y, box_width, box_height,colour, box_speed, box_border, BC):
        pygame.sprite.Sprite.__init__(self)
        self.box_x = box_x
        self.box_y = box_y
        self.box_width = box_width
        self.box_height = box_width
        self.colour = colour
        self.box_speed = box_speed
        self.box_border = box_border
        self.BC = BC

        self.image = pygame.Surface((self.box_width, self.box_width))
        self.image.fill(self.BC)
        draw = pygame.draw.rect(self.image, self.BC, [self.box_x - self.box_border/2, self.box_y - self.box_border/2, self.box_width + self.box_border, self.box_height + self.box_border])
        box = pygame.draw.rect(gameDisplay, self.colour, [self.box_x, self.box_y, self.box_width, self.box_height])
        self.rect = self.image.get_rect()


    def Fall(self):

        if self.box_y < height:
            self.box_y += box_speed
        elif self.box_y > height + 100:
            del square[0]

        border = pygame.draw.rect(gameDisplay, self.BC, [self.box_x - self.box_border/2, self.box_y - self.box_border/2, self.box_width + self.box_border, self.box_height + self.box_border])
        box = pygame.draw.rect(gameDisplay, self.colour, [self.box_x, self.box_y, self.box_width, self.box_height])
        self.rect.topleft = self.box_x, self.box_y

Here's the gameLoop code.

def game_loop():

    mx, my = pygame.mouse.get_pos()
    x = mx
    y = (height * 0.8)
    player = Player(x, y, 'Tri.png')

    box_width = int(width/15)
    blocksGroup = pygame.sprite.Group()

    if round(box_width/5) % 10 == 0:
        box_border = round(box_width/5)
    else:
        box_border = round(box_width/5 + 1)

    box_x = random.randrange(0, width)
    box_y =  0 - box_width

    min_gap = box_width/4

    global box_speed

    box_col = False
    box_start = random.randrange(0, width)
    delay = 0

    global square
    square = []



    move_speed = 10


    #level variables
    box_speed = 6
    max_gap = box_width/2
    score = 0
    bgColourList = [white, black, white, white]
    global bgColour
    bgColour = bgColourList[0]
    Blist = [red, green, black, pink, white]
    BC = Blist[0]
    Clist = [red, black, black, pink, white]
    box_colour = red
    text_colour = black
    z = 60
    level = 0
    delayBG = 0
    levelChange = 400
    gameExit = False

    #while still inside of game

    while not gameExit:

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                gameExit = True
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_q:
                    gameExit = True

        gameDisplay.fill(bgColour)
        player.update()
        player.draw(gameDisplay)
        #dodgers.checkCollision()




        if score % levelChange == 0:
            delayBG = 120
            z = 120

        if delayBG == 0:
            bgColour = bgColourList[level]
            BC = Blist[level]
            box_colour = Clist[level]


        if delay == 0:
            score += 1
            delay += 3
            if delayBG == 0:
                level += 1
                box_speed += 1
                max_gap -= 1



        #print(m_x)
        if z == 0:            
            new = random.randint(0, width)
            square.append(Square(new, box_y, box_width, box_width , box_colour, box_speed, box_border, BC))
            steven = Square(new, box_y, box_width, box_width , box_colour, box_speed, box_border, BC)
            blocksGroup.add(steven)
            print(player, blocksGroup)
            z = random.randint(int(min_gap), int(max_gap))
            last = new
            lasty = box_y

        for i in square: 
            i.Fall()
            """tris.remove(i)
            i.checkCollision(tris)
            tris.add(i)"""






        pygame.draw.rect(gameDisplay, bgColour, [0,0, width, int(height/23)])
        message_to_screen(str(score), text_colour, -height/2 + 15, 0)
        collide = pygame.sprite.spritecollide(player, blocksGroup, False)
        if collide:
            gameExit = True
            print("Dead")



        delayBG -= 1
        z -= 1

        delay -= 1
        pygame.display.update()
        clock.tick(FPS)
game_loop()
pygame.quit()
quit()
1
Welcome to Stack Overflow. Please try to reduce the code to the absolute minimum, remove everything that is not relevant for the issue, but make sure that the code is executable and the error can still be reproduced. And explain the desired behavior and the errors in detail. - skrx

1 Answers

0
votes

The problem is that you create two different Square instances every time you spawn a new square. You append the first one to the square list and add the second to the blocksGroup sprite group. Then you update only the sprites in the square list but not in the blocksGroup, but these are used for the collision detection.

To fix the bug, get rid of the square list and only use the blocksGroup.

You can also give the Square class an update method which allows you to update all contained sprites by calling blocksGroup.update(). And to draw the sprites just call blocksGroup.draw(gameDisplay).