python实现微信打飞机

跟着老杨学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()
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值