题目描述
不加pygame.sprite.groupcollide()代码,运行一切正常没有问题
加了pygame.sprite.groupcollide()代码运行时按下空格就发生错误了。不按空格就正常运行
Traceback (most recent call last):
File "alien_invasion.py", line 41, in <module>
run_game()
File "alien_invasion.py", line 33, in run_game
gf.update_bullet(bullets,aliens)
File "G:\python_work\alien_invasion\game_functions.py", line 115, in update_bullet
cllisions = pygame.sprite.groupcollide(bullets,aliens,True,True)
File "C:\Users\靖\AppData\Roaming\Python\Python36\site-packages\pygame\sprite.py", line 1550, in groupcollide
c = SC(s, groupb, dokillb, collided)
File "C:\Users\靖\AppData\Roaming\Python\Python36\site-packages\pygame\sprite.py", line 1513, in spritecollide
spritecollide = sprite.rect.colliderect
AttributeError: 'Bullet' object has no attribute 'rect'
题目来源及自己的思路
题目时python编程入门到实践的例题,自己打的和书上没什么差别
相关代码
// 请把代码文本粘贴到下方(请勿用图片代替代码)
# alien_invasion.py
import pygame
from settings import Settings
from ship import Ship
import game_functions as gf
from pygame.sprite import Group
def run_game():
#初始化游戏并创建一个屏幕对象
pygame.init()
#实例化Settings类
ai_settings = Settings()
#创建指定大小的屏幕
screen = pygame.display.set_mode(
(ai_settings.screen_width,ai_settings.screen_height))
#创建一个用于储存子弹,外星飞船的编组
bullets = Group()
aliens = Group()
#游戏标题
pygame.display.set_caption('Alien Invasion')
#创建飞船,实例化Ship类
ship = Ship(ai_settings,screen)
#创造外星人飞船
gf.create_fleet(aliens,screen,ai_settings,ship.ship_rect.height)
#游戏主循环
while True:
#监视鼠标与键盘的事件
gf.check_events(ship,screen,ai_settings,bullets)
#更新飞机位置
ship.update()
#更新子弹位置并删除无用子弹
gf.update_bullet(bullets,aliens)
#更新外星人位
gf.update_alien(aliens,ai_settings)
#更新屏幕
gf.update_screen(ai_settings,screen,ship,bullets,aliens)
run_game()
# settings.py
class Settings():
'''储存游戏的各种设置'''
def __init__(self):
#屏幕大小
self.screen_width = 1200
self.screen_height = 800
#背景颜色
self.background_color = (255,255,255)
#飞船速度
self.ship_rl_speed_factor = 1.5
self.ship_ud_speed_factor = 1
#子弹参数
self.bullet_speed_factor = 1
self.bullet_color = 80, 80, 80
self.bullet_width = 3
self.bullet_height = 15
self.bullet_allowed = 5
#外星人移动速度
self.alien_speed_factor = 1
self.alien_drop = 10
self.speed_argue = 1
#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.ship_rect = self.image.get_rect()
self.screen_rect = self.screen.get_rect()
#设置飞船的初始位置
self.ship_rect.centerx = self.screen_rect.centerx
self.ship_rect.bottom = self.screen_rect.bottom
#移动标志
self.moving_right = False
self.moving_left = False
self.moving_down = False
self.moving_up = False
#移动位置
self.center = float(self.ship_rect.centerx)
self.bottom = self.ship_rect.bottom
def update(self):
'''更新飞机位置'''
if self.moving_right and (
self.ship_rect.right < self.screen_rect.right):
self.center += self.ai_settings.ship_rl_speed_factor
if self.moving_left and self.ship_rect.left > 0:
self.center -= self.ai_settings.ship_rl_speed_factor
if self.moving_up and self.ship_rect.top > 0:
self.bottom -= self.ai_settings.ship_ud_speed_factor
if self.moving_down and (
self.ship_rect.bottom < self.screen_rect.bottom):
self.bottom += self.ai_settings.ship_ud_speed_factor
#根据self.center更新ship位置
self.ship_rect.centerx = self.center
self.ship_rect.bottom = self.bottom
def blitme(self):
'''屏幕上的指定位置上画指定形状飞机'''
self.screen.blit(self.image,self.ship_rect)
# game_functions.py
import sys
import pygame
from bullet import Bullet
from alien import Alien
'''按键事件函数'''
def check_keydown_events(event,ship,screen,ai_settings,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_UP:
ship.moving_up = True
elif event.key == pygame.K_DOWN:
ship.moving_down = True
elif event.key == pygame.K_SPACE:
#按下space时生成一个子弹并保存到编组
fire_bullet(screen,ai_settings,ship,bullets)
#按下q退出
elif event.key == pygame.K_q:
sys.exit()
def check_keyup_events(event,ship):
'''鼠标抬起事件'''
if event.key == pygame.K_RIGHT:
ship.moving_right = False
if event.key == pygame.K_LEFT:
ship.moving_left = False
if event.key == pygame.K_UP:
ship.moving_up = False
if event.key == pygame.K_DOWN:
ship.moving_down = False
def check_events(ship,screen,ai_settings,bullets):
#监视鼠标与键盘的事件
for event in pygame.event.get():
#鼠标按下,移动标志变true,抬起变false
if event.type == pygame.QUIT:
sys.exit()
elif event.type == pygame.KEYDOWN:
check_keydown_events(event,ship,screen,ai_settings,bullets)
elif event.type == pygame.KEYUP:
check_keyup_events(event,ship)
'''外星飞船函数'''
def get_number_rows(ai_settings,alien_height,ship_height):
'''获得外星人飞船行数的数量'''
available_space_y = (ai_settings.screen_height -
(7 * alien_height) - ship_height)
rows_number = int(available_space_y / (2 * alien_height))
return rows_number
def get_alien_number_x(alien_width,ai_settings):
'''一行外星人的数量'''
alien_create_space = ai_settings.screen_width - (2 * alien_width)
alien_create_number = int(alien_create_space/(2 * alien_width))
return alien_create_number
def create_alien(screen,ai_settings,aliens,alien_number,row_number):
'''在左上角创造一个外星人,添加到编组'''
alien = Alien(screen,ai_settings)
alien_width = alien.alien_rect.width
alien_height = alien.alien_rect.height
alien.x = alien_width + 2 * alien_number * alien_width
alien.y = alien_height + 2 * row_number * alien_height
alien.alien_rect.x = alien.x
alien.alien_rect.y = alien.y
aliens.add(alien)
def create_fleet(aliens,screen,ai_settings,ship_height):
'''将整个屏幕的外星人飞船都创造,并添加到编组'''
alien = Alien(screen,ai_settings)
alien_width = alien.alien_rect.width
alien_height = alien.alien_rect.height
alien_number_x = get_alien_number_x(alien_width,ai_settings)
row_number_y = get_number_rows(ai_settings,alien_height,ship_height)
for row_number in range(row_number_y):
for alien_number in range(alien_number_x):
create_alien(screen,ai_settings,aliens,alien_number,
row_number)
def update_alien(aliens,ai_settings):
'''检测外星人有没有到边缘,并更新位置'''
check_edges(aliens,ai_settings)
aliens.update()
def check_edges(aliens,ai_settings):
'''外星人达到边缘时下移并改变方向'''
for alien in aliens.sprites():
if alien.check_alien_edges():
check_drop_alien(aliens,ai_settings)
ai_settings.speed_argue *= -1
break
def check_drop_alien(aliens,ai_settings):
'''让外星人群下移'''
for alien in aliens.sprites():
alien.alien_rect.y += ai_settings.alien_drop
'''子弹函数'''
def fire_bullet(screen,ai_settings,ship,bullets):
'''开火子弹'''
if len(bullets) < ai_settings.bullet_allowed:
new_bullet = Bullet(screen,ai_settings,ship)
bullets.add(new_bullet)
def update_bullet(bullets,aliens):
'''更新子弹情况'''
#更新子弹位置
bullets.update()
#检测是否外星人与子弹有碰撞,有就删除他们
cllisions = pygame.sprite.groupcollide(bullets,aliens,True,True)
#删除无用子弹
for bullet in bullets.copy():
if bullet.bullet_rect.bottom <= 0:
bullets.remove(bullet)
'''更新屏幕函数'''
def update_screen(ai_settings,screen,ship,bullets,aliens):
#每次循环都重设背景色
screen.fill(ai_settings.background_color)
#画出飞船
ship.blitme()
#sprite方法从编组中返回一个列表,并将每个子弹都更新一次
for bullet in bullets.sprites():
bullet.draw_bullet()
for alien in aliens.sprites():
alien.blitme()
#让最近绘制的屏幕可见
pygame.display.flip()
# bullet.py
import pygame
from pygame.sprite import Sprite
class Bullet(Sprite):
'''子弹参数和更新子弹位置'''
def __init__(self,screen,ai_settings,ship):
super().__init__()
#让后面能在屏幕上指定位置(0,0)制作子弹
self.screen = screen
#生成子弹矩形
self.bullet_rect = pygame.Rect(
0,0,ai_settings.bullet_width,ai_settings.bullet_height)
#子弹生成位置
self.bullet_rect.centerx = ship.ship_rect.centerx
self.bullet_rect.top = ship.ship_rect.top
#子弹速度
self.speed_y = float(ai_settings.bullet_speed_factor)
self.y = float(self.bullet_rect.y)
#子弹颜色
self.color = ai_settings.bullet_color
def update(self):
'''更新子弹位置'''
self.y -= self.speed_y
self.bullet_rect.y = self.y
def draw_bullet(self):
'''在屏幕指定位置画出指定颜色的矩形子弹'''
pygame.draw.rect(self.screen,self.color,self.bullet_rect)
# alien.py
import pygame
from pygame.sprite import Sprite
class Alien(Sprite):
def __init__(self,screen,ai_settings):
super().__init__()
#获取屏幕和游戏设定值
self.screen = screen
self.ai_settings = ai_settings
#获取外星人图和矩形
self.image = pygame.image.load('images/alien_aircraft.bmp')
self.alien_rect = self.image.get_rect()
#设定外星人最初位置
self.alien_rect.x = self.alien_rect.width
self.alien_rect.y = self.alien_rect.height
def blitme(self):
'''在屏幕上画出外星人飞船'''
self.screen.blit(self.image,self.alien_rect)
def update(self):
'''更新外星人的位置'''
self.speed = self.ai_settings.alien_speed_factor
self.x += self.speed * self.ai_settings.speed_argue
self.alien_rect.x = self.x
def check_alien_edges(self):
'''检测边缘函数所用的数据是外星人矩形坐标和屏幕坐标,放在外星人中'''
screen_rect = self.screen.get_rect()
if self.alien_rect.right >= screen_rect.right:
return True
elif self.alien_rect.left <= screen_rect.left:
return True
你好,我也是这个问题,怎么解决呢?