Pygame: элемент в pygame.sprite.Group () не имеет атрибута rect

Я новичок в Python и застрял с некоторым кодом Pygame (см. Ниже трассировку и полный код). Я не понимаю, почему у объекта bullet нет атрибута rect, когда я перебираю элементы, хранящиеся в self.bullets. Любая помощь или указатели будут очень признательны. Спасибо!

Отслеживание

Traceback (most recent call last):
  File "/Users/svengerlach/PycharmProjects/AlienInvasion/practice_12_6.py", line 82, in <module>
    game.game_loop()
  File "/Users/svengerlach/PycharmProjects/AlienInvasion/practice_12_6.py", line 22, in game_loop
    self._bullet_update()
  File "/Users/svengerlach/PycharmProjects/AlienInvasion/practice_12_6.py", line 54, in _bullet_update
    if bullet.rect.left > self.screen_rect.right:
AttributeError: 'Bullet' object has no attribute 'rect'

Полный код

import pygame
import sys


class Game:
    def __init__(self):
        [...]
        self.bullets = pygame.sprite.Group()

    def game_loop(self):
        while True:
            self._check_user_inputs()
            self._ship_update()
            self._bullet_update()
            self._screen_update()

    def _check_user_inputs(self):
        for event in pygame.event.get():
            elif event.type == pygame.KEYDOWN:
                [...]
                elif event.key == pygame.K_SPACE:
                    new_bullet = Bullet(self)
                    self.bullets.add(new_bullet)
            elif event.type == pygame.KEYUP:
                [...]

    def _ship_update(self):
        [...]

    def _bullet_update(self):
        self.bullets.update()
        for bullet in self.bullets.copy():
            if bullet.rect.left > self.screen_rect.right:
                self.bullets.remove(bullet)

    def _screen_update(self):
        [...]
        for bullet in self.bullets.sprites():
            bullet.draw_bullet()
        pygame.display.flip()


class Bullet(pygame.sprite.Sprite):
    def __init__(self, ai_game):
        super().__init__()
        self.screen = ai_game.screen
        self.ship_rect = ai_game.ship_rect
        self.bullet_rect = pygame.Rect(0, 0, 15, 3)
        self.bullet_rect.midleft = self.ship_rect.midright

    def update(self):
        self.bullet_rect.x += 5

    def draw_bullet(self):
        pygame.draw.rect(self.screen, (60, 60, 60), self.bullet_rect)


if __name__ == '__main__':
    game = Game()
    game.game_loop()

person Sven Gerlach    schedule 14.07.2020    source источник
comment
bullet не имеет атрибута rect, потому что у него есть атрибут bullet_rect. В любом случае я рекомендую переименовать bullet_rect в rect, а не rect в bullet_rect. См. pygame.sprite.Sprite.   -  person Rabbid76    schedule 14.07.2020


Ответы (1)


bullet не имеет атрибута rect, но имеет атрибут bullet_rect. Рекомендую переименовать bullet_rect в rect. Таким образом, вы можете использовать pygame.sprite.Group.draw():

Рисует содержащиеся спрайты в аргумент Surface. При этом используется атрибут Sprite.image для исходной поверхности и Sprite.rect для положения.

Кроме того, используйте pygame.sprite.Sprite.kill():

Спрайт удаляется из всех групп, которые его содержат. [...]

Пример:

class Bullet(pygame.sprite.Sprite):
    def __init__(self, ai_game):
        super().__init__()
        self.image = pygame.Surface((15, 3))
        self.image.fill((60, 60, 60))
        self.rect = self.image.get_rect(midleft = ai_game.ship_rect.midright)

    def update(self):
        self.rect.x += 5
class Game:
    def __init__(self):
        # [...]
        self.bullets = pygame.sprite.Group()

    def game_loop(self):
        while True:
            self._check_user_inputs()
            self._ship_update()
            self._bullet_update()
            self._screen_update()

    def _check_user_inputs(self):
        for event in pygame.event.get():
            elif event.type == pygame.KEYDOWN:
                # [...]
                elif event.key == pygame.K_SPACE:
                    self.bullets.add(Bullet(self))
            elif event.type == pygame.KEYUP:
                # [...]

    def _bullet_update(self):
        self.bullets.update()
        for bullet in self.bullets:
            if bullet.rect.left > self.screen_rect.right:
                bullet.kill()

    def _screen_update(self):
        # [...]
        self.bullets.draw(ai_game.screen)
        pygame.display.flip()
person Rabbid76    schedule 17.12.2020