【问题标题】:(Python Crash Course) Alien Invasion Project(Python速成课程)外星人入侵项目
【发布时间】:2020-09-01 14:19:57
【问题描述】:

如果有人能告诉我如何解决此错误,我将不胜感激:

AttributeError: 'Ship' object has no attribute 'bullet_width'

我开始学习 Python,但我不确定解决方案是什么。当我按空格键时,总是会发生这种情况。 以下是该项目中的模块:

外星人入侵.py:

    import sys
    import pygame
    from settings import Settings
    from ship import Ship
    import game_functions as gf
    from pygame.sprite import Group

    def run_game():
        pygame.init()
        ai_settings = Settings()
        screen = pygame.display.set_mode(
            (ai_settings.screen_width, ai_settings.screen_height))
        screen = pygame.display.set_mode((1100, 600))
        pygame.display.set_caption("Alien Invasion")
        bg_color = (230, 230, 230)
        ship = Ship(screen, ai_settings)
        bullets = Group()
        while True:
            gf.check_events(ship, screen, ai_settings, bullets)
            ship.update()
            bullets.update()
            gf.update_screen(ai_settings, screen, ship, bullets)
            for event in pygame.event.get():
                if event.type == pygame.QUIT:
                     sys.exit()
            screen.fill(ai_settings.bg_color)
            ship.blitme()
            screen.fill(bg_color)

    run_game()

ship.py:

    import pygame
    class Ship():
        def __init__(self, screen, ai_settings):
            self.screen = screen
            self.ai_settings = ai_settings
            self.image = pygame.image.load('images/spaceship.png')
            self.rect = self.image.get_rect()
            self.screen_rect = screen.get_rect()
            self.rect.centerx = self.screen_rect.centerx
            self.rect.bottom = self.screen_rect.bottom
            self.center = float(self.rect.centerx)
            self.moving_right = False
            self.moving_left = False
        def update(self):
            if self.moving_right and self.rect.right < self.screen_rect.right:
                self.center += self.ai_settings.ship_speed_factor
            if self.moving_left and self.rect.left > 0:
                self.center -= self.ai_settings.ship_speed_factor
            self.rect.centerx = self.center

        def blitme(self):
            self.screen.blit(self.image, self.rect)

bullet.py:

    import pygame
    from pygame.sprite import Sprite

    class Bullet(Sprite):
        def __init__(self, ai_settings, screen, ship):
            super(Bullet, self).__init__()
            self.screen = screen

            self.rect = pygame.Rect(0, 0, ai_settings.bullet_width,
                            ai_settings.bullet_height)
            self.rect.centerx = ship.rect.top

            self.y = float(self.rect.y)
            self.color = ai_settings.bullet_color
            self.speed_factor = ai_settings.bullet_speed_factor

    def update(self):
            self.y -= self.speed_factor
            self.rect.y = self.y

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

game_functions.py

    import sys
    import pygame
    from bullet import Bullet

    def check_keydown_events(event, ai_settings, screen, ship, bullets):
        if event.key == pygame.K_RIGHT:
            ship.moving_right = True
        elif event.key == pygame.K_LEFT:
            ship.moving_left = True
        elif event.key == pygame.K_SPACE:
            new_bullet = Bullet(ai_settings, screen, ship)
            bullets.add(new_bullet)
    def check_keyup_events(event, ship):
        if event.key == pygame.K_RIGHT:
            ship.moving_right = False
        elif event.key == pygame.K_LEFT:
            ship.moving_left = False
    def check_events(ai_settings, screen, ship, bullets):
        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                check_keydown_events(event, ai_settings, screen, ship, bullets)
            elif event.type == pygame.KEYUP:
                check_keyup_events(event, ship)


    def update_screen(ai_settings, screen, ship, bullets):
        screen.fill(ai_settings.bg_color)
        for bullet in bullets.sprites():
            bullet.draw_bullet()
        ship.blitme()
        pygame.display.flip()

settings.py:

    class Settings():
        def __init__(self):
            self.screen_width = 1200
            self.screen_height = 800
            self.bg_color = (230, 230, 230)
            self.ship_speed_factor = 1.5

            self.bullet_speed_factor = 1
            self.bullet_width = 3
            self.bullet_height = 15
            self.bullet_color = 60, 60, 60

【问题讨论】:

  • 由于某种原因,ai_settings 看起来像 ship(可能是 Super 调用),但这并不是真正可以从这里解决的。您需要启动调试器并逐步执行,直到找到错误发生的时刻。
  • check_events(ship, screen, ai_settings, bullets) -> check_events(ai_settings, screen, ship, bullets)
  • 我刚刚更改了它,我很高兴地说它有效!但是为什么顺序很重要呢?
  • @JackBrown 请学习基础知识。参数的顺序很重要,Keyword Arguments 除外。
  • 参数的顺序在所有语言中都很重要(关键字参数除外)。语言不关心你如何命名变量——你可能在函数外部和函数内部有不同的名字——它们关心参数的位置

标签: python python-3.x pygame


【解决方案1】:

调用check_events时参数顺序错误:

check_events(ship, screen, ai_settings, bullets)

check_events(ai_settings, screen, ship, bullets) 

参数的顺序很重要,Keyword Arguments 除外。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-04
    • 1970-01-01
    • 2022-08-02
    • 1970-01-01
    • 2020-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多