AttributeError: 'pygame.Surface' object has no attribute 'screen'

AttributeError: 'pygame.Surface' object has no attribute 'screen'

我正在学习 Python 本书“PYTHON 速成课程:基于项目的动手编程入门”,2E。 在制作游戏时,我收到错误

Traceback (most recent call last):
File "d:\BOOKS\python\my-projects\AlienInvasion\tempCodeRunnerFile.py", line 69, in <module>
alinv = AlienInvasion()
File "d:\BOOKS\python\my-projects\AlienInvasion\tempCodeRunnerFile.py", line 22, in __init__
self.ship = Ship(self.screen)
File "d:\BOOKS\python\my-projects\AlienInvasion\ship.py", line 10, in   __init__
self.screen = alinv_game.screen
AttributeError: 'pygame.Surface' object has no attribute 'screen'

我的代码是: AlienInvasion.py

# Importing modules
import sys
import pygame
from settings import Settings
from ship import Ship


class AlienInvasion:
    '''Class to manage game assets and behavior'''

    def __init__(self):
        '''Constructor to initialize the game and its assets'''
        pygame.init()
        self.settings = Settings()

        self.screen = pygame.display.set_mode((0, 0), pygame.FULLSCREEN)
        self.settings.screen_width = self.screen.get_rect().width
        self.settings.screen_height = self.screen.get_rect().height

        pygame.display.set_caption("Alien Invasion")

        self.ship = Ship(self.screen)

    def run_game(self):
        '''Starts the main loop for the game'''
        while True:
            self._check_events()
            self.ship.update()
            self._update_screen()

    def _check_events(self):
        '''Watch for the keyboard 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):
        """Respond to keypresses."""
        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_ESCAPE:
            sys.exit()

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

    def _update_screen(self):
        '''Redraw the screen during each pass of the loop'''
        self.screen.fill(self.settings.bg_color)
        self.ship.blitme()
        '''Make the most recently drawn screen visible'''
        pygame.display.flip()


if __name__ == '__main__':
    '''Make a game instance, and run the game'''
    alinv = AlienInvasion()
    alinv.run_game()

ship.py

import pygame


class Ship:
    '''A class to manage the ship'''

    def __init__(self, alinv_game):
        '''Initialize the ship and set its starting position'''

        self.screen = alinv_game.screen
        self.settings = alinv_game.settings
        self.screen_rect = alinv_game.screen.get_rect()

        '''Load the ship image and get its rect'''
        self.image = pygame.image.load('images/ship.bmp')
        self.rect = self.image.get_rect()

        '''Start each new ship at the bottom-center of the screen'''
        self.rect.midbottom = self.screen_rect.midbottom

        '''Store a decimal value for ship's horizontal position'''
        self.x = float(self.rect.x)

        '''Movement Flag'''
        self.moving_right = False
        self.moving_left = False

    def update(self):
        
        if self.moving_right and self.rect.right < self.screen_rect.right:
            self.x += self.settings.ship_speed
        if self.moving_left and self.rect.left > 0:
            self.x -= self.settings.ship_speed

        '''Update rect obj from self.x'''
        self.rect.x = self.x

    def blitme(self):
        '''Draw the ship at its current location.'''
        self.screen.blit(self.image, self.rect)

在 class Ship 的更新方法中,我实现了两个单独的块以允许 ship.rect.x 值 增加,然后减少,当左右 箭头键被按下。否则,self.moving_right 将 如果实施 'elif',则优先级更高。

settings.py

class Settings:
    '''A class to store all settings for Alien Invasion Game.'''

    def __init__(self):
        '''Initialize the game's settings'''

        # Screen Settings:
        self.screen_width = 1280
        self.screen_height = 720
        self.bg_color = (230, 230, 230)

        # Ship Settings:
        self.ship_speed = 1.5

我认为错误应该与屏幕声明有关,因为我认为 Pygame.Surface 没有 'screen' 属性,但我们可以通过 get_rect 方法获取它。请帮助我找到错误。我无法解决问题。

我相信你的意思是让行 self.ship = Ship(self.screen) 变成 self.ship = Ship(self)。这样 Ship 对象可以访问 AlienInvasion 对象的所有属性,而不仅仅是它的 screen 属性(并且该属性没有 screen 属性,因此错误)。