Un jeu de vaisseau spatial python écrit selon le livre, le code est également écrit selon le livre, mais je ne sais pas où réside le problème
.AttributeError: 'Ship' object has no attribute 'bullet_width'
Il n'y a aucun problème lors de l'exécution du vaisseau spatial pour se déplacer à gauche et à droite, mais lorsqu'il s'agit de créer des balles et de déclencher, des problèmes surviennent
Voici le code spécifique :
alien_invasion.py
import sys
import pygame
from pygame.sprite import Group
from settings import Settings
from ship import Ship
import game_functions as gf
def run_game():
#初始化pygame、设置和屏幕对象
pygame.init()
ai_settings = Settings()
screen = pygame.display.set_mode((ai_settings.screen_width, ai_settings.screen_hight))
pygame.display.set_caption("Alien Invavsion")
#设置背景色
bg_color=(230,230,230)
#创建一艘飞船
ship = Ship(ai_settings, screen)
#创建一个用于存储子弹的编组
bullets = Group()
#开始游戏的主循环
while True:
#监视键盘和鼠标事件
gf.check_events(ai_settings, screen, ship, bullets)
ship.update()
bullets.update()
gf.updata_screen(ai_settings, screen, ship, bullets)
run_game()
settings.py
class Settings():
"""存储《外星人入侵》的所有设置的类"""
def __init__(self):
"""初始化游戏的设置"""
#屏幕设置
self.screen_width = 1200
self.screen_hight = 700
self.bg_color = (250,250,250)
#飞船的位置
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
game_functions.py
import sys
from bullet import Bullet
import pygame
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:
#创建一颗子弹,并将其加入到编组bullets中
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, ship, screen, bullets, ai_settings)
elif event.type == pygame.KEYUP:
check_keyup_events(event,ship)
def updata_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()
ship.py
import pygame
class Ship():
def __init__(self, ai_settings, screen):
"""初始化飞船并设置其初始位置"""
self.screen=screen
self.ai_settings = ai_settings
#加载飞船图像并获取其外接矩形
self.image = pygame.image.load('images/ship.bmp')
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
#在飞船的属性center中存储小数值
self.center = float(self.rect.centerx)
#移动标志
self.moving_right = False
self.moving_left = False
def update(self):
"""根据移动标志调整飞船的位置"""
#更新飞船的center值,而不是rect
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.centerx跟新的rect对象
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
#在(0,0)处创建一个表示子弹移动的矩形,再设置正确的位置
self.rect = pygame.Rect(0, 0, ai_settings.bullet_width,
ai_settings.bullet_height)
self.rect.conterx = ship.rect.centerx
self.rect.top = ship = 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
#更新表示子弹的rect的位置
self.rect.y = self.y
def draw_bullet(self):
"""在屏幕上绘制子弹"""
pygame.draw.rect(self.screen, self.color, self.rect)
C'est toutes les procédures jusqu'à présent. Quelqu'un peut-il me donner quelques conseils ? Merci.
L'ordre des paramètres de
check_events
中check_keydown_events(event, ship, screen, bullets, ai_settings)
est erroné, ajustez-le vous-mêmeÉvidemment, le code que vous avez fourni ne peut pas voir le code lié à la définition et à l'obtention de l'attribut bullet_width de l'objet ship. Votre bullet_width est défini pour les paramètres.
Peut-être avez-vous écrit ship.bullet quelque part. Il semble que le code n'ait pas été publié. Veuillez rechercher davantage. Il devrait y avoir un numéro de ligne devant votre message d'erreur.
Cela devrait être un exemple de python2, essayez l'environnement python2
Le feedback est écrit comme ceci, mais je l'ai débogué depuis longtemps et cela n'a toujours aucun effet
.Je pense que le problème est
Mais je ne sais toujours pas exactement comment le faire fonctionner. Quelqu'un peut-il m'aider ? Merci