1

another weird situation with pygame I guess. I want to creat a drop class which will be the parent class of statusdrops(health,armor etc...) and weapondrops(increase damage, switch weapon etc...). I need that because the two children will have almost the same functions but for some reason I failed with the inheritance, I checked the python documentation and still not sure what is going on.

Here is the first attempt using the 3 classes that gave me this error: 'StatusDrops' object has no attribute 'rect'. But I used the exact same method for my aliens and worked fine so far

Drop parent class

class Drops(pygame.sprite.Sprite):
def __init__(self, dw, dh, x, y):
    super().__init__()

    self.display_width = dw
    self.display_height = dh
    self.posx = x
    self.posy = y
    self.speedx = 3
    self.speedy = 5
    self.pickedUp = 0

#Set Rotation
def setRotation(self):
    self.rotationx = self.rotationy = random.randrange(-1, 1)
    if self.rotationx == 0:
        self.setRotation()

#Set both side's rotation chance
def setRotationChance(self):
    self.rotationxChance = random.randrange(1, 151)
    self.rotationyChance = random.randrange(1, 151)

#Change rotation side
def changeRotation(self):
    #Side steps rotation
    if self.rotationxChance == 1:
        if self.rotationx == 1:
            self.rotationx = -1
        else:
            self.rotationx = 1

    #Forward steps rotation
    if self.rotationyChance == 1:
        if self.rotationy == 1:
            self.rotationy = -1
        else:
            self.rotationy = 1

#Movement           
def move(self):
    self.rect.x += (self.rotationx * self.speedx)
    self.rect.y += (self.rotationy * self.speedy)

#Kill if picked up or went of the boundaries
def checkStatus(self):
    if self.pickedUp == 1:
        self.kill()

    if self.rect.x > self.display_width or self.width < 0:
        self.kill()
    elif self.rect.y < 0 or self.rect.y > self.display_height:
        self.kill()

StatusDrop child class (I didn't proceed to the weaponDrop because of the error)

class StatusDrops(Drops):
def _init__(self, dw, dh, x, y):
    super().__init__(dw, dh, x, y)

    self.type = self.setType()
    self.setAttributes(self)
    self.rect = self.image.get_rect(center = (self.posx, self.posy))
    self.image.set_colorkey(YELLOW)

    self.setRotation()


def setType(self):
    x = 1#random.randrange(1, 5)
    return x

#Set attributes, what kind of status will upgrade(health, stamina, tenacity, nano shell)
def setAttributes(self):
    #Hero increase's stamina(max health)
    if self.type == 1:
        self.image = staminaIcon
        self.width = 28
        self.height = 23
    #Hero heal, max heal income = 30% of stamina
    elif self.type == 2:
        self.image = healIcon
        self.width = 28
        self.height = 23
    #hero increases resistance to slow and stun(lower duration) up to 30%
    elif self.type == 3:
        self.image = tenacityIcon
        self.width = 28
        self.height = 23
    #hero increases resistance to incoming damage(armor) up to 50%
    elif self.type == 4:
        self.image = nanoshellIcon
        self.width = 28
        self.height = 22

    self.image = staminaIcon
    self.width = 28
    self.height = 23

def update(self):       
    #Movement
    self.move()       
    #Call both sides rotation chances
    self.setRotationChance()
    self.changeRotation()
    #Check drop status
    self.checkStatus()

After that(I even replace the self with super() on the functions but still didn't work) in order to fix it I chose not to use a parent class and just create them like 2 different classes. That fixed the problem of the missing attribute rect but when I tried to spawn them (after the alien died) the .add() printed this error:

File "/home/marios/Documents/Programming - TEI/Python_Spyder/Graphics/Game/Star Guardian/Star_Guardian.py", line 1210, in game_Loop statusDrop = StatusDrops(display_width, display_height, (private.rect.x + (private.width / 2)), (private.rect.y + (private.height / 2)))

File "/usr/local/lib/python3.6/dist-packages/pygame/sprite.py", line 124, in init self.add(*groups)

File "/usr/local/lib/python3.6/dist-packages/pygame/sprite.py", line 142, in add self.add(*group)

TypeError: add() argument after * must be an iterable, not int

This is the new Status class that the rect error fixed

class StatusDrops(pygame.sprite.Sprite):
def _init__(self, dw, dh, x, y):
    super().__init__()

    self.display_width = dw
    self.display_height = dh
    self.posx = x
    self.posy = y
    self.speedx = 3
    self.speedy = 5
    self.pickedUp = 0
    self.type = self.setType()
    self.setAttributes(self)
    self.rect = self.image.get_rect(center = (self.posx, self.posy))
    self.image.set_colorkey(YELLOW)

    self.setRotation()


def setType(self):
    x = 1#random.randrange(1, 5)
    return x

#Set attributes, what kind of status will upgrade(health, stamina, tenacity, nano shell)
def setAttributes(self):
    #Hero increase's stamina(max health)
    if self.type == 1:
        self.image = staminaIcon
        self.width = 28
        self.height = 23
    #Hero heal, max heal income = 30% of stamina
    elif self.type == 2:
        self.image = healIcon
        self.width = 28
        self.height = 23
    #hero increases resistance to slow and stun(lower duration) up to 30%
    elif self.type == 3:
        self.image = tenacityIcon
        self.width = 28
        self.height = 23
    #hero increases resistance to incoming damage(armor) up to 50%
    elif self.type == 4:
        self.image = nanoshellIcon
        self.width = 28
        self.height = 22

    self.image = staminaIcon
    self.width = 28
    self.height = 23

def update(self):       
    #Movement
    self.move()       
    #Call both sides rotation chances
    self.setRotationChance()
    self.changeRotation()
    #Check drop status
    self.checkStatus()

#Set Rotation
def setRotation(self):
    self.rotationx = self.rotationy = random.randrange(-1, 1)
    if self.rotationx == 0:
        self.setRotation()

#Set both side's rotation chance
def setRotationChance(self):
    self.rotationxChance = random.randrange(1, 151)
    self.rotationyChance = random.randrange(1, 151)

#Change rotation side
def changeRotation(self):
    #Side steps rotation
    if self.rotationxChance == 1:
        if self.rotationx == 1:
            self.rotationx = -1
        else:
            self.rotationx = 1

    #Forward steps rotation
    if self.rotationyChance == 1:
        if self.rotationy == 1:
            self.rotationy = -1
        else:
            self.rotationy = 1

#Movement           
def move(self):
    self.rect.x += (self.rotationx * self.speedx)
    self.rect.y += (self.rotationy * self.speedy)

And here the .add() error appears(I used the same method for the missiles and alien spawn and worked)

all_sprites_list = pygame.sprite.Group()
status_drops_list = pygame.sprite.Group()

statusDrop = StatusDrops(display_width, display_height, (private.rect.x + (private.width / 2)), (private.rect.y + (private.height / 2)))
                all_sprites_list.add(statusDrop)
                status_drops_list.add(statusDrop)

Thank you for your time, if you need anymore just ask me!!!

M2kk
  • 79
  • 2
  • 10
  • 1
    You wrote `_init__` instead of `__init__` in the `StatusDrops` class. – sloth Nov 09 '18 at 06:32
  • Wow you are right, but what about the first problem? the inheritance I mean. Did I do something wrong? – M2kk Nov 09 '18 at 07:51
  • It's the same problem. Since `_init__` is never called (because it's spelled wrong), the line with `self.rect = self.image.get_rect....` is never run, thus `StatusDrops` has not `rect` attribute, hence the `'StatusDrops' object has no attribute 'rect'.` exception. – sloth Nov 09 '18 at 07:54

0 Answers0