美文网首页
面向对象的飞机大战编程

面向对象的飞机大战编程

作者: 超人不会飞_9664 | 来源:发表于2019-02-01 13:57 被阅读0次

    游戏框架分为两部分

    1.创建一个plane_main.py的主文件,写出一个PlaneGame的主类。

    import pygame
    class PlaneGmae(object):
        def __init__(self):
            print('游戏初始化...')
        def start_game(self):
            print('游戏开始...')
    if __name__ == '__main__':
        # 创建游戏对象
        game = PlaneGmae()
        # 启动游戏
        game.start_game()
    

    运行结果为

    D:\python\python36\python.exe D:/PycharmProjects/feijidazhan_1/feiji.py
    游戏初始化...
    游戏开始...
    

    2.另新建一个plane_sprite.py 的模块

    import pygame
    class Game_Sprite(pygame.sprite.Sprite):#派生精灵子类
        '''飞机大战游戏精灵'''
        def __init__(self,image_name,speed = 1):
            # 继承父类的__init__()
            super().__init__()
            # 定义对象的属性
            self.image =pygame.image.load(image_name)
            self.rect = self.image.get_rect()
            '''self.image的get_rect()返回pygame.Rect(0,0,width,height)'''
            self.speed = speed
            def update(self):
               self.rect.y += self.speed
    

    3. 主程序中设置游戏初始化的步骤

    class PlaneGmae(object):
        def __init__(self):
            print('游戏初始化...')
            # 1.创建游戏屏幕
            self.screen = pygame.display.set_mode(SCREEN_RECT.size) #引入的常量
            # 2.创建游戏时钟
            self.clock = pygame.time.Clock()
            # 3.私有方法创建精灵和精灵组
            self.__creat_sprite()
        def __creat_sprite(self):
            pass
    

    4主程序中游戏的开始部分的步骤

    class PlaneGmae(object):
        游戏初始化部分...
        .......
        def start_game(self):
            print('游戏开始...')
            while True:
                # 1.设置帧率
                self.clock.tick(60)
                # 2. 事件监听
                self.__event_monitor()
                # 3. 碰撞检测
                self.__check_collide()
                # 4. 绘制图像
                self.__blit_photo()
                # 5.刷新显示
                pygame.display.update()
    

    5.为了让程序可读性高,便于维护,建议是使用私有方法,由于上面的四个步骤都是私有方法,所以接下来在上面的主要类开始布置私有方法

        def __event_monitor(self):
            pass
        def __check_collide(self):
            pass
        def __blit_photo(self):
            pass
        @staticmethod
        def __game_over():
            print('退出游戏')
            # 卸载所有模块
            pygame.quit()
            # 退出程序
            exit()
    
    • 需要注意的上面有一个静态方法,由于这个方法调用这个类里的任何方法和属性,所以要把它编程静态方法,加修饰符@staticmethod 不用加self参数
    • 代码走到上面的这些就已经把飞机大战的游戏的整体框架搞定了
      shift+f10 执行一下代码,显示为:
    image.png

    6.接下来我们开始布置背景图(这里用到一个小套路,让背景图在垂直方向上移动,这样就可以让英雄飞机相对运动了)

    1.在模块文档那里开始写背景类

    class Background(Game_Sprite):
        def __init__(self,is_alt = False):
            super().__init__('./images/background.png')
            if is_alt:
                self.rect.bottom = 0
        def  update(self):
            # 让屏幕往下移动,所以可以用到父类的方法。所以可以继承
            super().update()
            # 判断底部照片是否超出屏幕
            if self.rect.y > SCREEN_RECT.height:
                self.rect.y =-SCREEN_RECT.height
    

    2.回到主程序中的初始化部分那里,开始填写__creat_sprite()私有方法

     def __creat_sprite(self):
            # 创造背景精灵和精灵组
            bg1 = Background()
            bg2 = Background(True)
            self.bg_group = pygame.sprite.Group(bg1,bg2)
    

    3.回到主程序中游戏开始部分那里,self.__blit_photo() 图像绘制更新那里

        def __blit_photo(self):
            # 背景图片的绘制
            self.bg_group.update()
            self.bg_group.draw(self.screen)
    

    shift+f10 运行的效果是一向下移动的背景图

    7.为了方便后面测试程序,我们在这里就开始写事件监听的代码,一旦检测到退出的信号就直接退出

        def __event_monitor(self):
            for event in pygame.event.get():
                # 判断监听是否有退出动作
                if event.type == pygame.QUIT:
                    PlaneGmae. __game_over()
    
    • 注意静态方法的调用是直接类名.方法名

    8.敌机的类的填写以及精灵类和精灵组的填写(由于敌机较多,要用到定时器)

    class Enemy(Game_Sprite):
        def __init__(self):
            super().__init__('./images/enemy1')
            # 敌机初始化位置
            # 1.x轴上的随机位置
            Max_x = SCREEN_RECT.width-self.rect.width
            self.rect.x = random.randint(0,Max_x)
            # 2.y轴上的随机位置
            self.rect.bottom = 0
            # 初始速度的设置
            self.speed = random.randint(1,3)
        def update(self):
            # 继承父类的update让敌机向下移动
            super().update()
            # 判断敌机是否超出屏幕
            if self.rect.y > SCREEN_RECT.height:
                self.kill()
        def __del__(self):
            print('敌机挂了%s' % self.rect)
    

    1.敌机定时器的三步骤:
    a.在模块文件中写出定时器常量 eg:XXX = pygame.USEREVENT
    b.在主程序的初始化中

    pygame.time.set_timer(CREAT_TIMER,1000)
    

    其中1000指的1000毫秒也就是1秒执行一个定时器的动作
    c.在事件监听里

                elif event.type == CREAT_TIMER:
                    print('产生敌机...')
    

    那样就可以1秒一个敌机出现
    2.开始在初始化位置创建精灵组

    # 创建敌机精灵组
           self.enemy_group = pygame.sprite.Group()
    

    3.在事件监听那里去写精灵组,因为这是持续不断的要精灵组的

     elif event.type == CREAT_TIMER:
                    print('产生敌机...')
                    # 敌机精灵
                    enemy = Enemy()
    
                    # 敌机精灵组
                    self.enemy_group.add(enemy)
    

    4.将敌机精灵组进行绘制

     # 敌机的绘制
            self.enemy_group.update()
            self.enemy_group.draw(self.screen)
    
    • 此时屏幕开始持续出现敌机


      image.png

    9.开始英雄的类已经精灵的布置

    class Hero(Game_Sprite):
        # 继承父类,设置imgae和speed
        def __init__(self):
            super().__init__('./images/me1.png',0)
            # 确定好英雄的初始位置
            self.rect.centerx = SCREEN_RECT.centerx
            self.rect.bottom = SCREEN_RECT.bottom-120
    
    • 在创建精灵的私有方法里开始创建英雄的精灵和精灵组
    # 创建英雄精灵和精灵组
           self. hero_sprite = Hero()  #此对象要在其他方法被调用所以加self
            self.hero_sprite_group = pygame.sprite.Group(hero_sprite)
    
    • 绘制图像
     # 英雄的绘制
            self.hero_sprite_group.update()
            self.hero_sprite_group.draw(self.screen)
    
    • shift + f10


      image.png

    10.开始让飞机在左右移动但是不能超出左右边界

    • 1.使用键盘按键获取按键元组
    # 使用键盘方法获取按键元组
            keys_pressed = pygame.key.get_pressed()
            # 判断元组中对应按键索引值
            if keys_pressed[pygame.K_RIGHT]:
                self.hero_sprite.speed = 2
            elif keys_pressed[pygame.K_LEFT]:
                self.hero_sprite.speed = -2
            else:
                self.hero_sprite.speed = 0
    
    • 这个按键元组的value值是1时键值就是左右的一种

    • 此时的Hero类

    class Hero(Game_Sprite):
        # 继承父类,设置imgae和speed
        def __init__(self):
            super().__init__('./images/me1.png',0)
            # 确定好英雄的初始位置
            self.rect.centerx = SCREEN_RECT.centerx
            self.rect.bottom = SCREEN_RECT.bottom-120
        def update(self):
            # 因为是左右移动,所以可以完全改写父类方法
            self.rect.x += self.speed
    
            # 判断英雄飞机是否飞出屏幕外
            if self.rect.x < 0:
                self.rect.x = 0
            elif self.rect.x > SCREEN_RECT.width-self.rect.width:
                self.rect.right = SCREEN_RECT.right
    
    • 此时的效果为,英雄可以左右移动但不会超出边界


      image.png

    11.开始设置子弹

    • 1.设置子弹的类
    class Bullet(Game_Sprite):
        def __init__(self):
            # 继承父类,加载图片
            super().__init__('./images/bullet1.png',-2)
            # 初始位置先不要管,等到英雄类里再去弄
        def update(self):
            # 继承父类方法,让子弹移动
            super().update()
    
            # 判断子弹是否超出屏幕
            if self.rect.bottom < 0:
                self.kill()
        def __del__(self):
            print('超出子弹被销毁%s'%self.rect)
    

    注意下,这里不要设置子弹的初始位置,因为子弹的初始位置是要和英雄一起弄得

    • 2.设置子弹的定时器
    # 子弹常量
    HERO_FIRE = pygame.USEREVENT+1
    
     # 5. 发射子弹的定时器调用
            pygame.time.set_timer(HERO_FIRE,500)
    
     elif event.type ==  HERO_FIRE:
                    self.hero_sprite.fire()
    

    考虑到子弹是要和英雄一起弄的,我们把创建子弹精灵和精灵组放到英雄类中去

      1. 在英雄的类初始化方法里设置子弹精灵组
    class Hero(Game_Sprite):
        # 继承父类,设置imgae和speed
        def __init__(self):
            super().__init__('./images/me1.png',0)
            # 确定好英雄的初始位置
            self.rect.centerx = SCREEN_RECT.centerx
            self.rect.bottom = SCREEN_RECT.bottom-120
    
            # 创建子弹精灵组
            self.bullets = pygame.sprite.Group()
    
    • 4 .开始设置在英雄类里设置fire()方法
                elif event.type ==  HERO_FIRE:
                    self.hero_sprite.fire()
    
    def fire(self):
          print('发射子弹...')
          for i in range(3):
              # 创建子弹精灵
              bullet = Bullet()
              # 设置子弹的初始位置
              bullet.rect.bottom = self.rect.y- i*20
              bullet.rect.centerx = self.rect.centerx
              # 设置子弹的精灵组
              self.bullets.add(bullet)
    
    • 5 .开始将子弹精灵组放到绘制图像的方法里
     # 子弹的绘制
            self.hero_sprite.bullets.update()
            self.hero_sprite.bullets.draw(self.screen)
    

    呈现的效果为


    image.png

    12.开始碰撞检测

     def __check_collide(self):
            # 子弹碰到飞机
            pygame.sprite.groupcollide(self.hero_sprite.bullets,self.enemy_group,True,True)
            # 敌机撞毁飞机
            enemies = pygame.sprite.spritecollide(self.hero_sprite, self.enemy_group, True)
            # 判断列表是否有内容
            if len(enemies) > 0:
                # 让英雄牺牲
                self.hero_sprite.kill()
    
                # 结束游戏
                PlaneGmae.__game_over()
    

    shift +f10


    image.png

    碰撞的基础知识

    image.png image.png

    相关文章

      网友评论

          本文标题:面向对象的飞机大战编程

          本文链接:https://www.haomeiwen.com/subject/ilqnjqtx.html