飞机大战实现效果问题

飞机大战实现效果问题

plane.py中:


import pygame

import constants
from game.bullet import Bullet


class Plane(pygame.sprite.Sprite):
   #飞机图片
   plane_images = []
   # 飞机爆炸的图片
   desk = []
   # 坠毁的音乐地址
   scr = None
   #存活状态
   active = True
   #子弹发射精灵组
   bullets = pygame.sprite.Group()
   #(3)自定义初始化方法:参数--为屏幕对象(screen)、
   # 移动速度(speed=None);实例属性--屏幕对象screen、
   # 飞机图片静态资源列表img_list、飞机速度speed、飞机位置rect;
   def __init__(self,screen,speed = None):

       super().__init__()

       self.screen = screen

       #飞机图片静态资源列表
       self.img_list = []
       self.troy = []
       self.down = None
       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_rect()

       self.width,self.height = self.screen.get_size()
       #通过飞机位置rect和屏幕对象
       # screen获取飞机的宽plane_w高plane_h及游戏窗口宽width高height;
       self.rect.left = int((self.width - self.plane_w) / 2)
       self.rect.top = int(self.height / 2)

   #静态资源加载方法load_src,加载飞机图片资源并保存至img_list
   def load_src(self):
       for img in self.plane_images:
           self.img_list.append(pygame.image.load(img))
       for img in self.desk:
           self.troy.append(pygame.image.load(img))
       if self.scr:
           self.down = pygame.mixer.Sound(self.scr)
   @property
   #以属性访问方式定义方法image,返回img_list中保存的第一个元素
   def image(self):
       return self.img_list[0]
   #飞机绘制方法blit_me,将飞机图片绘制在rect位置
   def blit_me(self):
       self.screen.blit(self.image,self.rect)

   #(7)飞机上移方法move_up、下移方法move_down、
   # 左移方法move_left、右移方法move_right,
   # 根据飞机速度重新设置距离游戏窗口上边框和左边框的距离;
   def move_up(self):
       self.screen.top -= self.speed

   def move_down(self):
       self.screen.top += self.speed

   def move_left(self):
       self.screen.left -= self.speed

   def move_right(self):
       self.screen.left += self.screen

   def shoot(self):
       #子弹发射方法shoot,创建子弹对象并添加至类属性bullets中
       bull = Bullet(self.screen,self,30)
       self.bullets.add(bull)



'''(1)我方飞机类OurPlane,继承自飞机类Plane'''
class OurPlane(Plane):
   '''(2)设置类属性plane_images,
   值为constants.py中我方飞机图片资源路径(2个)
   '''
   plane_images = constants.OUR_PLANE_IMG_1,constants.OUR_PLANE_IMG_2

   def update(self, frame):
       ''' (3)更新飞机动画效果方法update,参数为播放帧数frame,
       当frame能5整除时,屏幕绘制飞机图片资源列表中的第一个;
       反之,屏幕绘制飞机图片资源列表中的第二个'''
       if frame % 5:
           self.screen.blit(self.img_list[0], self.rect)
       else:
           self.screen.blit(self.img_list[1], self.rect)


   #4)重写飞机上移方法move_up、下移方法move_down、
   # 左移方法move_left、右移方法move_right,
   # 确保飞机在移动时不会超出游戏窗口
   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

main.py中:


import pygame,sys

import constants
from game.plane import OurPlane


def main():

   # 初始化pygame
   pygame.init()

   #设置游戏屏幕宽width和高height
   width,height = 480,852#根据背景图片的大小定制

   #窗口对象的大小
   windows = pygame.display.set_mode((width,height))

   #屏幕窗口标题“飞机大战”
   pygame.display.set_caption('飞机大战')

   # 加载游戏背景图片bg
   bg = pygame.image.load(constants.BG_IMG)

   # 加载游戏标题的图片img_game_title
   img_game_title = pygame.image.load(constants.IMG_GAME_TITLE)
   img_game_title_rect = img_game_title.get_rect()


   #并获取其宽t_width、高t_height
   t_width,t_height = img_game_title.get_size()

   # 获取img_game_title的矩形区域,记录为img_game_title_rect
   # 并设置img_game_title_rect使其位于游戏屏幕的正中央
   img_game_title_rect.topleft = (int((width - t_width) / 2),int(height / 2 - t_height))

   # 加载游戏开始按钮btn_start
   btn_start = pygame.image.load(constants.IMG_GAME_START_BTN)

   btn_kai = btn_start.get_rect()

   #并设置其宽btn_width、高btn_height
   btn_width,btn_height = btn_start.get_size()

   btn_kai.topleft = (int((width - btn_width) / 2),
                       int(height / 2 + btn_height))

   # 加载游戏背景音乐,设置无限播放模式
   pygame.mixer.music.load(constants.BG_MUSIC)
   pygame.mixer.music.play(-1)
   pygame.mixer.music.set_volume(0.5)

   #设置记录游戏状态的status变量
   status = 0

   #播放帧数frame变量
   frame = 0

   #初始化我方飞机(OurPlane)对象,传入<2>中的屏幕对象
   our_plane = OurPlane(windows)

   #设置时间
   clock = pygame.time.Clock()

   #(11)开启while循环,设置帧速率为60,
   # 播放帧数frame循坏于(1到60之间),
   # 监听键盘事件(游戏退出、进入,游戏过程中控制飞机上下左右移动)
   # 并根据游戏状态值status分别绘制对应status下的游戏窗口中的元素

   while True:

       clock.tick(60)

       frame += 1

       if frame >= 60:
           frame = 0

       for event in pygame.event.get():
           # 退出游戏
           if event.type == pygame.QUIT:
               pygame.quit()
               sys.exit()

           elif event.type == pygame.MOUSEBUTTONDOWN:
               if  status == 0:
                   status = 1

           elif event.type == pygame.KEYDOWN:
               #键盘事件(WASD)
               if status == 1:
                   if event.key == pygame.k_w or event.key == pygame.k_UP:
                       our_plane.move_up()
                   elif event.key == pygame.k_s or event.key == pygame.k_DOWN:
                       our_plane.move_down()
                   elif event.key == pygame.k_a or event.key == pygame.k_LEFT:
                       our_plane.move_left()
                   elif event.key == pygame.k_d or event.key == pygame.k_RIGHT:
                       #发射子弹
                       our_plane.move_right()
       #游戏更新
       if status == 0:
           # 游戏正在准备中
           # 绘制背景
           windows.blit(bg,bg.get_rect())
           # 标题
           windows.blit(img_game_title,img_game_title_rect)
           # 开始按钮
           windows.blit(btn_start,btn_kai)
       elif status == 1:
           # 游戏进行中
           # 绘制背景
           windows.blit(bg,bg.get_rect())
           # 绘制飞机
           our_plane.update(frame)
           #绘制子弹
           our_plane.bullets.update()

       pygame.display.flip()


if __name__ == "__main__":
   main()


bullet.py中:

import pygame


#1)子弹类Bullet,继承自(pygame.sprite.Sprite)
# ,设置类属性active记录存活状态,默认为True;
import constants


class Bullet(pygame.sprite.Sprite):

   active = True

   #(2)自定义初始化方法,参数为屏幕对象screen、飞机plane、
   # 移动速度(speed=None),设置实例属性屏幕对象screen、
   # 子弹运行速度speed、飞机plane、子弹图片静态资源列表image子弹位置rect。
   # 通过rect获取子弹的中心点rect.centerx和距离上边距距离rect.top
   def __init__(self,screen,plane,speed = None):
       super().__init__()

       self.speed = speed or 10

       self.screen = screen

       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 = self.rect.top

       #并设置属性shoot_sound获取加载的子弹发射音效资源,最终进行播放
       self.shoot_sound = pygame.mixer.Sound(constants.BULLET_SHOOT_SOUND)

       self.shoot_sound.set_volume(0.5)

       self.shoot_sound.play()

   #(3)自定义子弹位置更新方法update,参数为(*args),
   # 根据子弹运行速度更新其位置,当子弹运行超出游戏窗口时,
   # 从精灵组中进行移除
   def update(self, *args):

       self.rect.top -= self.speed

       if self.rect.top < 0:

           self.remove(self.plane.bullets)

       self.screen.blit(self.image,self.rect)

constants.py中:

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_1 = os.path.join(ASSETS_DIR, 'images/hero1.png')
OUR_PLANE_IMG_2 = 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')

老师,报错的地方是怎么回事?请解释一下

http://img1.sycdn.imooc.com//climg/5e26b37f09ed627b09140262.jpg

正在回答

登陆购买课程后可参与讨论,去登陆

1回答

同学,你好。执行同学提供的代码没有报相应的错误,报的是其他的错误。

1、飞机的宽度和高度应使用get_size()

http://img1.sycdn.imooc.com//climg/5e26b751099e37aa06420058.jpg

2、在飞机移动时,应是rect飞机的位置得到对应的top或left值

http://img1.sycdn.imooc.com//climg/5e26b7820950a44e04290372.jpg

3、在按键盘上下左右移动时,K应该是大写

http://img1.sycdn.imooc.com//climg/5e26b87a09a5f19107280314.jpg

同学可根据上述方法修改后运行下程序看是否还有相应错误。若有同学可将具体的操作描述下。

如果我的回答解决了您的疑惑,请采纳!祝学习愉快~~~~

  • Kepler_ 提问者 #1
    老师更改过来之后还是不行!还是报一样的错误!
    2020-01-21 18:37:29
  • 时间, 回复 提问者 Kepler_ #2
    同学,你好。已经在同学的新问答中给出解决方案,同学可根据回答中的方法进行修改。问答连接如下:https://class.imooc.com/course/qadetail/187320。祝学习愉快~~~~
    2020-01-22 10:22:16
问题已解决,确定采纳
还有疑问,暂不采纳

恭喜解决一个难题,获得1积分~

来为老师/同学的回答评分吧

0 星
1.Python零基础入门
  • 参与学习           人
  • 提交作业       2727    份
  • 解答问题       8160    个

想要进入Python Web、爬虫、人工智能等高薪领域,你需要掌握本阶段的Python基础知识,课程安排带你高效学习轻松入门,学完你也能听得懂Python工程师的行业梗。

了解课程
请稍等 ...
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号

在线咨询

领取优惠

免费试听

领取大纲

扫描二维码,添加
你的专属老师