Ошибка AttributeError: ‘Text’ object has no attribute ‘die’

Решено584 просмотра
1
0 Комментариев

Изучаю книгу Майлка Доусона по Python, написал игру «Прерванный Полет».
При уничтожении астероида вылезает следующая ошибка.

Traceback (most recent call last):
  File "C:/Users/Чебупелька/Desktop/Python/!Читаю с клавиатуры.py", line 249, in <module>
main()
  File "C:/Users/Чебупелька/Desktop/Python/!Читаю с клавиатуры.py", line 246, in main
game.play()
  File "C:/Users/Чебупелька/Desktop/Python/!Читаю с клавиатуры.py", line 27, in play
games.screen.mainloop()
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\livewires\games.py", line 308, in mainloop
object._tick()
  File "C:\Program Files (x86)\Python36-32\lib\site-packages\livewires\games.py", line 506, in _tick
self.update()
  File "C:/Users/Чебупелька/Desktop/Python/!Читаю с клавиатуры.py", line 126, in update
super(Missile, self).update()
  File "C:/Users/Чебупелька/Desktop/Python/!Читаю с клавиатуры.py", line 90, in update
sprite.die()
AttributeError: 'Text' object has no attribute 'die'
Exception ignored in: <bound method Sprite.__del__ of <__main__.Missile object at 0x06283610>>

Код ниже.

import random
import math
 
from livewires import games, color
 
games.init(screen_width=800, screen_height=600, fps=60)
 
 
class Game(object):
    def __init__(self):
        self.level = 0
        self.score = games.Text(value='0',
                                size=30,
                                color=color.black,
                                top=0,
                                left=games.screen.width)
        games.screen.add(self.score)
        self.ship = Ship(game=self,
                         x=games.screen.width / 2,
                         y=games.screen.height / 2)
        games.screen.add(self.ship)
 
    def play(self):
        nebula_image = games.load_image('nebula228.jpg', transparent=False)
        games.screen.background = nebula_image
        self.lvlup()
        games.screen.mainloop()
 
    def lvlup(self):
        self.level += 1
        BUFFER = 150
        for i in range(self.level):
            x_min = random.randrange(BUFFER)
            y_min = BUFFER - x_min
            x_distance = random.randrange(y_min, games.screen.width - x_min)
            y_distance = random.randrange(x_min, games.screen.height - y_min)
            x = self.ship.x + x_distance
            y = self.ship.y + y_distance
            y %= games.screen.height
            x %= games.screen.width
            new_asteroid = Asteroid(game=self,
                                    x=x, y=y,
                                    size=Asteroid.LARGE)
            games.screen.add(new_asteroid)
            level_message = games.Message(value='Level ' + str(self.level),
                                          size=40,
                                          color=color.yellow,
                                          x=games.screen.width / 2,
                                          y=games.screen.height / 10,
                                          lifetime=3 * games.screen.fps,
                                          is_collideable=False)
            games.screen.add(level_message)
 
    def end(self):
        end_message = games.Message(value='Game Over!', lifetime=5 * games.screen.fps,
                                    x=games.screen.width / 2,
                                    y=games.screen.height / 2,
                                    is_collideable=False,
                                    after_death=games.screen.quit)
        games.screen.add(end_message)
 
 
class Wrapper(games.Sprite):
    def upadte(self):
        if self.top > games.screen.height:
            self.bottom = 0
        if self.bottom < 0:
            self.top = games.screen.height
        if self.left > games.screen.width:
            self.right = 0
        if self.right < 0:
            self.left = games.screen.width
 
    def die(self):
        self.destroy()
 
 
class Collider(Wrapper):
    def update(self):
        if self.top > games.screen.height:
            self.bottom = 0
        if self.bottom < 0:
            self.top = games.screen.height
        if self.left > games.screen.width:
            self.right = 0
        if self.right < 0:
            self.left = games.screen.width
        if self.overlapping_sprites:
            for sprite in self.overlapping_sprites:
                sprite.die()
            self.die()
 
    def die(self):
        new_expl = Explosion(x=self.x, y=self.y)
        games.screen.add(new_expl)
        self.destroy()
 
 
class Missile(Collider):
    image = games.load_image('missile.bmp', transparent=True)
    BUFFER = 40
    VELOCITY_FACTOR = 7
    LIFETIME = 100
 
    def __init__(self, sx, sy, sangle):
        angle = sangle * math.pi / 180
        bx = Missile.BUFFER * math.sin(angle)
        by = Missile.BUFFER * -math.cos(angle)
        x = sx + bx
        y = sy + by
        dy = Missile.VELOCITY_FACTOR * -math.cos(angle)
        dx = Missile.VELOCITY_FACTOR * math.sin(angle)
        super(Missile, self).__init__(image=Missile.image,
                                      x=x, y=y,
                                      dx=dx, dy=dy)
        self.lifetime = Missile.LIFETIME
 
    def update(self):
        if self.overlapping_sprites:
            for sprite in self.overlapping_sprites:
                sprite.die()
            self.die()
        self.lifetime -= 1
        if self.lifetime == 0:
            self.destroy()
        super(Missile, self).update()
 
    def die(self):
        self.destroy()
 
 
class Ship(Collider):
    image = games.load_image('ship.bmp', transparent=True)
    ROTATION_STEP = 3
    VELOCITY_STEP = .03
    VELOCITY_MAX = 3
    MISSILE_DELAY = 25
 
    def __init__(self, game, x, y):
        self.game = game
        super(Ship, self).__init__(image=Ship.image, x=x, y=y)
        self.missile_wait = 0
 
    def update(self):
        if self.missile_wait > 0:
            self.missile_wait -= 1
        if games.keyboard.is_pressed(games.K_w):
            angle = self.angle * math.pi / 180
            self.dy += Ship.VELOCITY_STEP * -math.cos(angle)
            self.dx += Ship.VELOCITY_STEP * math.sin(angle)
            self.dx = min(max(self.dx, -Ship.VELOCITY_MAX), Ship.VELOCITY_MAX)
            self.dy = min(max(self.dy, -Ship.VELOCITY_MAX), Ship.VELOCITY_MAX)
        if games.keyboard.is_pressed(games.K_LEFT):
            self.angle -= Ship.ROTATION_STEP
        if games.keyboard.is_pressed(games.K_RIGHT):
            self.angle += Ship.ROTATION_STEP
        if games.keyboard.is_pressed(games.K_SPACE) and self.missile_wait == 0:
            new_missile = Missile(self.x, self.y, self.angle)
            games.screen.add(new_missile)
            self.missile_wait = Ship.MISSILE_DELAY
        if self.top > games.screen.height:
            self.bottom = 0
        if self.bottom < 0:
            self.top = games.screen.height
        if self.left > games.screen.width:
            self.right = 0
        if self.right < 0:
            self.left = games.screen.width
        super(Ship, self).update()
 
    def die(self):
        self.game.end()
        super(Ship, self).die()
 
 
class Asteroid(Wrapper):
    POINTS = 30
    SMALL = 1
    MEDIUM = 2
    LARGE = 3
    SPAWN = 2
    images = {SMALL: games.load_image('asteroid_small.bmp'),
              MEDIUM: games.load_image('asteroid_med.bmp'),
              LARGE: games.load_image('asteroid_big.bmp')}
    SPEED = 2
    total = 1
 
    def __init__(self, game, x, y, size):
        self.game = game
        Asteroid.total += 1
        super(Asteroid, self).__init__(
            image=Asteroid.images[size],
            x=x, y=y,
            dx=random.choice([1, -1]) * Asteroid.SPEED * random.random() / size,
            dy=random.choice([1, -1]) * Asteroid.SPEED * random.random() / size)
        self.size = size
 
    def update(self):
        if self.top > games.screen.height:
            self.bottom = 0
        if self.bottom < 0:
            self.top = games.screen.height
        if self.left > games.screen.width:
            self.right = 0
        if self.right < 0:
            self.left = games.screen.width
        super(Asteroid, self).update()
 
    def die(self):
        Asteroid.total -= 1
        self.game.score.value += str(30)
        self.game.score.right = games.screen.width - 10
        new_expl = Explosion(x=self.x, y=self.y)
        games.screen.add(new_expl)
        self.destroy()
        if self.size != 1:
            for i in range(Asteroid.SPAWN):
                new_aster = Asteroid(x=self.x, y=self.y,
                                     size=self.size - 1)
                games.screen.add(new_aster)
        if Asteroid.total == 0:
            self.game.lvlup()
        super(Asteroid, self).die()
 
 
class Explosion(games.Animation):
    ALLAHU_AKBAR = ('1.bmp',
                    '2.bmp',
                    '3.bmp',
                    '4.bmp',
                    '5.bmp',
                    '6.bmp',
                    '7.bmp',
                    '8.bmp',
                    '9.bmp')
 
    def __init__(self, x, y):
        super(Explosion, self).__init__(images=Explosion.ALLAHU_AKBAR,
                                        x=x, y=y,
                                        repeat_interval=4, n_repeats=1,
                                        is_collideable=False)
 
 
def main():
    game = Game()
    game.play()
 
 
main()


Добавить комментарий

1 Ответы

Python Опубликовано 14.12.2018
0

Сначала определите функцию die() и только потом функцию где она вызывается.

class Collider(Wrapper):
    def die(self):
        new_expl = Explosion(x=self.x, y=self.y)
        games.screen.add(new_expl)
        self.destroy()
 
    def update(self):
        if self.top > games.screen.height:
            self.bottom = 0
        if self.bottom < 0:
            self.top = games.screen.height
        if self.left > games.screen.width:
            self.right = 0
        if self.right < 0:
            self.left = games.screen.width
        if self.overlapping_sprites:
            for sprite in self.overlapping_sprites:
                sprite.die()
            self.die()

Добавить комментарий
Scroll Up