报错Bullet object has no attribute 'rect' 如何解决
main.py
from game.war import PlaneWar def main(): war = PlaneWar() while True: # 设置帧速率 war.set_frame() # 监听事件 war.monitor_event() # 更新游戏状态 war.reset_game() if __name__ == '__main__': main()
war.py
import sys, pygame
import constants
from game.plane import MyPlane, EnermyPlane
class PlaneWar(object):
enermy_group = pygame.sprite.Group()
def __init__(self):
""" 初始化 """
pygame.init()
self.width, self.height = 640, 640
self.screen = pygame.display.set_mode((self.width, self.height))
pygame.display.set_caption('test')
# 加载开始图片
self.start = pygame.image.load(constants.START_DIR)
self.start_rect = self.start.get_rect()
self.start_w, self.start_h = self.start.get_size()
self.start_rect.topleft = (int((self.width - self.start_w) / 2), int((self.height - self.start_h) / 2))
self.my_plane = MyPlane(self.screen, 15)
self.add_enermy_plane(6)
# 设置帧速率
self.frame = 0
self.clock = pygame.time.Clock()
self.status = 0
def add_enermy_plane(self, num):
for i in range(num):
enermy_plane = EnermyPlane(self.screen, 8)
self.enermy_group.add(enermy_plane)
def run_game(self):
# 设置帧速率
self.set_frame()
# 监听事件
self.monitor_event()
# 更新游戏状态
self.reset_game()
pygame.display.flip()
def set_frame(self):
# 设置帧速率
self.clock.tick(60)
self.frame += 1
if self.frame >= 60:
self.frame = 0
def monitor_event(self):
# 监听事件
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
if self.status == 0:
self.status = 1
elif event.type == pygame.KEYDOWN:
if self.status == 1:
if event.key == pygame.K_w or event.key == pygame.K_UP:
self.my_plane.move_up()
elif event.key == pygame.K_s or event.key == pygame.K_DOWN:
self.my_plane.move_down()
elif event.key == pygame.K_a or event.key == pygame.K_LEFT:
self.my_plane.move_left()
elif event.key == pygame.K_d or event.key == pygame.K_RIGHT:
self.my_plane.move_right()
elif event.key == pygame.K_SPACE:
self.my_plane.shoot()
def reset_game(self):
if self.status == 0:
self.screen.blit(self.start, self.start_rect)
# 绘制
elif self.status == 1:
self.screen.fill(pygame.Color(255, 255, 255))
self.my_plane.update()
self.my_plane.bullets.update(self)
self.enermy_group.update()
pygame.display.flip()plane.py
import pygame import constants from game.bullet import Bullet import random class Plane(pygame.sprite.Sprite): img = [] b_imag = [] b_music = None bullets = pygame.sprite.Group() active = True def __init__(self, screen, speed=None): super(Plane, self).__init__() self.screen = screen self.speed = speed or 15 self.img_obj =[] self.b_img_obj = [] self.b_music_obj = [] self.load_src() self.img_obj_rect = self.get_img.get_rect() self.screen_w, self.screen_h = self.screen.get_size() self.width, self.height = self.get_img.get_size() self.img_obj_rect.topleft = (int((self.screen_w - self.width) / 2), int(self.screen_h - self.height)) def load_src(self): """ 加载静态资源 """ for img in self.img: self.img_obj.append(pygame.image.load(img)) if self.b_imag: for img in self.b_imag: self.b_img_obj.append(img) if self.b_music: self.b_music_obj = pygame.mixer.Sound(self.b_music) @property def get_img(self): return self.img_obj[0] def move_up(self): self.img_obj_rect.top -= self.speed def move_down(self): self.img_obj_rect.top += self.speed def move_left(self): self.img_obj_rect.left -= self.speed def move_right(self): self.img_obj_rect.left += self.speed def update(self, *args): ''' 绘制以及改变位置 ''' self.screen.blit(self.get_img, self.img_obj_rect) def shoot(self): bullet = Bullet(self, self.screen, speed=8) self.bullets.add(bullet) class MyPlane(Plane): img = [constants.PLANE1_DIR] b_imag = [] b_music = None @property def get_img(self): """ 获取图片 """ return self.img_obj[0] def set_rect(self): """ 设置图片位置 """ self.img_obj_rect.topleft = (int((self.screen_w - self.width)/2), self.screen_h) def move_up(self): self.img_obj_rect.top -= self.speed if self.img_obj_rect.top <= 0: self.img_obj_rect.top = 0 def move_down(self): self.img_obj_rect.top += self.speed if self.img_obj_rect.top > self.screen_h - self.height: self.img_obj_rect.top = self.screen_h - self.height def move_left(self): self.img_obj_rect.left -= self.speed if self.img_obj_rect.left <= 0:self.img_obj_rect.left = 0 def move_right(self): self.img_obj_rect.left += self.speed if self.img_obj_rect.left > self.screen_w - self.width: self.img_obj_rect.left = self.screen_w - self.width class EnermyPlane(Plane): img = [constants.PLANE_DIR] b_imag = [] b_music = None def __init__(self, screen, speed=None): super(EnermyPlane, self).__init__(screen, speed) # 初始敌方飞机位置 self.set_rect() def set_rect(self): """ 设置敌方飞机位置 """ self.img_obj_rect.top = random.randint(-5 * self.height, self.height) self.img_obj_rect.left = random.randint(0, self.screen_w - self.width) def blit_me(self): self.screen.blit(self.img_obj[0], self.img_obj_rect) def reset(self): self.active = True self.set_rect() def update(self, *args): self.move_down() self.blit_me() if self.img_obj_rect.top >= self.screen_h: self.active = False # 复位飞机 self.reset()
bullet.py
import pygame import constants class Bullet(pygame.sprite.Sprite): def __init__(self, plane, screen, speed=None): """ 这是写死的程序,不可更改""" super(Bullet, self).__init__() self.speed = speed or 15 self.screen = screen self.plane = plane active = True # 加载图片 self.imag = constants.BULLET_DIR self.bullet = pygame.image.load(self.imag) # 设置子弹图片初始位置 self.bullet_rect = self.bullet.get_rect() self.width, self.height = self.bullet.get_size() self.screen_w, self.screen_h = self.screen.get_size() self.bullet_rect.centerx = self.plane.img_obj_rect.centerx self.bullet_rect.top = self.plane.img_obj_rect.top def update(self, war): """ 更新子弹位置 """ # 改变子弹位置,改变位置变量 self.bullet_rect.top -= self.speed if self.bullet_rect.top < 0: self.remove(self.plane.bullets) self.screen.blit(self.bullet, self.bullet_rect) result = pygame.sprite.spritecollide(self, war.enermy_group, False) for r in result: # 消除子弹和碰撞飞机 self.kill() # 播放爆炸动画 # 更新敌方飞机 r.reset()
constants.py
import os # 基础路径 BASE_DIR = os.path.dirname(os.path.abspath(__file__)) # assets路径 ASSETS_DIR = os.path.join(BASE_DIR, 'assets') # 开始界面 START_DIR = os.path.join(ASSETS_DIR, 'images\\start.png') # 飞机 # 敌方飞机 PLANE_DIR = os.path.join(ASSETS_DIR, 'images\\plane.png') # 我方飞机 PLANE1_DIR = os.path.join(ASSETS_DIR, 'images\\plane1.png') # 子弹 BULLET_DIR = os.path.join(ASSETS_DIR, 'images\\bullet.png')
报错:
D:\Python_act\envs\2d_game\Scripts\python.exe D:/Python_act/2d_game/main.py
pygame 1.9.6
Hello from the pygame community. https://www.pygame.org/contribute.html
Traceback (most recent call last):
File "D:/Python_act/2d_game/main.py", line 14, in <module>
main()
File "D:/Python_act/2d_game/main.py", line 11, in main
war.reset_game()
File "D:\Python_act\2d_game\game\war.py", line 85, in reset_game
self.my_plane.bullets.update(self)
File "D:\Python_act\envs\2d_game\lib\site-packages\pygame\sprite.py", line 463, in update
s.update(*args)
File "D:\Python_act\2d_game\game\bullet.py", line 37, in update
result = pygame.sprite.spritecollide(self, war.enermy_group, False)
File "D:\Python_act\envs\2d_game\lib\site-packages\pygame\sprite.py", line 1534, in spritecollide
spritecollide = sprite.rect.colliderect
AttributeError: 'Bullet' object has no attribute 'rect'
正在回答
同学,你好。Bullet对象没有rect属性,这是该spritecollide函数所必需的,同学可根据图2图3修改,在子弹类和飞机类中,使用get_rect()得到位置时赋值给rect即可



如果我的回答解决了您的疑惑,请采纳!祝学习愉快~~~~
- 参与学习 人
- 提交作业 2727 份
- 解答问题 8160 个
想要进入Python Web、爬虫、人工智能等高薪领域,你需要掌握本阶段的Python基础知识,课程安排带你高效学习轻松入门,学完你也能听得懂Python工程师的行业梗。
了解课程
恭喜解决一个难题,获得1积分~
来为老师/同学的回答评分吧
0 星