簡體   English   中英

AttributeError Python 速成班

[英]AttributeError Python Crash Course

我正在關注 Python 速成課程來創建外星人入侵游戲。 我對run_game()方法中的一次調用感到很困惑。 在書中提到“當您在組上調用update()時,該組會自動為組中的每個精靈調用update()self.bullets.update()行為每個子彈調用bullet.update()我們將子彈放入組中。”

我嘗試在run_game()方法中插入一個self.bullets.draw_bullet()調用,但最終出現 AttributeError:

“組”object 沒有屬性“draw_bullet”。

為什么? 組應該為組中的每個精靈自動調用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 object。 Bullet的一個實例有一個方法draw_bullet ,因為您已經實現了它。

如果要繪制每個子彈,則必須遍歷子彈並為每個子彈調用draw_bullet

for bullet in selfbullets:
    bullet.draw_bullet()

另一種選擇是使用 pygame.sprite.Group 的pygame.sprite.Group .draw()方法。 在這種情況下, 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()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM