美文网首页
用python做一个小游戏——飞机大战

用python做一个小游戏——飞机大战

作者: 随风摇摆的樱桃 | 来源:发表于2018-03-18 20:45 被阅读0次

    通过做这个小游戏有两个目的:

    1.强化面向对象程序设计

    2.体验使用pygame模块进行游戏开发

    一.确认模块

    pygame就是一个python模块,专为电子游戏设计

    官方网站:https://www.pygame.org/

    [要学习第三方模块,通常最好的参考资料就在官方网站]

    二.安装pygame

    $ sudo pip3 install pygame

    三.验证安装

    $ python3 -m pygame.examples.aliens

    代码块

    • 精灵类---plane_sprites
    #这个模块放一些常用的工具和基础类和精灵类
    #在其他模块调用
    import pygame
    import random
    #设置游戏屏幕大小 这是一个常量
    SCREEN_RECT = pygame.Rect(0,0,580,700)
    #敌机的定时器事件常量
    CREATE_ENEMY_EVENT = pygame.USEREVENT
    
    #定制一个精灵类,需要继承pygame提供的精灵类
    #需要定义的属性有:
    #image图片 
    #rect坐标
    #speed速度
    
    #接下来开始写敌机方面的内容 产生敌机
    #先定义一个事件常量
    CREATE_ENEMY_EVENT = pygame.USEREVENT
    #我们还可以定义一个事件常量(发射子弹)
    HERO_FIRE_EVENT = pygame.USEREVENT + 1
    
    class GameSprite(pygame.sprite.Sprite):
        def __init__(self,new_image,new_speed=1):
            super().__init__()
            #图片
            self.image = pygame.image.load(new_image)
            #速度
            self.speed = new_speed
            #位置 获取图片的宽和高 get_rect()(0,0,宽,高)
            self.rect = self.image.get_rect()
            #精灵移动的速度 包括英雄精灵 背景精灵 敌机精灵 子弹精灵
            self.speed = new_speed
    
        def update(self):
            #默认垂直方向移动 y轴控制垂直方向
            self.rect.y += self.speed
            #self.rect.x += 1
    #以上是游戏的基础类,接下来设置背景类
    #明确背景类继承自游戏的精灵类
    class Background(GameSprite):
        def __init__(self,is_alt = False):
            #is_alt判断是否为另一张图像
            #False表示第一张图像
            #Ture表示另外一张图像
            #两张图像交替循环
            #传图片
            super().__init__("/home/liutingting/下载/beijing.png")
            if is_alt:
                #如果是第二张图片 初始位置为-self.rect.height
                self.rect.y = -self.rect.height
        #def __init__(self,new_image):
        #   super().init__(new_image)
        def update(self):
            #调用父类方法
            super().update()
            if self.rect.y >= SCREEN_RECT.height:
                self.rect.y = -self.rect.height
    #敌机出场
    class Enemy(GameSprite):
        #敌机精灵
        def __init__(self):
            #1 调用父类方法 创建敌机精灵 并且指定敌机图像
            super().__init__("/home/liutingting/桌面/images/enemy1.png")
    
            #2 设置敌机的随机初始速度1~3
            self.speed = random.randint(2,6)
            #3 设置敌机的随机初始位置
            self.rect.bottom = 0
            max_x =SCREEN_RECT.width -self.rect.width
            self.rect.x = random.randint(0,max_x)
    
        def update(self):
            #1 调用父类方法 让敌机在垂直方向运动
            super().update()
    
            #2 判断是否飞出屏幕 如果是 需要将敌机从精灵组删除
            if self.rect.y >= SCREEN_RECT.height:
                #print("敌机飞出屏幕")
                #将精灵从精灵组中删除
                self.kill()
    
    #英雄出场
    class Hero(GameSprite):
        def __init__(self):
            super().__init__("/home/liutingting/桌面/images/life.png",0)
            self.bullet = pygame.sprite.Group()
            #设置初始位置
            self.rect.center =SCREEN_RECT.center
            self.rect.bottom =SCREEN_RECT.bottom-120
            self.move = False
        def update(self):
            #super().update()
            if not self.move:
                self.rect.x += self.speed
            else:
                self.rect.y += self.speed
    
            #self.rect.y += self.speed
            #飞机飞出屏幕
            if self.rect.bottom <= 0:
                self.rect.y = self.rect.bottom+SCREEN_RECT.height
            elif self.rect.y >= SCREEN_RECT.height:
                self.rect.y = -self.rect.height
    
            if self.rect.right <= 0:
                self.rect.x = self.rect.right+SCREEN_RECT.width
            elif self.rect.x >= SCREEN_RECT.width:
                self.rect.x = -self.rect.width
        def fire(self):
            #print("发射子弹")
    
            for i in (1,2,3):
                bullet = Bullet()
                bullet.rect.bottom = self.rect.y-i*20
                bullet.rect.center = self.rect.center
                self.bullet.add(bullet)
    
    
    #子弹精灵
    class Bullet(GameSprite):
    
        def __init__(self):
            super().__init__("/home/liutingting/桌面/images/bullet1.png",-5)
        def update(self):
            super().update()
    
            #判断是否超出屏幕 如果是 从精灵组删除
            if self.rect.bottom < 0:
                self.kill()
    
    
    • 游戏主类---plane_main
    import pygame
    from plan_sprites import *
    
    #初始化
    
    pygame.mixer.init()
    
    pygame.mixer.music.load("/home/liutingting/下载/Mark Petrie - Kara Kul.mp3")
    #播放
    pygame.mixer.music.play(loops =-1)
    
    
    HERO_FIRE_EVENT = pygame.USEREVENT +1
    class PlaneGame(object):
        def __init__(self):
            #print("游戏初始化")
    
            #1.创建游戏窗口pygame.display.set_mode
            self.screen = pygame.display.set_mode(SCREEN_RECT.size)
            #2.创建游戏时钟pygame.time.Clock()
            self.clock = pygame.time.Clock()
            #3.创建精灵和精灵组内容较多 故封装成一个方法
            #调用创建精灵的方法
            self.__creat_sprites()
            #以上属于游戏初始化时候的设置
            #4.设置定时器 每隔多少秒创建一个敌机
            #pygame.time.set_timer相当于写了一个定时器 每隔一秒调用一次
            pygame.time.set_timer(CREATE_ENEMY_EVENT,500)
            #再写一个定时器 发射子弹
            pygame.time.set_timer(HERO_FIRE_EVENT,500)
            #上面这一步定义了系统每隔0.5秒 调用一次pygame事件
            #下面去事件监听方法里监听事件
    
    
        def star_game(self):
            while True:
                # 1 设置帧率
                self.clock.tick(200)
                # 2 事件监听 主要监听我们鼠标键盘的一些事件
                self.__event_handler()
    
                # 3 碰撞检测 
                self.__check_collide()
                # 4 更新精灵和精灵组
                self.__update_sprites()
                # 5 更新显示
                pygame.display.update()
                #以上都是要实时监测的,so写在循环里
                #每1\60秒就会调用一次
        #创建精灵和精灵组
        def __creat_sprites(self):
            bg1 = Background()
            #Ture 就表示是第二张图片
            bg2 = Background(True)
        
    
            #英雄
            self.hero = Hero()
            self.hero_group = pygame.sprite.Group(self.hero)
    
            self.back_group = pygame.sprite.Group(bg1,bg2)
            #敌机组
            self.enemy_group = pygame.sprite.Group()
            
            
    
    
        #事件监听
        def __event_handler(self):
    
            for event in pygame.event.get():
                #如果某个按键按下 对应的值应该会是
                keys_pressed = pygame.key.get_pressed()
                #控制飞机移动
                if keys_pressed[276]:
                    self.hero.move = False
                    self.hero.speed = -9
                elif keys_pressed[275]:
                    self.hero.move = False
                    self.hero.speed = 9
                elif keys_pressed[273]:
                    self.hero.move = True
                    self.hero.speed = -9
                elif keys_pressed[274]:
                    self.hero.move = True
                    self.hero.speed = 9
                else:
                    self.hero.speed = 0
    
    
                if event.type == pygame.QUIT:
                    self.__game_over()
    
                elif event.type == CREATE_ENEMY_EVENT:
                    #print("新的敌机产生")
    
                    self.enemy_group.add(Enemy())
    
                 #发射子弹
                elif event.type == HERO_FIRE_EVENT:
                        self.hero.fire()
    
        #更新精灵和精灵组
        def __update_sprites(self):
    
            for x in[self.back_group,self.enemy_group,self.hero_group,self.hero.bullet]:
                x.update()
                x.draw(self.screen)
    
        def __check_collide(self):
            #碰撞检测
            #1.子弹摧毁飞机 
            #第一个参数和第二个参数是要参与碰撞检测的精灵
            #第三个参数为Ture的时候 就是当碰撞的时候被碰撞的精灵从精灵组移除
            pygame.sprite.groupcollide( self.enemy_group,self.hero.bullet, True, True)#子弹
            #2.敌机撞毁飞机
            enemies = pygame.sprite.spritecollide(self.hero,self.enemy_group,True)
    
            #判断列表时候有内容
            if len(enemies)>0:
                #让英雄牺牲
                self.hero.kill()
    
                #结束游戏
                PlaneGame.__game_over()
        @staticmethod
        def __game_over():
            print("游戏结束")
            #这是pygame提供的卸载模块功能
            pygame.quit()
            #这是pygame本身提供的退出脚本的功能
            exit()
            #需要先卸载pygame模块 然后退出脚本
            
    if __name__ == "__main__":
        game = PlaneGame()
        game.star_game()
    
    image.png

    相关文章

      网友评论

          本文标题:用python做一个小游戏——飞机大战

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