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
属性,因此错误)。
我正在学习 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
属性,因此错误)。