zoukankan      html  css  js  c++  java
  • 二、飞机大战终极版-巩固面向对象设计项目的思想

    上面一节主要介绍pygame入门,这一节是利用面向对象完成整个项目设计:子弹射击敌机,战机碰撞敌机,用户左右控制战机移动等等

     

    1、知识点:pygame中提供了俩个非常强大的类精灵类和精灵组类:

              精灵类可以创建很多对象,例如:创建多个敌机,是用精灵类创建方便快速,代码简洁

       精灵组可以接受多个精灵类创建的对象,并且可以一次性将多个对象一次性绘制到屏幕

    首先创建一个plane_sprites模块,所有创建的敌机精灵,战机精灵,子弹精灵等类都写在此文件:
    import pygame
    import random
    
    """pygame中提供了俩个非常强大的类精灵类和精灵组类
       精灵类可以创建很多对象,例如:创建多个敌机,是用精灵类创建方便快速,代码简洁
       精灵组可以接受多个精灵类创建的对象,并且可以一次性将多个对象一次性绘制到屏幕
    """
    SCREEN=pygame.Rect(0,0,480,700)  # 屏幕大小常量
    CREAT_EVENT=pygame.USEREVENT  # 定时器常量,这个用于向屏幕定时添加敌机
    BULLET_EVENT = pygame.USEREVENT+1 # 这也是定时器常量,用于定时发射子弹。
    
    
    class PlaneSprites(pygame.sprite.Sprite):
        """创建精灵类"""
        def __init__(self, image, speed=1):
            super().__init__()
            self.image = pygame.image.load(image)
            self.rect = self.image.get_rect()
            self.speed = speed
    
    
    
         #  重写update方法
        def update(self):
            self.rect.y += self.speed
    
    
    """制作背景滚动:方法就是需要俩张一摸一样的图片,一张位置放在覆盖屏幕,另外一张放在屏幕上方,一起向下移动时,
    当第一张刚好移到屏幕最下方,第二张刚好覆盖屏幕,此时将第一张再放到屏幕上方,如此循环,看到的效果就是背景滚动了
    提示:rect设置的矩形对象,xy值默认的是(0,0)
    """
    class BackGround(PlaneSprites):
        def __init__(self,is_flag=False):
            super().__init__('./images/background.png')
            if is_flag:
                self.rect.y =-self.rect.height
    
        def update(self):
            super().update()
            if self.rect.y >= SCREEN.height:  # 判断图片是否滚出屏幕,如果背景图片rect对象的y值大于屏幕的高度
                self.rect.y =-self.rect.height  # 将背景图的y值设置为背景图高度的负值,这张图片就在屏幕上方
    
    # 创建敌机类
    class CreatPlane(PlaneSprites):
        def __init__(self):
            super().__init__('./images/enemy1.png')
            self.speed = random.randint(1,3)  # 利用随机数控制敌机飞行速度
            self.rect.y = -self.rect.height
            self.rect.x = random.randint(0, SCREEN.width-self.rect.width)
    
        def update(self):
            super().update()
            if self.rect.y >= SCREEN.height:
                self.kill()
    
        def __del__(self):
            print('敌机消失.....')
    
    # 创建战机类
    class CreatHero(PlaneSprites):
        def __init__(self):
            super().__init__('./images/me1.png', speed=0)
            self.rect.centerx = SCREEN.centerx
            self.rect.bottom = SCREEN.bottom-120
            self.bullet_gruop = pygame.sprite.Group()
    
        def update(self):
            self.rect.x += self.speed
            if self.rect.x < 0:
                self.rect.x = 0
            elif self.rect.right > SCREEN.right:
                self.rect.right = SCREEN.right
    
        # 发射子弹
        def fire(self):
            for i in (0, 1, 2):
                bullt = CreatBullet()
                bullt.rect.bottom = self.rect.y-i*20
                bullt.rect.centerx = self.rect.centerx
                self.bullet_gruop.add(bullt)
    
    
    # 创建子弹精灵类
    class CreatBullet(PlaneSprites):
        def __init__(self):
            super().__init__('./images/bullet1.png', speed=-2)
    
        def update(self):
            super().update()
            if self.rect.y < SCREEN.y:
                self.kill()
    
        def __del__(self):
            print('子弹消失......')

    2、创建一个plane_main模块,这个是运行的主程序入口:
    import pygame
    from plane_sprites import *
    
    
    class GamePlay(object):
        def __init__(self):
            self.screen = pygame.display.set_mode(SCREEN.size)
            self.clock = pygame.time.Clock()
            self.__creat_sprite()
            pygame.time.set_timer(CREAT_EVENT, 1000)  # 定时器:第一个参数是定时事件发生的,第二是每隔多少毫秒发生一次,这里是每个1秒触发这个定时器
            pygame.time.set_timer(BULLET_EVENT, 500)
    
        def start_game(self):
            while True:
                self.clock.tick(60)
                self.__update()
                pygame.display.update()
                self.__event()
                self.__chenck()
    
        def __chenck(self):
            # 子弹摧毁敌机
            pygame.sprite.groupcollide(self.hero.bullet_gruop,self.enemy_group,True,True)
            # 敌机碰撞战机
            bullet_list = pygame.sprite.spritecollide(self.hero,self.enemy_group, True)
            if len(bullet_list) != 0:
                self.hero.kill()
                GamePlay.game_over()
    
        def __creat_sprite(self):
            # hero1=BackGround('./images/background.png')
            # hero2=BackGround('./images/background.png')
            # hero2.rect.y =-hero2.rect.height
            # 创建背景精灵和精灵组
            bg1 = BackGround()
            bg2 = BackGround(is_flag=True)
            self.bg_group = pygame.sprite.Group(bg1,bg2)
            # 创建敌机精灵组
            self.enemy_group = pygame.sprite.Group()
            # 创建战机精灵和精灵组
            self.hero = CreatHero()
            self.hero_group = pygame.sprite.Group(self.hero)
            self.hero.bullet_gp = pygame.sprite.Group()
    
        #  更新精灵的位置
        def __update(self):
            # 更新背景图片位置
            self.bg_group.update()
            self.bg_group.draw(self.screen)
            # 更新敌机位置
            self.enemy_group.update()
            self.enemy_group.draw(self.screen)
            # 更新战机位置
            self.hero_group.update()
            self.hero_group.draw(self.screen)
            #  更新子弹位置
            self.hero.bullet_gruop.update()
            self.hero.bullet_gruop.draw(self.screen)
    
        # 事件监听
        def __event(self):
            for event in pygame.event.get():
                if event.type == pygame.QUIT:  # 当监听事件为退出事件,则退出游戏
                    print('游戏退出....')
                    pygame.quit()  # 卸载所有模块
                    exit()  # 退出整个系统
                elif event.type == CREAT_EVENT:  # 当监听事件为定时器发生的,则创建一个敌机
                    enemy1 = CreatPlane()
                    self.enemy_group.add(enemy1)
                elif event.type == BULLET_EVENT:
                    self.hero.fire()
            keys_press = pygame.key.get_pressed()
            # 键盘操作战机左右移动
            if keys_press[pygame.K_RIGHT]:  # 按下右键,
                self.hero.speed = 2
            elif keys_press[pygame.K_LEFT]:  # 按下左键
                self.hero.speed = -2
            else:
                self.hero.speed = 0
    
        @staticmethod
        def game_over():
            pygame.quit()
    
    if __name__ == '__main__':
        game = GamePlay()
        game.start_game()
    3、运行效果如下:



  • 相关阅读:
    [C++]2-5 分数化小数
    [C++]2-4 子序列的和
    [C++]2-3 倒三角形
    [C++]2-2 韩信点兵
    [C++]2-1 水仙花数
    [C++]竞赛模板·数据统计与IO(重定向版与非重定向版)
    数学建模·经验小结
    信息检索·论文写作
    PPT制作
    演讲与语言表达
  • 原文地址:https://www.cnblogs.com/lz-tester/p/9314888.html
Copyright © 2011-2022 走看看