AttributeError: 'pygame.Surface' 对象没有属性 'screen'

问题描述

我正在从“PYTHON CRASH COURSE: A Hands-On,Project-Based Introduction to Programming”一书中学习 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'

我的代码是: 外星人入侵.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)

在类 Ship 的更新方法中,我实现了两个单独的块以允许 ship.rect.x 值 左、右时先增后减 箭头键被按下。否则, self.movi​​ng_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 属性,因此错误)。