I am currently working on a small RPG in Pygame to get used to object oriented coding.
When looking into how to auto-update a property I came across the following:
class P:
def __init__(self,x):
self.x = x
@property
def x(self):
return self.__x
@x.setter
def x(self, x):
if x < 0:
self.__x = 0
elif x > 1000:
self.__x = 1000
else:
self.__x = x
I tried applying it to my code but I get the following error:
File "weapons.py", line 13, in __init__
self.name = '{} {}'.format(ammo, self.raw_name)
TypeError: name() takes exactly 3 arguments (2 given)
I understand what the error is but I don't get how to solve it since I need both the raw_name and the ammo attributes to auto-update my Arrow instance's name.
My class is as such:
class Projectile(Item):
def __init__(self, name, value, image, x, y, speed, dmg, dmg_modif, ammo):
super(Projectile, self).__init__(name, value, image, x, y)
self.dest = (self.rect[0],self.rect[1])
self.speed = speed
self.dmg_modif = dmg_modif
self.dmg = dmg
self.orientation = 0
self.ammo = ammo
@property
def name(self):
return self.___name
@name.setter
def name(self, raw_name, ammo):
if '{} {}'.format(raw_name,ammo) != self.___name:
self.___name = '{} {}'.format(raw_name,ammo)
The child class which returns the error is:
class Arrow(Projectile):
def __init__(self, ammo): #name, value, image, x, y, dmg
self.raw_name = 'Arrows'
self.name = '{} {}'.format(ammo, self.raw_name)
self.value = 5
self.image = variables.quiver_img
self.speed = 4
self.dmg = 2
self.dmg_modif = 1
super(Arrow, self).__init__(self.name, self.value, self.image, 200, 150, self.speed, self.dmg, self.dmg_modif, ammo)
And the parent classes are, Item and MySprite:
class Item(MySprite):
def __init__(self, name, value, image, x, y):
# Call the parent class (Sprite) constructor
super(Item, self).__init__(image, x, y)
self.name = name
self.value = value
self.inv_pos = -1
and
class MySprite(pygame.sprite.Sprite):
def __init__(self,image,x,y):
# Call the parent class (Sprite) constructor
super(MySprite, self).__init__()
self.image = image
self.rect = self.image.get_rect().move(x, y) #initial placement
self.top_cp = (self.rect[0]+self.rect[2]/2,self.rect[1])
self.bot_cp = (self.top_cp[0],self.rect[1]+self.rect[3])
self.left_cp = (self.rect[0],self.rect[1]+self.rect[3]/2)
self.right_cp = (self.left_cp[0]+self.rect[2],self.left_cp[1])
self.center = self.rect.center
self.pos = self.rect.topleft
self.blit_order = 1
self.level = variables.current_level #Level(1)#level to which sprite belongs
So I eventually managed to solve my problem:
class Projectile(object):
def __init__(self, raw_name, ammo):
self.raw_name = raw_name
self.name = self.raw_name
self.ammo = ammo
@property
def ammo(self):
return self._ammo
@ammo.setter
def ammo(self, ammo):
self.name = str(ammo) + self.raw_name
self._ammo = ammo
class Arrow(Projectile):
def __init__(self):
self.raw_name = ' Arrows'
self.name = self.raw_name
super(Arrow, self).__init__(self.raw_name, ammo
= 10)
arrow = Arrow()
print arrow.ammo
print arrow.name
arrow.ammo = 15
print arrow.ammo
print arrow.name
gives:
>>>10
>>>10 Arrows
>>>15
>>>15 Arrows