碰撞检测后,飞机没有播放碰撞动画
来源:3-9 飞机大战项目飞机碰撞及爆炸效果
慕移动4586040
2020-05-14 21:54:03
##plane类
import random
import pygame
import constants
from game.bullet import Bullet
class Plane(pygame.sprite.Sprite):
"""飞机的基础类"""
#飞机图片
plane_images = []
#飞机爆炸的图片
destroy_images = []
#坠毁的音乐地址
down_sound_src = None
#飞机的状态 true表示活着,false表示毁灭
active = True
#该飞机发射的子弹精灵组
bullets = pygame.sprite.Group()
def __init__(self, screen, speed=None):
#调用父类
super().__init__()
self.screen = screen
#加载静态资源
self.img_list = []
self._destroy_img_list = []
self.down_sound = None
self.load_src()
#飞行的速度
self.speed = speed or 10
#获取飞机的位置
self.rect = self.img_list[0].get_rect()
#游戏窗口的宽高
self.width, self.height = self.screen.get_size()
#飞机本身的宽高
self.plane_w, self.plane_h = self.img_list[0].get_size()
# 改变飞机的初始化位置,放在屏幕下方
self.rect.left = int((self.width - self.plane_w)/2)
self.rect.top = int(self.height/2)
def load_src(self):
"""加载静态资源"""
#飞机图像
for img in self.plane_images:
self.img_list.append(pygame.image.load(img))
#飞机坠毁的图像
for img in self.destroy_images:
self._destroy_img_list.append(pygame.image.load(img))
#坠毁的音乐
if self.down_sound_src:
# self.down_sound = pygame.mixer.Sound(self.down_sound_src)
self.down_sound = pygame.mixer.Sound(self.down_sound_src)
@property
def image(self):
return self.img_list[0]
def blit_me(self):
self.screen.blit(self.image, self.rect)
def move_up(self):
"""
飞机向上移动
:return:
"""
self.rect.top -= self.speed
def move_down(self):
"""飞机向下移动"""
self.rect.top += self.speed
def move_left(self):
"""飞机向下移动"""
self.rect.left -= self.speed
def move_right(self):
"""飞机向下移动"""
self.rect.left += self.speed
def broken_down(self):
"""飞机坠毁效果"""
#1.播放坠毁音乐
if self.down_sound:
self.down_sound.play()
#2.播放坠毁动画
for img in self._destroy_img_list:
self.screen.blit(img, self.rect)
#3.坠毁后
self.active = False
def shoot(self):
"""飞机发射子弹"""
bullet = Bullet(self, self.screen, 15)
self.bullets.add(bullet)
pass
class OurPlane(Plane):
"""我方的飞机"""
#飞机图片
plane_images = constants.OUR_PLANE_IMG_LIST
destroy_images = []
#坠毁的音乐地址
down_sound_src = None
def update(self, war):
"""更新飞机的动画效果"""
#1.切换飞机动画效果
if war.frame % 5:
self.screen.blit(self.img_list[0], self.rect)
else:
self.screen.blit(self.img_list[1], self.rect)
#2.碰撞检测
rest = pygame.sprite.spritecollide(self, war.enemies, False)
if rest:
#1.游戏结束
war.status = war.OVER
#2.敌方所有飞机清除
war.enemies.empty()
war.small_enemies.empty()
#3.我方飞机坠毁效果
self.broken_down()
#4.游戏成绩统计
def move_up(self):
"""向上移动,超出范围之后,拉回来"""
super().move_up()
if self.rect.top <= 0:
self.rect.top = 0
def move_down(self):
super().move_down()
if self.rect.bottom >= self.height - self.plane_h:
self.rect.bottom = self.height - self.plane_h
def move_left(self):
super().move_left()
if self.rect.left <= 0:
self.rect.left = 0
def move_right(self):
super().move_right()
if self.rect.left >= self.width - self.plane_w:
self.rect.left = self.width - self.plane_w
class SmallEnemyPlane(Plane):
"""敌方小型飞机类"""
#飞机图片
plane_images = constants.SMALL_ENEMY_PLANE_IMG_LIST
#飞机爆炸的图片
destroy_images = constants.SMALL_ENEMY_DESTROY_IMG_LIST
#坠毁的音乐地址
down_sound_src = (constants.SMALL_ENEMY_DOWN_SOUND)
def __init__(self, screen, speed):
super().__init__(screen, speed)
#改变生成小型飞机时,要随机出现在屏幕中
#改变随机位置
self.init_pos()
def init_pos(self):
"""初始化飞机位置"""
# 屏幕宽度-飞机宽度
self.rect.left = random.randint(0, self.width - self.rect.width)
# 屏幕之外随机高度
self.rect.top = random.randint(-5 * self.plane_h, -self.plane_h)
def update(self, *args):
"""更新飞机的移动"""
super().move_down()
#绘制在p屏幕上
self.blit_me()
#超出范围
#1.重用
if self.rect.top >= self.height:
# self.kill()
self.reset()
#todo 2.多线程、多进程
def reset(self):
"""重置飞机状态,达到复用效果"""
self.active = True
#重置飞机
self.init_pos()
def broken_down(self):
"""重写父类爆炸效果"""
super().broken_down()
self.reset()
###war类
import pygame
import sys
import constants
from game.plane import OurPlane, SmallEnemyPlane
class PlaneWar(object):
READY = 0 #游戏准备中
PLAY = 1 #正在游戏中
OVER = 2 #游戏结束
#游戏状态
status = READY #准备中 1游戏中 2游戏结束
#实例化我方飞机
our_plane = None
#播放帧数
frame = 0
#一架飞机可以属于多个精灵组
small_enemies = pygame.sprite.Group()
enemies = pygame.sprite.Group()
def __init__(self):
#初始化方法
pygame.init()
self.width, self.height = 480, 852
# 屏幕对象
self.screen = pygame.display.set_mode((self.width, self.height))
# 设置窗口标题
pygame.display.set_caption('飞机大战')
# 加载背景图片
self.bg = pygame.image.load(constants.BG_IMG)
# 游戏标题图片
self.img_game_title = pygame.image.load(constants.IMG_GAME_TITLE)
self.img_game_title_rect = self.img_game_title.get_rect()
# 游戏标题图片宽高
t_width, t_height = self.img_game_title.get_size()
self.img_game_title_rect.topleft = (int((self.width - t_width) / 2),
int(self.height / 2 - t_height))
# 开始按钮图片
self.btn_start = pygame.image.load(constants.IMG_GAME_START_BTN)
self.btn_start_rect = self.btn_start.get_rect()
btn_width, btn_height = self.btn_start.get_size()
self.btn_start_rect.topleft = (int((self.width - btn_width) / 2),
int(self.height / 2 + btn_height))
# 加载背景音乐
pygame.mixer.music.load(constants.BG_MUSIC)
# 无限循环播放
pygame.mixer.music.play(-1)
# 调整音乐播放音量
pygame.mixer.music.set_volume(20)
#我方飞机对象
self.our_plane = OurPlane(self.screen, speed = 20)
self.clock = pygame.time.Clock()
def bind_event(self):
"""绑定事件"""
# 1.监听事件
for event in pygame.event.get():
# 退出游戏
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
elif event.type == pygame.MOUSEBUTTONDOWN:
# 鼠标点击进入游戏
# 游戏正在准备中, 点击才能进入游戏
if self.status == self.READY:
self.status = self.PLAY
elif event.type == pygame.KEYDOWN:
# 键盘事件
# 游戏正在游戏中,才能够控制键盘事件
if self.status == self.PLAY:
if event.key == pygame.K_w or event.key == pygame.K_UP:
self.our_plane.move_up()
elif event.key == pygame.K_s or event.key == pygame.K_DOWN:
self.our_plane.move_down()
elif event.key == pygame.K_a or event.key == pygame.K_LEFT:
self.our_plane.move_left()
elif event.key == pygame.K_d or event.key == pygame.K_RIGHT:
self.our_plane.move_right()
elif event.key == pygame.K_SPACE:
# 发射子弹
self.our_plane.shoot()
def add_small_enemies(self, num):
"""
:param num: 飞机产生数量
:return:
"""
# 随机添加num架小型敌机
for i in range(num):
plane = SmallEnemyPlane(self.screen, 8)
plane.add(self.small_enemies, self.enemies)
def run_game(self):
"""游戏主循环"""
while True:
#1 设置帧速率
self.clock.tick(60)
self.frame += 1
if self.frame >= 60:
self.frame = 0
#2 绑定事件
self.bind_event()
# 3 更新游戏的状态
if self.status == self.READY:
# 游戏正在准备中
# 绘制背景
self.screen.blit(self.bg, self.bg.get_rect())
# 标题
self.screen.blit(self.img_game_title, self.img_game_title_rect)
# 开始按钮
self.screen.blit(self.btn_start, self.btn_start_rect)
pygame.display.flip()
elif self.status == self.PLAY:
# 游戏进行中
# 绘制背景
self.screen.blit(self.bg, self.bg.get_rect())
# 绘制飞机
self.our_plane.update(self)
# 绘制子弹
self.our_plane.bullets.update(self)
# 绘制敌方飞机
self.small_enemies.update()
pygame.display.flip()
# #绘制游戏的状态
# screen.blit(bg,bg.get_rect())
# #更新屏幕
# pygame.display.flip()
###bullets
import pygame
import constants
class Bullet(pygame.sprite.Sprite):
"""子弹类"""
#子弹状态 True 活的;
active = True
def __init__(self, plane, screen, speed= None):
super().__init__()
self.screen = screen
#速度
self.speed = speed or 10
self.plane = plane
#加载子弹图片
self.image = pygame.image.load(constants.BULLET_IMG)
#改变子弹的位置
self.rect = self.image.get_rect()
self.rect.centerx = plane.rect.centerx
self.rect.top = plane.rect.top
#发射的音乐效果
self.shoot_sound = pygame.mixer.Sound(constants.BULLET_SHOOT_SOUND)
self.shoot_sound.set_volume(0.3)
self.shoot_sound.play()
def update(self, war):
"""更新子弹位置"""
self.rect.top -= self.speed
#超出屏幕范围
if self.rect.top < 0:
self.remove(self.plane.bullets)
print(self.plane.bullets)
#绘制子弹
self.screen.blit(self.image, self.rect)
#碰撞检测,检测子弹是否碰撞到了敌机
rest = pygame.sprite.spritecollide(self, war.enemies, False)
print(rest, 666)
for r in rest:
#1.子弹消失
self.kill()
#2.飞机爆炸 坠毁
r.broken_down()
#3.统计游戏成绩
####main
import sys
import pygame
import constants
from game.plane import Plane, OurPlane, SmallEnemyPlane
from game.war import PlaneWar
def main():
"""游戏入口,main方法"""
war = PlaneWar()
#添加小型敌方飞机
war.add_small_enemies(6)
war.run_game()
if __name__ == '__main__':
main()
####constants
import os
#项目根目录
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
#静态文件目录
ASSETS_DIR = os.path.join(BASE_DIR, 'assets')
#背景图片
BG_IMG = os.path.join(ASSETS_DIR, 'images\\background.png')
#标题图片
IMG_GAME_TITLE = os.path.join(ASSETS_DIR, 'images\\game_title.png')
#游戏按钮图片
IMG_GAME_START_BTN = os.path.join(ASSETS_DIR, 'images\\game_start.png')
#背景音乐
BG_MUSIC = os.path.join(ASSETS_DIR, 'sounds\\game_bg_music.mp3')
#我方飞机的静态资源
OUR_PLANE_IMG_LIST = [os.path.join(ASSETS_DIR,'images\\hero1.png'),os.path.join(ASSETS_DIR,'images\\hero2.png')]
OUR_DESTROY_IMG_LIST = [
os.path.join(ASSETS_DIR,'images\\hero_broken_n1.png'),
os.path.join(ASSETS_DIR,'images\\hero_broken_n2.png'),
os.path.join(ASSETS_DIR,'images\\hero_broken_n3.png'),
os.path.join(ASSETS_DIR,'images\\hero_broken_n4.png')]
#子弹图片和发射声音
BULLET_IMG = os.path.join(ASSETS_DIR, 'images\\bullet1.png')
BULLET_SHOOT_SOUND = os.path.join(ASSETS_DIR, 'sounds\\bullet.wav')
#敌方小型飞机图片及音效
SMALL_ENEMY_PLANE_IMG_LIST = [os.path.join(ASSETS_DIR, 'images\\enemy1.png')]
SMALL_ENEMY_DESTROY_IMG_LIST = [
os.path.join(ASSETS_DIR,'images\\enemy1_down1.png'),
os.path.join(ASSETS_DIR,'images\\enemy1_down2.png'),
os.path.join(ASSETS_DIR,'images\\enemy1_down3.png'),
os.path.join(ASSETS_DIR,'images\\enemy1_down4.png')]
#小型飞机坠毁音效
SMALL_ENEMY_DOWN_SOUND = (os.path.join(ASSETS_DIR,'sounds\\enemy1_down.wav'))
请问老师,为什么碰撞检测后调用坠毁动画等失败?
1回答
好帮手慕觉浅
2020-05-15
同学你好:在plane.py中的OuoPlane类里destroy_images需要赋值为constants.OUR_DESTROY_IMG_LIST,而不是空列表。就是因为这里图片没有添加进来因此无法播放碰撞后的图片的。修改后即可正常播放。
如果解决了你的疑惑,请采纳,祝学习愉快~
相似问题