python 外星人入侵 射击bug 当射中单数时会出现bug 但双数则不会 每次都是在检测边缘的时候出现
代码如下
alien_invasion
from settings import Settingsfrom ship import Ship
from alien import Alien
import game_functions as gf
from pygame.sprite import Group
#将导入的模块指定别名为gf
import pygame
def run_game():
#初始化屏幕并创建一个屏幕对象
pygame.init()
setting =Settings()
screen = pygame.display.set_mode((setting.screen_width, setting.screen_height))
ship=Ship(setting,screen)
#创建一个外星人组
aliens=Group()
gf.create_fleet(setting,screen,ship,aliens)
bullets=Group()
pygame.display.set_caption("Alien Invasion")
#开始游戏的主循环
while True:
#监视键盘和鼠标事件
gf.check_events(setting,screen,ship,bullets)
ship.update()
gf.update_bullets(aliens,bullets)
gf.update_aliens(setting,aliens)
#让最近绘制的屏幕可见
gf.update_screen(setting,screen,ship,aliens,bullets)
run_game()
alien
import pygamefrom pygame.sprite import Sprite
class Alien(Sprite):
"""表示单个外星人类"""
def __init__(self,setting,screen):
"""初始化外星人并设置其初始位置"""
super(Alien,self).__init__()
self.screen=screen
self.setting=setting
#加载外星人图像,并设置rect属性
self.image=pygame.image.load('D:\\CODE\\py\\pygame\\alien_invasion\\images\\alien.bmp')
self.rect=self.image.get_rect()
#每个外星人最初都在屏幕的左上角附件
self.rect.x=self.rect.width
self.rect.y=self.rect.height
#将外星人的左边距设置成外星人的宽度
#将外星人的上边距设置成外星人的高度
#存储外星人的准确位置
self.x=float(self.rect.x)
def update(self):
"""向左右移动外星人"""
self.x+=(self.setting.alien_speed_factor*self.setting.fleet_direction)
self.rect.x=self.x
def check_edges(self):
"""如果外星人位于屏幕边缘,就返回ture"""
screen_rect=self.screen.get_rect()
if self.rect.right>=screen_rect.right:
return True
elif self.rect.left<=0:
return True
bullet
import pygamefrom pygame.sprite import Sprite
class Bullet(Sprite):
"""发射子弹的类"""
def __init__(self,setting,screen,ship):
"""在飞船所处位置创建一个子弹对象"""
super(Bullet,self).__init__()
self.screen=screen
#在(0,0)处创建一个子弹的矩阵,再设置正确的位置
self.rect=pygame.Rect(0,0,setting.bullet_width,setting.bullet_height)
#先创建一个矩形
self.rect.centerx=ship.rect.centerx
self.rect.top=ship.rect.top
#移动到飞船的正上方
#存储用小数表示的子弹位置
self.y=float(self.rect.y)
#y是子弹的纵向坐标 可以控制子弹的速度
self.color=setting.bullet_color
self.speed_factor=setting.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)
game_functions
import pygameimport sys
from bullet import Bullet
from alien import Alien
def check_events(setting,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,setting,screen,ship,bullets)
elif event.type==pygame.KEYUP:
check_keyup_events(event,ship)
def check_keydown_events(event,setting,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_UP:
ship.moving_up=True
elif event.key==pygame.K_DOWN:
ship.moving_down=True
elif event.key==pygame.K_SPACE:
fire_bullets(setting,screen,ship,bullets)
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
elif event.key==pygame.K_UP:
ship.moving_up=False
elif event.key==pygame.K_DOWN:
ship.moving_down=False
def update_screen(setting,screen,ship,aliens,bullets):
"""更新屏幕上的图像,并切换到新屏幕"""
#每次循环时都要重绘屏幕
screen.fill(setting.bg_color)
for bullet in bullets.sprites():
bullet.draw_bullet()
ship.blitme()
aliens.draw(screen)#在屏幕中绘制编组中的每一个外星人
#让最近绘制的屏幕可见
pygame.display.flip()
def update_bullets(aliens,bullets):
bullets.update()
#将飞出屏幕的子弹删除
for bullet in bullets.copy():
if bullet.rect.bottom<=0:#检测
bullets.remove(bullet)#删除
#检查是否有子弹击中外星人
#如果是 则删除相应的子弹和外星人
collisions=pygame.sprite.groupcollide(bullets,aliens,True,True)
def fire_bullets(setting,screen,ship,bullets):
if len(bullets)<setting.bullet_allowed:
new_bullet=Bullet(setting,screen,ship)
bullets.add(new_bullet)
def get_number_alien_x(setting,alien_width):
available_space_x=setting.screen_width-2*alien_width
#左右两边删去留边距
number_alien_x=int(available_space_x/(2*alien_width))
#间距为一个外星人的宽度
return number_alien_x
def get_number_rows(setting,ship_height,alien_height):
"""计算屏幕可容纳多少行外星人"""
available_space_y=(setting.screen_height-(3*alien_height)-ship_height)
number_rows=int(available_space_y/(2*alien_height))
return number_rows
def create_alien(setting,screen,aliens,alien_number,row_number):
alien=Alien(setting,screen)
#创建一个外星人
alien_width=alien.rect.width
alien.x=alien_width+2*alien_width*alien_number
#计算出它应该有的x坐标并赋予
alien.rect.x=alien.x
alien.rect.y=alien.rect.height+2*alien.rect.height*row_number
aliens.add(alien)
def create_fleet(setting,screen,ship,aliens):
alien=Alien(setting,screen)
number_alien_x=get_number_alien_x(setting,alien.rect.width)
number_rows=get_number_rows(setting,ship.rect.height,alien.rect.height)
for row_number in range(number_rows):
for alien_number in range(number_alien_x):
create_alien(setting,screen,aliens,alien_number,row_number)
#循环创建次数为计算得出的外星人数量
def update_aliens(setting,aliens):
"""检测是否有外星人到达屏幕边界,更新外星人群中所有外星人的位置"""
check_fleet_edge(setting,aliens)
aliens.update()
def check_fleet_edge(setting,aliens):
"""有外星人到达边界时采取相应的措施"""
for alien in aliens.sprites():
if alien.check_edges():
change_fleet_direction(setting,aliens)
break
def change_fleet_direction(setting,aliens):
"""将整群外星人下移,并改变他们的方向"""
for alien in aliens.sprites():
alien.rect.y+=setting.fleet_drop_speed
setting.fleet_direction*=-1
settings
class Settings(): """存储所有设置的类"""
def __init__(self):
"""初始化游戏的设置"""
#屏幕设置
self.screen_width = 1300
self.screen_height = 600
self.bg_color=(230,230,230)#颜色的RGB
self.ship_speed_factor=0.5#factor=因素
#子弹设置
self.bullet_speed_factor=1
self.bullet_width=3
self.bullet_height=15
self.bullet_color=60,60,60
self.bullet_allowed=5
#外星人设置
self.alien_speed_factor=0.2
self.fleet_drop_speed=2
#fleet_direction为1表示向右移,为-1表示向左移
self.fleet_direction=1
ship
import pygameclass Ship():
def __init__(self,setting,screen):
"""初始化飞船并设置其初始位置"""
self.screen=screen
self.setting=setting
#加载飞船图像并获取其外接矩形
self.image = pygame.image.load('D:\\CODE\\py\\pygame\\alien_invasion\\images\\ship.bmp')
self.rect=self.image.get_rect()
#获取图片的外接矩阵
self.screen_rect=screen.get_rect()
#获取屏幕的外接矩阵
#将每部新飞船放到屏幕底部中央
self.rect.centerx=self.screen_rect.centerx
#CENTERX =中心 让飞船的中心等于屏幕的中心
self.rect.bottom=self.screen_rect.bottom
#BOTTOM =底部 让飞船的底部等于屏幕的底部
#在飞船的属性center中存储小数值
self.center=float(self.rect.centerx)
self.bottom=float(self.rect.bottom)
self.moving_right=False
self.moving_left=False
#控制飞船的左右
self.moving_up=False
self.moving_down=False
def update(self):
"""根据移动标志调整飞船的位置"""
if self.moving_right and self.rect.right<self.screen_rect.right:
#只有飞船的右边界小于屏幕右边界的时候并且有向右的命令才能移动
self.center+=self.setting.ship_speed_factor
if self.moving_left and self.rect.left>0:
#同理 飞船左边界大于零时并且有命令时
self.center-=self.setting.ship_speed_factor
if self.moving_up and self.rect.top>0:
self.bottom-=self.setting.ship_speed_factor
if self.moving_down and self.rect.bottom<self.screen_rect.bottom:
self.bottom+=self.setting.ship_speed_factor
self.rect.centerx=self.center
self.rect.bottom=self.bottom
#根据调整的飞船的中心值来改变原来飞船的中心值
#只取整移动
def blitme(self):
"""在指定位置绘制飞船"""
self.screen.blit(self.image,self.rect)
谢谢啦 第一次用思否 有什么不对的地方 望见谅
回答:
我也遇到了这个问题,你的解决了么
回答:
你可以看看你写的 game_function.py 里面的 change_fleet_direction 函数
每次 for 循环里面都乘了 -1 改变了 direction 的值
这样一来,如果 for 循环偶数次,那么 direction 保持原值。若 for 循环了奇数次,那么 direction 相反。这就是这个 bug 的问题所在。
所以只要把 那一行移到 for 循环外面就可以了。
这里要提一下。settings 是一个类的对象。在 python 里,类的对象是一个引用,所以这里的 settings 改变,aliens 的所有成员的 settigns 成员都会改变。(就像全局变量一样)所以要改变 settings 里的 direction,只要改变一次就够了。
以上是 python 外星人入侵 射击bug 当射中单数时会出现bug 但双数则不会 每次都是在检测边缘的时候出现 的全部内容, 来源链接: utcz.com/a/161471.html