老师帮我看看这个错在哪?
来源:3-9 飞机大战项目飞机碰撞及爆炸效果
Dawn_2020
2020-05-12 11:45:59
"""
飞机的基类
我方飞机 敌方小型飞机 敌方中型飞机 敌方大型飞机
"""
import random
import pygame,constants
from game.bullet import Bullet
class Plane(pygame.sprite.Sprite):
"""
飞机基础类
"""
#飞机图片
plane_images = []
#飞机爆炸的图片
destory_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._destory_img_list = []
self.down_sound = []
self.load_src()
#飞行的速度
self.speed = speed or 10
#获取飞机的位置
self.rect = self.img_list[0].get_rect()
#飞机的宽度和高度
self.plane_w,self.plane_h = self.img_list[0].get_size()
#游戏窗口的宽度和高度
self.width,self.height = self.screen.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.destory_images:
self._destory_img_list.append(pygame.image.load(img))
#坠毁的音乐
if 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):
"""飞机向上移动"""
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._destory_img_list:
self.screen.blit(img,self.rect)
#坠毁后
self.active = False
def shoot(self):
"""飞机发射子弹"""
#self为飞机
bullet = Bullet(self.screen,self,15)
self.bullets.add(bullet)#bullets为子弹精灵组
class Ourplane(Plane):
"""我方飞机"""
#飞机图片
plane_images = constants.OUR_PLANE_IMG_LIST
#飞机爆炸图片
destory_images = constants.OUR_DESTROY_IMG_LIST
#坠毁音乐地址
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)
#飞机撞击检测,第一个self为我方的飞机
rest = pygame.sprite.spritecollide(self,war.enemies,False)
if rest:
#1.游戏结束
war.status = war.OVER
#2.敌方所有飞机清除
war.enemies.empty()#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.top >= self.height - self.plane_h:
self.rect.top = 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
# 飞机爆炸的图片
destory_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.plane_w)
#在屏幕上方,所以为负值,每一排摆五架
self.rect.top = random.randint(-5*self.plane_h,-self.plane_h)
def update(self,war):
"""更新飞机的移动,不需要考虑边界问题"""
super().move_down()
#画在屏幕上。调用父类父类方法
self.blit_me()
#超出范围后如何处理
#1.重用
if self.rect.top >= self.height:
self.active = False
#调用函数kill系统会自己移除精灵
#self.kill()
self.reset()
#2.多线程,多进程
def reset(self):
"""重置飞机的状态,达到复用的效果"""
self.active = True
self.init_pos() # 调用该方法即可
def broken_down(self):
"""飞机爆炸"""
super().broken_down()
"""重复利用飞机对象"""
self.reset()
---------------------------------------------------------------------------------------------
#war
import pygame,sys
import constants
from game.plane import Ourplane,SmallEnemyPlane
class PlaneWar(object):
"""飞机大战"""
# 游戏状态
READY = 0 #游戏准备中
PLAYING = 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.img_game_start = pygame.image.load(constants.IMG_GAME_START)
self.img_game_start_rect = self.img_game_start.get_rect()
self.start_weigh, start_height = self.img_game_start.get_size()
self.img_game_start_rect.topleft = (int((self.width - start_height) / 2),
int(self.height / 2 + start_height))
# 加载背景音乐
pygame.mixer_music.load(constants.BG_MUSIC)
pygame.mixer_music.play(-1) # 无限循环播放
pygame.mixer_music.set_volume(0.5) # 设置音量
#我方飞机对象
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.PLAYING
elif event.type == pygame.KEYDOWN:
# 键盘事件
# 游戏进行中,才需要控制键盘 ASDW
if self.status == self.PLAYING:
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_enemy(self,num):
#随机添加num架飞机
for i in range(num):
plane = SmallEnemyPlane(self.screen, 6)
plane.add(self.small_enemies, self.enemies)
def run_game(self):
"""游戏主体循环部分 """
while 1:
"""绑定事件"""
# 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.img_game_start, self.img_game_start_rect)
elif self.status == self.PLAYING:
# 游戏进行中
# 绘制背景
self.screen.blit(self.bg, self.bg.get_rect())
# 绘制飞机
self.our_plane.update(self.frame)
# 绘制子弹
self.our_plane.bullets.update(self) # 会调用各个精灵update()的方法
# 绘制敌方飞机
self.small_enemies.update(self)
# 3.绘制
pygame.display.flip()
-------------------------------------------------------------------------------
#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 = os.path.join(ASSETS_DIR,"images/game_start.png")
#背景音乐
BG_MUSIC = os.path.join(ASSETS_DIR,"sound/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,"sound/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,"sound/enemy1_down.wav")
----------------------------------------------------------------------------
#main
import pygame,sys,constants
from game.plane import Ourplane,SmallEnemyPlane
from game.war import PlaneWar
def main():
"""游戏入口,main方法"""
war=PlaneWar()
#添加小型飞机
war.add_small_enemy(6)
war.run_game()
if __name__ == "__main__":
main()
---------------------------------------------------------------------
#bullet
import pygame
import constants
class Bullet(pygame.sprite.Sprite):
"""子弹精灵类"""
#子弹状态,True:活的,
active = True
def __init__(self,screen,plane,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)
#绘制子弹,self.image表示子弹图片,self.rect图像坐标
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.统计游戏成绩
2回答
好帮手慕觉浅
2020-05-12
同学你好:那就换实参为self,下图里的update()不变,还使用war
改变调用时传入的实参为self,表示实例对象本身。
后面还有一个错误,PlaneWar类这里需要改成全大写的OVER,如下图:
如果解决了你的疑惑,请采纳,祝学习愉快~
好帮手慕觉浅
2020-05-12
同学你好:根据错误提示找到plane.py中119行:
因为在调用时使用的是self.our_plane.update(self.frame),传入的直接是frame,而在OurPlane类中update()的参数是war,之后使用war.frame调用frame,传入的参数不匹配,所以报错了。需要修改update()的参数为frame,判断时直接使用if frame % 5即可。如下图:
如果解决了你的疑惑,请采纳,祝学习愉快~
相似问题