最近在做python的期末项目,需要实现这个功能,然后各种百度,一直在调bug,走了一些弯路,导致搞了接近两个小时才搞出来,总结一下我遇到的问题以及解决方案。
一.实现效果
爆炸图片有七张,所以爆炸效果看上去是动态的
2.效果实现
第一步:新建一个Bomb爆炸类
import pygame
class Bomb(object):
# 初始化爆炸
def __init__(self,ai_settings,scene):
self.main_scene = scene
# 加载爆炸资源
self.image = [pygame.image.load("picture/bomb-" + str(v) + ".png") for v in range(1, 8)]
# 设置当前爆炸播放索引
self.index = 0
# 图片爆炸播放间隔
self.interval = 20
self.interval_index = 0
# 爆炸位置
self.position = [0, 0]
# 是否可见
self.visible = False
# 设置爆炸播放的位置
def set_pos(self, x, y):
self.position[0] = x
self.position[1] = y
# 爆炸播放
def action(self):
# 如果爆炸对象状态不可见,则不计算坐标
if not self.visible:
return
# 控制每一帧图片的播放间隔
self.interval_index += 1
if self.interval_index < self.interval:
return
self.interval_index = 0
self.index = self.index + 1
if self.index >= len(self.image):
self.index = 0
self.visible = False
# 绘制爆炸
def draw(self):
# 如果对象不可见,则不绘制
if not self.visible:
return
self.main_scene.blit(self.image[self.index], (self.position[0], self.position[1]))
View Code
第二步:在alien_invasion.py中进行修改:
#添加代码:
#导入Bomb类
from Bomb import Bomb
# 创建爆炸对象
bomb = Bomb(ai_settings,screen)
#修改代码:
# 删除已消失的子弹
gf.update_bullets(ai_settings, screen, stats, sb, ship, aliens, bullets,bomb)
gf.update_aliens(ai_settings, screen, stats, sb, ship, aliens, bullets,bomb) gf.update_screen(ai_settings, screen, stats, sb, ship, aliens, bullets, play_button,introduce_button,bomb)
第三步:在game_function.py中进行修改:
#导入Bomb类
from Bomb import Bomb
#修改代码
def update_bullets(ai_settings, screen, stats, sb, ship, aliens, bullets,bomb):
"""更新子弹的位置,并删除已消失的子弹"""
# 更新子弹的位置
bullets.update()
# 删除已消失的子弹
for bullet in bullets.copy():
if bullet.rect.bottom <= 0:
bullets.remove(bullet)
check_bullet_alien_collisions(ai_settings, screen, stats, sb, ship, aliens, bullets,bomb)
def check_bullet_alien_collisions(ai_settings, screen, stats, sb, ship, aliens, bullets,bomb):
# 检查是否有子弹击中了外星人
# 如果是这样,就删除相应的外星人和子弹
"""
collisions = pygame.sprite.groupcollide(bullets, aliens, True, True)
if collisions:
for aliens in collisions.values():
stats.score += ai_settings.alien_points * len(aliens)
sb.prep_score()
check_high_score(stats, sb)
"""
for bullet in bullets:
# 检查子弹与飞机的碰撞,及击中飞机
collisions = pygame.sprite.groupcollide(aliens, bullets, True, True)
if collisions:
current_pos = pygame.Vector2(bullet.rect.x, bullet.rect.y)
if bullet.rect.collidepoint(current_pos):
bomb.position[0] = (bullet.rect.x - 20)
bomb.position[1] = (bullet.rect.y - 40)
bomb.visible = True
if len(aliens) == 0:
# 删除现有的子弹, 加快游戏节奏,并新建一群外星人
bullets.empty()
ai_settings.increase_speed()
# 提高等级
stats.level += 1
sb.prep_level()
create_fleet(ai_settings, screen, ship, aliens)
def update_aliens(ai_settings, screen, stats, sb, ship, aliens, bullets,bomb):
"""
检查是否有外星人到达屏幕边缘
然后更新外星人群中的所有外星人位置
"""
bomb.action()
check_fleet_edges(ai_settings, aliens)
check_alien_bottom(ai_settings, screen, stats, sb, ship, aliens, bullets)
aliens.update()
# 检测外星人和飞船之间的碰撞
if pygame.sprite.spritecollideany(ship, aliens):
ship_hit(ai_settings, screen, stats, sb, ship, aliens, bullets)
def update_screen(ai_settings, screen, stats, sb, ship, aliens, bullets, play_button,introduce_button,bomb):
"""更新屏幕上的图像,并切换到新屏幕"""
# 每次循环时都重绘屏幕
screen.fill(ai_settings.bg_color)
# 在飞船和外星人后面重绘所有子弹
for bullet in bullets.sprites():
bullet.draw_bullet()
ship.blitme()
aliens.draw(screen)
# 绘制爆炸图片
# # 绘制爆炸图片
#self.bomb.draw()
bomb.draw()
# 显示得分
sb.show_score()
# 如果游戏处于非活动状态,就绘制Play按钮
if not stats.game_active:
play_button.draw_button()
introduce_button.drawintroduce_button()
# 让最近绘制的屏幕可见
pygame.display.flip()
三.总结
1.创建bomb对象,我们可以仿照ship类去写
# 创建爆炸对象
bomb = Bomb(ai_settings,screen
2.bomb在哪使用?
我们绘制初场景时以及相关的事件检测(碰撞检测)
3.如何找到发生碰撞的坐标?
子弹打中外星人发生碰撞,我们要求碰撞位置,可以直接去求发生碰撞的子弹的位置,而碰撞子弹可以通过从子弹的group中遍历找到,找到碰撞坐标后我们把bomb的visible设为True(即可视)
注明:collisions = pygame.sprite.groupcollide(aliens, bullets, True, True)这里引用了碰撞检测函数
for bullet in bullets:
# 检查子弹与飞机的碰撞,及击中飞机
collisions = pygame.sprite.groupcollide(aliens, bullets, True, True)
if collisions:
current_pos = pygame.Vector2(bullet.rect.x, bullet.rect.y)
if bullet.rect.collidepoint(current_pos):
bomb.position[0] = (bullet.rect.x - 20)
bomb.position[1] = (bullet.rect.y - 40)
bomb.visible = True