I'm using Livewires and pygame and one of my objects in the game that gives you extra lives is being mistaken as an asteroid object, and when the extra lives objects collides with the player it returns the 'Extra lives object has no attribute handle_caught' error message, so can I please have some help.
class Extralives(games.Sprite):
global lives
image = games.load_image('lives.png', transparent = True)
speed = 2
def __init__(self,x,y = 10):
""" Initialize a asteroid object. """
super(Extralives, self).__init__(image = Extralives.image,
x = x, y = y,
dy = Extralives.speed)
def update(self):
""" Check if bottom edge has reached screen bottom. """
if self.bottom>games.screen.height:
self.destroy()
self.add_extralives
def add_extralives(self):
lives+=1
The asteroid class:
class Asteroid(games.Sprite):
global lives
global score
"""
A asteroid which falls through space.
"""
image = games.load_image("asteroid_med.bmp")
speed = 1.7
def __init__(self, x,image, y = 10):
""" Initialize a asteroid object. """
super(Asteroid, self).__init__(image = image,
x = x, y = y,
dy = Asteroid.speed)
def update(self):
""" Check if bottom edge has reached screen bottom. """
if self.bottom>games.screen.height:
self.destroy()
score.value+=10
def handle_caught(self):
if lives.value>0:
lives.value-=1
self.destroy_asteroid()
if lives.value <= 0:
self.destroy_asteroid()
self.end_game()
def destroy_asteroid(self):
self.destroy()
part of the player class which handles the collisions:
def update(self):
""" uses A and D keys to move the ship """
if games.keyboard.is_pressed(games.K_a):
self.x-=4
if games.keyboard.is_pressed(games.K_d):
self.x+=4
if self.left < 0:
self.left = 0
if self.right > games.screen.width:
self.right = games.screen.width
self.check_collison()
def ship_destroy(self):
self.destroy()
def check_collison(self):
""" Check if catch pizzas. """
global lives
for asteroid in self.overlapping_sprites:
asteroid.handle_caught()
if lives.value <=0:
self.ship_destroy()
for extralives in self.overlapping_sprites:
extralives.add_extralives()
Here is your problem:
The fact that you call your loop variable
asteroid
does not mean that it's magically only going to ever be an asteroid. Not if you have other kinds of objects you can collide with!overlapping_sprites
is all overlapping sprites, not just asteroids. At some pointasteroid
is anExtraLives
object. When you try to callhandle_caught()
on it, this obviously fails becauseExtraLives
doesn't have ahandle_caught()
method.The simplest solution here is to rename
add_extralives
tohandle_caught
on yourExtraLives
class. After all, you're doing the same thing: handling the situation where you collide with (or "catch") the object, it's just a different kind of object so the result needs to be different, which you specify by providing different code. Being able to implement entirely different kinds of behavior by calling the same methods (called "polymorphism") is kinda the whole point of object-oriented programming.The following loop has a similar problem, in that you're calling
add_extralives()
on objects that might not be of typeExtraLives
. Fortunately you can remove this code since you're already handling this situation by renamingadd_extralives
tohandle_caught
.