老师帮我看看这个错在哪?

来源: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.统计游戏成绩


http://img.mukewang.com/climg/5eba1bf509db37b112870558.jpg

写回答

2回答

好帮手慕觉浅

2020-05-12

同学你好:那就换实参为self,下图里的update()不变,还使用war

http://img.mukewang.com/climg/5eba71b609c33eeb06480255.jpg

改变调用时传入的实参为self,表示实例对象本身。

http://img.mukewang.com/climg/5eba725f09346f1707580268.jpg

后面还有一个错误,PlaneWar类这里需要改成全大写的OVER,如下图:

http://img.mukewang.com/climg/5eba72ab09a5f05403460208.jpg

如果解决了你的疑惑,请采纳,祝学习愉快~


0

好帮手慕觉浅

2020-05-12

同学你好:根据错误提示找到plane.py中119行:

http://img.mukewang.com/climg/5eba55350997f0d212370504.jpg

因为在调用时使用的是self.our_plane.update(self.frame),传入的直接是frame,而在OurPlane类中update()的参数是war,之后使用war.frame调用frame,传入的参数不匹配,所以报错了。需要修改update()的参数为frame,判断时直接使用if frame % 5即可。如下图:

http://img.mukewang.com/climg/5eba566c0929713d04650142.jpg

如果解决了你的疑惑,请采纳,祝学习愉快~


0
hawn_2020
h 老师改了这个参数,后面也报错呀
h020-05-12
共1条回复

0 学习 · 8160 问题

查看课程