我目前正在从“ Python速成课程”这本书中学习python。
在这本书中,我目前在一个名为Alien Invasion的项目中。我尝试增加飞船在您按下按钮的时间时获得速度的能力后,在游戏中遇到问题。它说settings()没有属性“ blit”(当它调用blitme函数在游戏中绘制飞船时)。
我的代码分为以下多个模块。
所有模块均为.py。
外星人入侵基础:
import sys
import pygame
from settings import *
from ship import *
from gamef import *
def start_game():
pygame.init()
ai_settings = settings()
screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_height))
pygame.display.set_caption("Space Wars")
ship = Ship(ai_settings, screen)
while True:
ship.update()
check_events(ship)
us(ai_settings,screen,ship)
start_game()
game.py:
import sys
import ship
import pygame
def check_events(ship):
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
if event.key == pygame.K_RIGHT:
ship.moving_right = True
elif event.key == pygame.K_LEFT:
ship.moving_left = True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_RIGHT:
ship.moving_right = False
elif event.key == pygame.K_LEFT:
ship.moving_left = False
def us(self,ai_settings,screen,ship):
self.screen.fill(ai_settings.bg_color)
self.ship.blitme()
self.pygame.display.flip()
check_events(ship)
ship.py:
import pygame
import sys
class Ship():
def __init__(self,screen,ai_settings):
self.screen = screen
self.ai_settings = ai_settings
self.image = pygame.image.load('images/spaceship.bmp')
self.rect = self.image.get_rect()
self.screen_rect = self.image.get_rect()
self.screen_rect.centerx = self.screen_rect.centerx
self.rect.bottom = self.screen_rect.bottom
self.moving_right = False
self.moving_left = False
def update(self):
if self.moving_right == True:
self.rect.centerx += 1
if self.moving_left == True:
self.rect.centerx += -1
def blitme(self):
self.screen.blit(self.image,self.rect)
settings.py:
import pygame
import sys
import ship
class settings():
def __init__(self):
self.screen_width = 1200
self.screen_height = 800
self.bg_color = (0,0,0)
答案 0 :(得分:1)
game.py 中的us
方法不是实例方法,因为它不是类的一部分,因此它不需要self
参数。参见What is the purpose of the word 'self', in Python?。
def us(self,ai_settings,screen,ship):
self.screen.fill(ai_settings.bg_color)
self.ship.blitme()
self.pygame.display.flip()
删除self
,直接使用3个参数即可。
def us(ai_settings,screen,ship):
screen.fill(ai_settings.bg_color)
ship.blitme()
pygame.display.flip()
我认为最好使用check_events
的{{1}}和us
实例方法,因为无论如何都要传递Ship
作为参数,并且也将所有{{1 }}实例已经具有ship
和Ship
的副本。
我看到的另一个问题是您将参数混合到screen
中。类ai_settings
的方法接受Ship
和__init__
,按照特定顺序:
screen
但是您实例化了这样的一艘船:
ai_settings
请注意,订单不正确。因此,在def __init__(self,screen,ai_settings): # <--- look at the input order
self.screen = screen
self.ai_settings = ai_settings
中,将第一个参数 ship = Ship(ai_settings, screen) # <--- the order here is incorrect
分配给__init__
,将第二个参数 ai_settings
分配给self.screen
。 顺序对于函数的位置参数很重要,Python不会检查变量名。
这将导致您在此处提到的错误:
screen
因为实际上,self.ai_settings
实际上是def blitme(self):
self.screen.blit(self.image,self.rect)
实例self.screen
的实例。您可以通过打印出settings
进行检查。它与:
ai_settings
并且type(self.screen)
类没有ai_settings = settings() # instantiated in `start_game`
ai_settings.blit(...) # inside `Ship#blitme`
属性。