pythonpygamecollision

Why does spritecillide work incorrectly in pygame


So, i do not understand, why does it allways print "collided", but it was not collided. I have two classes: Car and Beam. I want to detect rhe cllision betwen Car and a group of Beams. I made the function is_collision to make this, but it wors incorrectly and always return collided. Please help me. Thank you.

import pygame as pg
import cv2
import random
pg.init()


display_width = 1000
display_height = 1000

BLUE = 47, 158, 189
RED = 255, 0, 0

display = pg.display.set_mode((display_width, display_height))
pg.display.set_caption("Cars Evolution")

icon = pg.image.load("icon.png")
pg.display.set_icon(icon)

clock = pg.time.Clock()

car_url = "car_img.png"
car_direction = 0  # car_direction from -1 to 1


beam_url = "beam_img.png"
beam_x = 200
beam_y = 200
beam_width = 20
beam_height = 160

total_level_width = 5000
total_level_height = 5000


class Beam(pg.sprite.Sprite):
    def __init__(self, input_beam_url, input_beam_x, input_beam_y):
        pg.sprite.Sprite.__init__(self)
        self.x = input_beam_x
        self.y = input_beam_y
        self.image = pg.image.load(input_beam_url)
        self.width = 20
        self.height = 160
        self.rect = self.image.get_rect()

    def draw_beam(self):
        self.x -= car.delta_x
        self.y -= car.delta_y
        display.blit(self.image, (self.x, self.y))
        pg.draw.rect(display, RED, pg.Rect(self.x, self.y, self.width, self.height), 2)


class Car(pg.sprite.Sprite):
    def __init__(self, input_car_url):
        pg.sprite.Sprite.__init__(self)
        self.image = pg.image.load(input_car_url)
        self.x = display_width / 2
        self.y = display_height / 3
        self.width = 46
        self.height = 89
        self.rect = self.image.get_rect()
        self.delta_x = 0
        self.delta_y = 0

    def draw_car(self):
        display.blit(self.image, (self.x, self.y))
        pg.draw.rect(display, RED, pg.Rect(self.x, self.y, self.width, self.height), 2)

    def move_car(self, vertical_ind, horizontal_ind, speed):
        self.delta_x = horizontal_ind * speed
        self.delta_y = vertical_ind * speed

    def is_collision(self, input_beams_list):
        collide_beam_list = pg.sprite.spritecollide(self, input_beams_list, False)
        if collide_beam_list:
            print("collided")
            return True


def close_game():
    game = False
    pg.quit()
    quit()


beams_amount = 5
beams_list = pg.sprite.Group()

random.seed(57)

for beam in range(beams_amount):
    beam_to_add = Beam(beam_url, random.randint(beam_width, display_width - beam_width), random.randint(beam_height, display_height - beam_height))
    beams_list.add(beam_to_add)


car = Car(car_url)

def run_game():
    game = True

    while game:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                close_game()

        display.fill(BLUE)

        # Drawing

        beams_list.update()

        car.draw_car()
        car.move_car(0.5, 0, 5)

        for sprite_object in beams_list.sprites():
            sprite_object.draw_beam()

        car.is_collision(beams_list)
            #close_game()

        pg.display.update()

        clock.tick(60)


run_game() 


Solution

  • You have to update the .rect attributes. pygame.sprite.spritecollide use the .rect attributes of the pygame.Sprite objects to detect the collision:

    class Beam(pg.sprite.Sprite):
        # [...]
    
        def draw_beam(self):
            self.x -= car.delta_x
            self.y -= car.delta_y
    
            self.rect.topleft = (self.x, self.y) # <---- ADD
    
            display.blit(self.image, (self.x, self.y))
            pg.draw.rect(display, RED, pg.Rect(self.x, self.y, self.width, self.height), 2)
    
    class Car(pg.sprite.Sprite):
        # [...]
    
        def draw_car(self):
    
            self.rect.topleft = (self.x, self.y) # <---- ADD
    
            display.blit(self.image, (self.x, self.y))
            pg.draw.rect(display, RED, pg.Rect(self.x, self.y, self.width, self.height), 2)