AttributeError: 'Group' object has no attribute 'collide' Pygame

Question:

I’m creating a basic simulation in pygame and my object (an amoeba represented by a green square on the screen) has two methods. My update method is running fine, but the collide method is giving my an attribute error. By the way, since I have added many amoebae to the screen, I apply the methods to my amoebas group.

import pygame
import random
import time

from pygame.locals import (
    QUIT
)

pygame.init()

SCREEN_WIDTH = 500
SCREEN_HEIGHT = 500

screen = pygame.display.set_mode([500, 500])

amoebas = pygame.sprite.Group()
all_sprites = pygame.sprite.Group()

class Amoeba(pygame.sprite.Sprite):
    def __init__(self, maturingSpeed, x, y):
        super(Amoeba, self).__init__()
        self.surf = pygame.Surface((10,10))
        self.surf.fill((0, maturingSpeed, 0))
        self.rect = self.surf.get_rect(
            center=(
                x,
                y,
            )
        )
        self.speed = 2
        self.age = 1
        self.maturingSpeed = maturingSpeed    

    def update(self):
        if self.rect.left <= 0:
            direction = 1
        elif self.rect.right >= SCREEN_WIDTH:
            direction = 2
        elif self.rect.top <= 0:
            direction = 3
        elif self.rect.bottom >= SCREEN_HEIGHT:
            direction = 4
        else:
            direction = random.randint(1, 4)
            
        if direction == 1:
            self.rect.move_ip(self.speed, 0)
        elif direction == 2:
            self.rect.move_ip(-self.speed, 0)
        elif direction == 3:
            self.rect.move_ip(0, self.speed)
        elif direction == 4:
            self.rect.move_ip(0, -self.speed)

    def collide(self):  
        posList = [(amoeba.rect.left, amoeba.rect.top) for amoeba in list]
        length = len(posList)
        print(posList)
        print(length)
        for i in range(length):
          y = posList[i]
          for h in range(length):
              if posList[h] == y and h != i:
                  locationX = posList[i][0]
                  locationY = posList[i][1]
                  new_amoeba = Amoeba(150, locationX, locationY)
                  amoebas.add(new_amoeba)
                  all_sprites.add(new_amoeba)
              else:
                  pass

screen.fill((255, 255, 255))

for i in range(100):
        new_amoeba = Amoeba(150, random.randint(0, SCREEN_WIDTH), random.randint(0, SCREEN_HEIGHT))
        amoebas.add(new_amoeba)
        all_sprites.add(new_amoeba)

while True:
    time.sleep(0.000001)
    screen.fill((255, 255, 255))
    
    for event in pygame.event.get():
        if event.type == QUIT:
            break
    
    amoebas.update()
    amoebas.collide()

    for entity in all_sprites:
        screen.blit(entity.surf, entity.rect)
        
    pygame.display.flip()
    

pygame.quit()

I’m very new to OOP and this is my first complex program written in it, so any advice is welcome!
Also, I know my question is pretty much identical to this one: Python is throwing AttributeError: 'Group' object has no attribute 'blitme' but unfortuantely I could not understand the answer so any help with that would also be welcome.

Asked By: AtomProgrammer

||

Answers:

pygame.sprite.Group.draw() and pygame.sprite.Group.update() are methods which are provided by pygame.sprite.Group.

The latter delegates to the update method of the contained pygame.sprite.Sprites — you have to implement the method. See pygame.sprite.Group.update():

Calls the update() method on all Sprites in the Group. […]

The former uses the image and rect attributes of the contained pygame.sprite.Sprites to draw the objects — you have to ensure that the pygame.sprite.Sprites have the required attributes. See pygame.sprite.Group.draw():

Draws the contained Sprites to the Surface argument. This uses the Sprite.image attribute for the source surface, and Sprite.rect. […]

Therefore you can call amoebas.update() and amoebas.draw(screen), but you can’t call amoebas.collide().

You must call the collide methods in a loop:

for amoeba in amoebas;
    amoeba.collide()
Answered By: Rabbid76