美文网首页微信
python实现微信打飞机

python实现微信打飞机

作者: 无心文先森 | 来源:发表于2019-07-10 14:23 被阅读0次

    跟着老杨学python

    微信打飞机这个简单的小游戏曾经风靡全国,霸占朋友圈,既然python如此强大,今天老杨就用python来搞定它。

    快速弄懂一件事物的核心就在乎知道它的本质和规律。我们制作微信打飞机,那我们就先了解一下游戏的原理到底是什么。

    其实,游戏的原理很简单,首先要有一个窗口用来运行你的游戏,然后准备一个素材资源,以微信打飞机为例,就是把背景图,飞机图等图片资源,粘贴到窗口上,你可以把它理解成创建一个毛坯房(这就是你的游戏的窗口),再准备一些墙纸或装饰品,把它们填充到房子里面。既然把物品放到某个地方,我们需要知道物体的位置,而如何确定一个平面的目标,就是坐标了,但编程中和数学不太一样的一点是,我们起点是在左上角的。到这里我们就知道,其实游戏中角色的运动就是图片资源坐标的变化。那运行中会有各种操作,这就是事件,比如我们按下键盘的某个键或按下鼠标,都会捕获到一个事件,根据这些事件,我们执行对应的代码即是执行对应操作,而我们游戏的连贯运行,是动态的,其实就是将不同的页面显示,当刷新的足够快,间隔足够短,就可以达到连贯运行的目的,其实这是不停地将不同的页面显示出来而已(可以参考手翻书的原理)。而代码是从上往下,顺序执行,执行完毕即退出,所以我们的游戏部分代码需要不停的循环进行,只到一个退出事件,退出循环,退出游戏。

    好,懂了原理之后,我们就用代码搞定吧

    这里我们需要先安装一个第三方库,pygame,这个库主要用于2D游戏的开发

    pip install pygame

    先实现第一部分:

    #!/usr/bin/python3
    # @Time      : 2019/7/9 15:22
    # @Author    : 老杨
    # @FileName  : start1.py
    # @Software  : PyCharm
    """
    游戏的原理就是视觉欺骗
    1.首先要有个窗口,显示出界面
    2,然后需要资源(图片)充当背景,角色等,再让他们显示
    
    关于角色会动:
    角色的移动就是图片的移动,移动的本质是什么呢?就是坐标的变化
    
    关于运行游戏:
    那我们怎么运行游戏呢,当我们用手机去触摸,或者说在电脑的键盘上按下某个键盘,其实都是一个事件,我们定义什么事件做什么事情,比方说按下键盘上的左箭头就控制飞机的图片左滑等等
    
    游戏退出和不停地运行:
    代码是执行一遍就完了,那我们的游戏不能一打开就没了把,所以我们需要一个死循环,(不停地去执行代码),然后定义一个事件来退出
    
    关于游戏是连贯的:(手翻书)
    为什么游戏会动呢?原理也很简单,只要动的足够快,中间的间隔短,在我们人眼看来这就是连贯,就是在动的,在我们人眼中,只要间隔低于1/60秒,我们就感觉不出来。所以说只要我们画几幅图,只要他们的出现的间隔足够短,那我们看来这就是连贯的,运动的
    #####在实际开发中,不管图片时什么样子,实际是哪个一定是个矩形。只是部分透明而已。不管在任何操作系统,图片一定是个矩形
    
    总结:
    开发一个游戏,首先得先创建一个窗口,然后准备资源,再填充上。就像房子,首先你得有个毛坯房,然后再刷油漆,或者贴墙纸。
    然后游戏中角色的运动其实就是图片资源坐标的变化,不停的去刷新页面,(把多个不同的图片以很短的间隔出现旧图片覆盖新图片)就是我们看到的角色在运动)
    """
    # 第一步:导入pygame
    # 主要用于2D游戏的开发
    import pygame
    # 初始化pygame
    pygame.init()
    # 创建一个窗口   毛坯房
    #X,Y轴,对应宽和高
    screen = pygame.display.set_mode((450, 600))
    # 设置标题
    pygame.display.set_caption('飞机大战')
    # 准备资源背景图     毛坯房有了,现在就要贴墙纸了,贴墙纸首先要准备好选择好墙纸
    # convert_alpha()的意思:修改图像(Surface 对象)的像素格式,包含 alpha 通道
    # 可以理解为保留了透明的部分,这样图片才可以是不规则的
    background = pygame.image.load('./resources/background.png').convert_alpha()
    #设置游戏是否结束
    gameOver  = True
    # 设置字体 使用自定义字体 传None即使用系统字体,
    # 如果是使用中文的话,使用 Unicode 来表示文字内容,即 u'中文文字'
    # font = pygame.font.Font(None, 32)
    # 使用指定字体
    font = pygame.font.Font("./ziti/miaowu.ttf",32)
    # 分数
    score = 0
    while True:
        # 设定需要显示的背景图  blit填充的意思  第一个参数为要贴的图片,第二个为开始的坐标
        screen.blit(background,(0, 0))
        # 获取事件,比如按键等
        for event in pygame.event.get():
            # 判断是否点击了退出按钮
            if event.type == pygame.QUIT:
                # 退出pygame
                pygame.quit()
                # 退出程序
                exit()
            # 如果游戏结束,且鼠标松开,就重新开始
            if gameOver and event.type == pygame.MOUSEBUTTONUP:
                # 积分重新计算
                score = 0
                # 设置游戏开始
                gameOver = False
        # 如果游戏没有结束
        if not gameOver:
            pass
        else:
            # 准备文字
            # # 参数分别为 显示内容、是否消除锯齿、字体颜色、背景颜色
            # 第二个参数antialias:字体的边缘是否平滑,true表示平滑,false表示带有毛边。
            text = font.render("Socre:%d"%score,True, (0, 0, 0))
            # 填充资源
            screen.blit(text, (150, 300))
            text = font.render("点击鼠标开始游戏",True, (0, 0, 0))
            screen.blit(text, (100, 330))
        #更新(刷新)需要显示的内容
        pygame.display.update()
    

    接下来,我们创建飞机,子弹,和敌机

    #!/usr/bin/python3
    # @Time      : 2019/7/9 15:24
    # @Author    : 老杨
    # @FileName  : start2.py
    # @Software  : PyCharm
    # 第一步:导入pygame
    # 主要用于2D游戏的开发
    import pygame
    import random
    #************** 创建一个飞机类 **************
    class Plane():
        # 因为游戏重新开始,飞机又要回到原点,所以抽离出来
        def restart(self):
            self.x = 200
            self.y = 450
        # 先写初始化方法,创建对象时会自动调用
        def __init__(self):
            # 先自动调用方法,设置飞机的起始坐标
            self.restart()
            # 准备飞机的图片资源
            self.image = pygame.image.load('./resources/hero1.png').convert_alpha()
        # 飞机的移动方法
        def move(self):
            # 我们让飞机随着鼠标的移动而移动
            # 得到鼠标的坐标,返回鼠标的x,y的坐标
            x, y = pygame.mouse.get_pos()
            # 因为粘贴都是左上角开始粘贴的,分别除以2等于水平和垂直居中
            x -= self.image.get_width()/2
            y -= self.image.get_height()/2
            # 重新设置坐标
            self.x = x
            self.y = y
    #************** 创建一个飞机类 **************
    
    ##*******************子弹类***********************##
    class Bullet:
        def __init__(self):
            self.image = pygame.image.load('./resources/bullet.png').convert_alpha()
    
    ##*******************子弹类***********************##
    
    ##*******************敌机类***********************##
    class Enemy():
        # 因为游戏重新开始,飞机又要回到原点,所以抽离出来
        # 因为敌机都是从下面落下来的,却不确定所以利用随机数指定X轴坐标
        def start(self):
            self.x = random.randint(0, 400)
            self.y = 0
    
        def __init__(self):
            self.start()
            self.image = pygame.image.load('./resources/enemy0.png').convert_alpha()
    
    ##*******************敌机类***********************##
    
    
    # 初始化pygame
    pygame.init()
    # 创建一个窗口   毛坯房
    #X,Y轴,对应宽和高
    screen = pygame.display.set_mode((450, 600))
    # 设置标题
    pygame.display.set_caption('飞机大战')
    # 准备资源背景图     毛坯房有了,现在就要贴墙纸了,贴墙纸首先要准备好选择好墙纸
    # convert_alpha()的意思:修改图像(Surface 对象)的像素格式,包含 alpha 通道
    # 可以理解为保留了透明的部分,这样图片才可以是不规则的
    background = pygame.image.load('./resources/background.png').convert_alpha()
    #设置游戏是否结束
    gameOver  = True
    # 设置字体 使用自定义字体 传None即使用系统字体,
    # 如果是使用中文的话,使用 Unicode 来表示文字内容,即 u'中文文字'
    # font = pygame.font.Font(None, 32)
    # 使用指定字体
    font = pygame.font.Font("./ziti/miaowu.ttf",32)
    # 分数
    score = 0
    
    # 第二部分*********
    # 创建飞机类
    plane = Plane()
    
    # 创建子弹类
    bullet = Bullet()
    
    # 创建多架敌机类
    # enemy = Enemy()
    enemys = []
    for i in range(5):
        enemys.append(Enemy())
    
    while True:
        # 设定需要显示的背景图  blit填充的意思  第一个参数为要贴的图片,第二个为开始的坐标
        screen.blit(background,(0, 0))
        # 获取事件,比如按键等
        for event in pygame.event.get():
            # 判断是否点击了退出按钮
            if event.type == pygame.QUIT:
                # 退出pygame
                pygame.quit()
                # 退出程序
                exit()
            # 如果游戏结束,且鼠标松开,就重新开始
            if gameOver and event.type == pygame.MOUSEBUTTONUP:
                # 积分重新计算
                score = 0
                # 设置游戏开始
                gameOver = False
        # 如果游戏没有结束
        if not gameOver:
            # # 让飞机移动
            plane.move()
            # 将飞机的图片填充 ,参数为飞机的图片资源,粘贴的坐标
            screen.blit(plane.image, (plane.x, plane.y))
    
            # 子弹肯定是出现飞机的前面的,那子弹的粘贴坐标就以飞机的坐标为基础来表达
            x = plane.x + plane.image.get_width()/2-bullet.image.get_width()/2
            y = plane.y - 100
            # 准备子弹的图片
            screen.blit(bullet.image, (x, y))
    
            # 多架敌机都需要在不同的地点显示
            for enemy in enemys:
                screen.blit(enemy.image, (enemy.x, enemy.y))
    
        else:
            # 准备文字
            # # 参数分别为 显示内容、是否消除锯齿、字体颜色、背景颜色
            # 第二个参数antialias:字体的边缘是否平滑,true表示平滑,false表示带有毛边。
            text = font.render("Socre:%d"%score,True, (0, 0, 0))
            # 填充资源
            screen.blit(text, (150, 300))
            text = font.render("点击鼠标开始游戏",True, (0, 0, 0))
            screen.blit(text, (100, 330))
        #更新(刷新)需要显示的内容
        pygame.display.update()
    

    最后,完成让子弹移动和击中敌机的功能,大功告成

    #!/usr/bin/python3
    # @Time      : 2019/7/9 15:52
    # @Author    : 老杨
    # @FileName  : start3.py
    # @Software  : PyCharm
    # 第一步:导入pygame
    # 主要用于2D游戏的开发
    import pygame
    import random
    import time
    #************** 创建一个飞机类 **************
    class Plane():
        # 因为游戏重新开始,飞机又要回到原点,所以抽离出来
        def restart(self):
            self.x = 200
            self.y = 450
        # 先写初始化方法,创建对象时会自动调用
        def __init__(self):
            # 先自动调用方法,设置飞机的起始坐标
            self.restart()
            # 准备飞机的图片资源
            self.image = pygame.image.load('./resources/hero1.png').convert_alpha()
        # 飞机的移动方法
        def move(self):
            # 我们让飞机随着鼠标的移动而移动
            # 得到鼠标的坐标,返回鼠标的x,y的坐标
            x, y = pygame.mouse.get_pos()
            # 因为粘贴都是左上角开始粘贴的,分别除以2等于水平和垂直居中
            x -= self.image.get_width()/2
            y -= self.image.get_height()/2
            # 重新设置坐标
            self.x = x
            self.y = y
        # 炸毁了
        def ruin(self):
            self.ruin_image = pygame.image.load('./resources/hero_blowup_n1.png').convert_alpha()
            screen.blit(self.ruin_image, (self.x, self.y))
            pygame.display.update()
    #************** 创建一个飞机类 **************
    ##*******************子弹类***********************##
    class Bullet:
        def __init__(self):
            self.image = pygame.image.load('./resources/bullet.png').convert_alpha()
    ##*******************子弹类***********************##
    
    ##*******************敌机类***********************##
    class Enemy():
        # 因为游戏重新开始,飞机又要回到原点,所以抽离出来
        # 因为敌机都是从下面落下来的,却不确定所以利用随机数指定X轴坐标
        def start(self):
            self.x = random.randint(0, 400)
            self.y = 0
    
        def __init__(self):
            self.start()
            self.image = pygame.image.load('./resources/enemy0.png').convert_alpha()
        # 让敌机运动,运动的本质就是坐标发生变化,在极短的时间内刷新,达到动态的效果
        # 让敌机每次运动一点,Y轴的坐标加0.1等于就是像下移动一点
        def move(self):
            # 判断如果小于高度就继续向下,如果大于高度,则回归起点
            if self.y < 600:
                self.y += 0.1
            if self.y > 600:
                self.start()
        # # 炸毁了
        # def ruin(self):
        #     self.ruin_image = pygame.image.load('./resources/enemy0_down2.png').convert_alpha()
        #     screen.blit(self.ruin_image, (self.x, self.y))
        #     pygame.display.update()
    
    ##*******************敌机类***********************##
    
    ##*******************碰撞***********************##
    def Crash(plane,enemy):
        # 表示撞上了
        if (plane.x+plane.image.get_width()>enemy.x) and (plane.x<enemy.x+enemy.image.get_width()) and (plane.y+plane.image.get_height()>enemy.y) and (plane.y<enemy.y+enemy.image.get_height()) :
            return True
        else:
            return False
    ##*******************碰撞***********************##
    ##*******************子弹射中敌机***********************##
    def Shoot(x,y,enemy):
        if (enemy.x<x<enemy.x+enemy.image.get_width()) and (enemy.y<y<enemy.y+enemy.image.get_height()):
            # bullet.active = False
            enemy.start()
            return True
        else:
            return False
    ##*******************子弹射中敌机***********************##
    # 初始化pygame
    pygame.init()
    # 创建一个窗口   毛坯房
    #X,Y轴,对应宽和高
    screen = pygame.display.set_mode((450, 600))
    # 设置标题
    pygame.display.set_caption('飞机大战')
    # 准备资源背景图     毛坯房有了,现在就要贴墙纸了,贴墙纸首先要准备好选择好墙纸
    # convert_alpha()的意思:修改图像(Surface 对象)的像素格式,包含 alpha 通道
    # 可以理解为保留了透明的部分,这样图片才可以是不规则的
    background = pygame.image.load('./resources/background.png').convert_alpha()
    #设置游戏是否结束
    gameOver  = True
    # 设置字体 使用自定义字体 传None即使用系统字体,
    # 如果是使用中文的话,使用 Unicode 来表示文字内容,即 u'中文文字'
    # font = pygame.font.Font(None, 32)
    # 使用指定字体
    font = pygame.font.Font("./ziti/miaowu.ttf",32)
    # 分数
    score = 0
    
    # 第二部分*********
    # 创建飞机类
    plane = Plane()
    
    # 创建子弹类
    bullet = Bullet()
    
    # 创建多架敌机类
    # enemy = Enemy()
    enemys = []
    for i in range(5):
        enemys.append(Enemy())
    
    # 事先定义一个值
    a = 1
    while True:
        # 设定需要显示的背景图  blit填充的意思  第一个参数为要贴的图片,第二个为开始的坐标
        screen.blit(background,(0, 0))
        # 获取事件,比如按键等
        for event in pygame.event.get():
            # 判断是否点击了退出按钮
            if event.type == pygame.QUIT:
                # 退出pygame
                pygame.quit()
                # 退出程序
                exit()
            # 如果游戏结束,且鼠标松开,就重新开始
            if gameOver and event.type == pygame.MOUSEBUTTONUP:
                # 积分重新计算
                score = 0
                # 设置游戏开始
                gameOver = False
        # 如果游戏没有结束
        if not gameOver:
            # # 让飞机移动
            plane.move()
            # 将飞机的图片填充 ,参数为飞机的图片资源,粘贴的坐标
            screen.blit(plane.image, (plane.x, plane.y))
            # 子弹肯定是出现飞机的前面的,那子弹的粘贴坐标就以飞机的坐标为基础来表达
            x = plane.x + plane.image.get_width()/2-bullet.image.get_width()/2
            y = plane.y-a*50
            # 准备子弹的图片
            screen.blit(bullet.image, (x, y))
            a += 1
            if a>=12:
                a = 1
            # 多架敌机都需要在不同的地点显示
            for enemy in enemys:
                # 让每一个敌机都运动
                enemy.move()
                screen.blit(enemy.image, (enemy.x, enemy.y))
                # 当任意一个敌机撞上飞机,就游戏结束
                if Crash(plane,enemy):
                    gameOver = True
                    plane.ruin()
                    time.sleep(1)
                if Shoot(x,y,enemy):
                    score += 100
                    # enemy.ruin()
                    # time.sleep(0.1)
            # 准备文字
            text = font.render("Socre: %d" % score, 1, (0, 0, 0))
            # 填充资源
            screen.blit(text, (0, 0))
        else:
            # 准备文字
            # # 参数分别为 显示内容、是否消除锯齿、字体颜色、背景颜色
            # 第二个参数antialias:字体的边缘是否平滑,true表示平滑,false表示带有毛边。
            text = font.render("Socre:%d"%score,True, (0, 0, 0))
            # 填充资源
            screen.blit(text, (150, 300))
            text = font.render("点击鼠标开始游戏",True, (0, 0, 0))
            screen.blit(text, (100, 330))
        #更新(刷新)需要显示的内容
        pygame.display.update()
    

    相关文章

      网友评论

        本文标题:python实现微信打飞机

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