python - AttributeError Python 速成类(class)

标签 python python-3.x pygame

我正在学习 Python 速成类(class)来创建外星人入侵游戏。我对 run_game() 方法中的一次调用感到非常困惑。书中提到“当您在组上调用 update() 时,该组会自动为组中的每个 Sprite 调用 update()。行 self.bullets.update() 为我们放置在项目符号组中的每个项目符号调用 bullet.update()。”

我尝试将 self.bullets.draw_bullet() 调用插入 run_game() 方法,但最终出现 AttributeError:

'Group' object has no attribute 'draw_bullet'.

这是为什么呢?组是否应该自动为组中的每个 Sprite 调用draw_bullet()?为什么“draw_bullet()”与“update()”不同?有人可以透露一些信息吗?谢谢。

这是书中的原始代码,它可以工作。 外星人入侵.py

import sys, pygame

from settings import Settings
from ship import Ship
from bullet import Bullet

class AlienInvasion:
    """Overall class to manage game assests and behavior."""

    def __init__(self):
        """Initialize the game and create game resources."""
        pygame.init()
        self.settings = Settings()

        self.screen = pygame.display.set_mode(
            (self.settings.screen_width, self.settings.screen_height))
        pygame.display.set_caption("Alien Invasion")

        self.ship = Ship(self)
        self.bullets = pygame.sprite.Group()

    def run_game(self):
        """Start the main loop for the game."""
        while True:
            self._check_events()
            self.ship.update()
            self.bullets.update()
            self._update_screen()

    def _check_events(self):
        """Respond to keypresses and mouse events."""
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                self._check_keydown_events(event)
            elif event.type == pygame.KEYUP:
                self._check_keyup_events(event)

    def _check_keydown_events(self, event):
        if event.key == pygame.K_RIGHT:
            self.ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = True
        elif event.key == pygame.K_q:
            sys.exit()
        elif event.key == pygame.K_SPACE:
            self._fire_bullet()

    def _check_keyup_events(self, event):
        if event.key == pygame.K_RIGHT:                                    
            self.ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            self.ship.moving_left = False

    def _fire_bullet(self):
        new_bullet = Bullet(self)
        self.bullets.add(new_bullet)

    def _update_screen(self):
        # Redraw the screen during each pass through the loop
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()

        for bullet in self.bullets.sprites():
            bullet.draw_bullet()

        # Make the most recently drawn screen visible
        pygame.display.flip()

子弹.py

import pygame
from pygame.sprite import Sprite

class Bullet(Sprite):

    def __init__(self, ai_game):
        super().__init__()
        self.screen = ai_game.screen
        self.settings = ai_game.settings
        self.color = self.settings.bullet_color

        # Create a bullet rect at (0,0) and then set correct position
        self.rect = pygame.Rect(0, 0, self.settings.bullet_width,
            self.settings.bullet_height)
        self.rect.midtop = ai_game.ship.rect.midtop

        # Store the bullet's position as a decimal value
        self.y = float(self.rect.y)

    def update(self):
        self.y -= self.settings.bullet_speed
        self.rect.y = self.y

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

最佳答案

当然bullets没有属性draw_bullet

bulletspygame.sprite.Group 的一个实例,但 Bullet 源自 pygame.sprite.Sprite目的。 Bullet 的实例有一个 draw_bullet 方法,因为您已经实现了它。

如果你想绘制每个项目符号,那么你必须遍历项目符号并为每个项目符号调用 draw_bullet :

for bullet in selfbullets:
    bullet.draw_bullet()

另一个选项是使用 .draw() pygame.sprite.Group 的方法。在这种情况下,Bullet必须具有属性.rect.image,但它不需要任何绘制方法(draw_bullet ),因为 draw() 使用每个项目符号的属性来绘制它们。例如:

class Bullet(Sprite):

    def __init__(self, ai_game):
        super().__init__()
        self.screen = ai_game.screen
        self.settings = ai_game.settings
        self.color = self.settings.bullet_color

        # Create a bullet rect at (0,0) and then set correct position
        self.rect = pygame.Rect(0, 0, self.settings.bullet_width,
            self.settings.bullet_height)
        self.rect.midtop = ai_game.ship.rect.midtop

        # Store the bullet's position as a decimal value
        self.y = float(self.rect.y)

        # create Surface 
        self.image = pygame.Surface(self.rect.size)   # <-----
        self.image.fill(self.color)                   # <-----

    def update(self):
        self.y -= self.settings.bullet_speed
        self.rect.y = self.y
self.bullets.draw()

关于python - AttributeError Python 速成类(class),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58480212/

相关文章:

python - 使用正则表达式子在字符串中添加空格

python - 如何将钱(以便士计)转换为单独的硬币?

python - 转换 osmnx 投影 map 的经纬度坐标

python - 初始化字体需要很长时间

python - 如何深度复制 pygame Sprite 组?

python - pygame - 在 event.key 上取消按键

python - 在 BioPython 中使用 Entrez 从 GenBank 检索和解析蛋白质序列

python - ValueError:太多值无法在OpenCV项目中解压缩

python-3.x - Beautifulsoup 无法正确处理所有网址

python - `super`类是如何实现代理设计模式的?