A python spaceship game written according to the book. The code is also written according to the book, but I don’t know where the problem lies.
AttributeError: 'Ship' object has no attribute 'bullet_width'
There is no problem when running the spacecraft to move left and right, but when it comes to creating bullets and triggering, problems arise
The following is the specific code:
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)
That’s all the procedures so far. Can anyone give me some advice? Thank you.
The order of parameters in
check_keydown_events(event, ship, screen, bullets, ai_settings)
in
check_eventsis wrong, adjust it yourself
Obviously the code you provided cannot see the code related to setting and obtaining the bullet_width attribute of the ship object. Your bullet_width is set for settings.
Perhaps you have written ship.bullet somewhere. It seems that the code has not been posted. Please search more. There should be a line number in front of your error message. Check which line of the file contains the error.
This should be an example of python2, try the python2 environment
The feedback is written like this, but I have debugged it for a long time and it still has no effect.
I think the problem is
But I still don’t know exactly how to operate it. Can someone help me? Thanks