Reputation: 311
I wanted to make my first Kivy game, with enemies which run over the screen and the player is supposed to kill the enemies by clicking on them.
I created an Enemy class which is part of a level class, both are subclasses of the class Widget. I made a function, which automatically adds instances of the class Enemy to the class level. I made an if
loop in the class Enemy, which should check if the enemy reached the end of the screen.
Then it should remove one number from the variable zicie
and then it should remove the enemy, but both things are not working.
The error messages are:
File "bbgsa1.py", line 47, in Update
self.parent.remove_widget(self)
AttributeError: 'NoneType' object has no attribute 'remove_widget'
and
File "bbgsa1.py", line 45, in Update
self.parent.zicie = self.parent.zicie - 1
AttributeError: 'NoneType' object has no attribute 'zicie'
Here is the part of the code with the error:
class level(Widget):
zicie = NumericProperty(10)# the variable containg the life of the player
zloto = NumericProperty(0)
e_killed = NumericProperty(0)
intv1 = NumericProperty(2/1.)
def __init__(self, **kwargs):
super(level, self).__init__(**kwargs)
Clock.schedule_interval(self.Update, self.intv1)
def Update(self, *args):# this funktion generates enemys
obj = ROOT.ids.place.ids.level
obj.add_widget(Enemy(pos=(800,100))) # the widget enemy is added here
class Enemy(Widget):
imgp = StringProperty('enemy.png')
velocity = NumericProperty(1)
intv = NumericProperty(0/60.)
def __init__(self, **kwargs):
super(Enemy, self).__init__(**kwargs)
Clock.schedule_interval(self.Update, self.intv)
def Update(self, *args):# the funktion that lets the enemy move
self.x -= self.velocity
if self.x < 1:# checks if the enemy widget reached the end
self.velocity = 0#m akes the enemy stop moving
self.parent.zicie = self.parent.zicie - 1# the variable zicie that is not found
self.parent.remove_widget(self) # this command is also not working
def on_touch_down(self, touch):# the funktion, that lets the enemy die
if self.collide_point(*touch.pos):
self.velocity = 0
self.imgp = 'enemyd.png'
self.parent.e_killed += 1
self.parent.zloto += 10
self.parent.remove_widget(self)
Upvotes: 0
Views: 96
Reputation: 29450
These errors are because self.parent is None at the point where the lines are run. I haven't checked in detail, but one way this could arise is that the Clock scheduled self.Update function is called even after the Enemy has been removed from its parent.
You should be careful to unschedule the function after the Enemy has been removed from the screen (to avoid the number of scheduled functions building up), but can also directly resolve the issue by checking if self.parent is None before trying to do things based on its value.
Upvotes: 1