• 3
  • 0
分享
  • 80+行代码实现简单的飞行的小鸟游戏
  • 不知所云 2018-04-28 11:59:33 字数 7730 阅读 2472 收藏 0

想做一个小游戏玩玩,飞行的小鸟,简单好玩,尝试看看。用python做游戏的话,就得要用到pygame这个模块了。先简单介绍一下pygame吧。


pygame是一个利用SDL库(全名Simple DirectMedia Layer)写就的游戏库。安装好python3环境以后,可以用pip3 install pygame命令来安装pygame。pygame有很多的模块,我们这个游戏会用到以下模块:
  • pygame:主模块,一些通用的控制
  • pygame.display:用来访问显示设备
  • pygame.draw:绘制形状,线和点
  • pygame.rect:管理矩形区域
  • pygame.init:初始化的一些定义
  • pygame.font:使用字体
  • pygame.time:管理时间和帧信息
另外因为游戏需要用到很多随机数,所以还需要random模块,也可以通过pip3命令安装。
既然是实现"飞行的小鸟"游戏,首先要有鸟和管子,这里我想通过类来分别定义小鸟和管子。小鸟和管子还要在屏幕上显示,所以这个屏幕的显示也是要定义的。首先看看这个屏幕的定义吧,下面是屏幕定义的代码和一些注释
pygame.init()
# 定义颜色
PIPE = (0,0,255)
SKY = (135,206,250)
BIRD = (220,20,60)
GROUND = (245,245,220)
# 设置游戏幕布大小
size = (800, 650)
screen = pygame.display.set_mode(size)
# 标题设置
pygame.display.set_caption("Flappy Block")
#字体设置
arial18 = pygame.font.SysFont('arial',18, False, False)
# 游戏未结束
done = False
# 时钟
clock = pygame.time.Clock()
# 游戏初始状态
gameState = 1 #未开始
pipes = []#定义管子的list
pygame.init函数,初始化pygame模块,好让我们可以利用pygame的那些模块。比如pygame.font,pygame.draw等(上面列举到的模块)。
然后程序里定义各个对象的颜色,包括小鸟、管子、天空、背景,完了再设置游戏的屏幕大小。幕布左上角坐标是(0,0)设置了游戏的显示标题,还有字体。默认游戏是未开始的状态。gameState=1,代表游戏初始未开始。pipes=[],管子是有序的,所以用list定义。
现在来用类定义小鸟。python是强制缩进的,所以可以很清楚的看到代码块,一个代码块实现一定的逻辑。
# 定义小鸟
class Bird():
    def __init__(self):
        self.x = 250  # 小鸟x坐标
        self.y = 250  # 小鸟y坐标
        self.yV = 0   # 小鸟的位置初始化
    # 定义小鸟的下降振幅
    def flap(self):
        self.yV = -5  # 每次下降的位移
    # 定义小鸟的上升振幅和y周的上下边界
    def update(self):
        self.yV += 0.3  # 小鸟上升速度
        self.y += self.yV  # y轴位置等于原位置加yV振幅
    # 定义小鸟的飞行
    def draw(self):
        pygame.draw.rect(screen, BIRD, (self.x, self.y, 40, 40))#参数为(幕布,颜色,坐标,大小)
    # 重置小鸟
    def reset(self):
        self.x = 250
        self.y = 250
        self.yV = 0
bird = Bird()# 实例一个小鸟
类class Bird():定义了小鸟。__init(self)__方法初始化了小鸟的位置等信息。注意这个self,在python语言里,类的方法,会有一个默认的参数,一般通用的都是用self表示,这个self是代表类的自身。flap方法定义了小鸟每次下降的位移。update方法定义了小鸟的上升。draw方法通过调用pygame.draw.rect实现了小鸟的飞行。reset方法重置小鸟的位置。bird=Bird()是小鸟类的实例化。
下面来定义管子
# 定义管子
class Pipe():
    def __init__(self):
        self.centerY = random.randrange(180, 520)  # 管子的y轴中间值范围
(大数上面管子长,小数下面管子长)
        self.x = 800  # 管子的初始x轴位置
        self.size = 150  # 上下两个管子之间的空间宽度的一半
    # 更新管子
    def update(self):
        # 几个全局变量
        global pipes
        global bird
        global gameState
        self.x -= 4  # 管子的移动速度,因为小鸟其实没有动x轴的位移,小鸟其实是不前进的,只是上下跳动
        # 管子的初始位置
        if self.x == 300:
            pipes.append(Pipe())  # 显示一个新管子
        if self.x <= -100: del pipes[0] # 删除一个不再显示的管子 # 小鸟撞到管子,游戏结束,第一个条件是撞到下面的管子,第二个条件是撞到上面的管子(小鸟位置固定,管子在x轴运动) #小鸟的y轴位移小于管子的y轴范围减去中间空的部分 #或者小鸟的y轴位移+40大于管子的y轴范围加上中间空的部分,40是小鸟的长度 #则小鸟撞到管子,游戏结束 if self.x >= 170 and self.x <= 290 and bird.y <= (self.centerY - self.size) \ or self.x >= 170 and self.x <= 290 and (bird.y + 40) >= (self.centerY + self.size):
            gameState = 3  # 结束
            # 小鸟飞过管子,游戏继续,两个75等于size的150
        if self.x == 168 and bird.y > (self.centerY - 75) and bird.y < (self.centerY + 75): gameState = 2 # 小鸟撞到地面,游戏结束 if bird.y >= 610:
            gameState = 3
    # 定义管子的显示

    def draw(self):
        # 定义上面管子的显示(幕布,颜色,坐标,宽=80,长)
        pygame.draw.rect(screen, PIPE, (self.x, 0, 80, (self.centerY - self.size)))
        # 定义下面管子的显示
        pygame.draw.rect(screen, PIPE, (self.x, (self.centerY + self.size), 80, (548 - self.centerY)))
# 实例化管子,显示新管子
pipes.append(Pipe())
管子的这个类,我们说说和小鸟不一样的地方。update方法实现了管子的更新显示。注意global,global使参数全局化。管子的移动是self.x=4,说明管子是从右向左运动,速率是4。(所以这个游戏里,其实是管子在左右动,而小鸟其实只是上下动,没有进行x轴的运动)。
pipes.append(Pipe())是列表调用类,列表的append方法,是给列表里插入一个新的元素。这里代表显示(插入)一个新管子。del pipes[0],列表中0代表第一个元素的位置,也就是删掉第一个管子(管子不再显示)。
小鸟碰到管子
if self.x >= 170 and self.x <= 290 \ #管子的位置在120-290之间 and bird.y <= (self.centerY - self.size) \#并且小鸟的身体碰到了上面的管子 or self.x >= 170 and self.x <= 290 and (bird.y + 40) >= (self.centerY + self.size):#小鸟的身体碰到了下面的管子
    gameState = 3  # 结束
小鸟飞过管子
# 小鸟飞过管子,游戏继续,两个75等于self.size的150
if self.x == 168 and bird.y > (self.centerY - 75) and bird.y < (self.centerY + 75): gameState = 2

管子的x轴位置168,表示穿过了。而且小鸟刚好在两个管子的空间self.size里。
实现管子的显示
# 定义管子的显示
    def draw(self):
        # 定义上面管子的显示(幕布,颜色,坐标,宽=80,长)
        pygame.draw.rect(screen, PIPE, (self.x, 0, 80, (self.centerY - self.size)))
        # 定义下面管子的显示
        pygame.draw.rect(screen, PIPE, (self.x, (self.centerY + self.size), 80, (548 - self.centerY)))
# 实例化管子,显示新管子
pipes.append(Pipe())
现在看一下游戏的具体实现。
游戏要有控制键,设置为空格键控制。游戏结束要退出,用QUIT方法。游戏有三个状态:
1:未开始;2:进行中;3:结束
首先游戏未开始时,点击空格键可以开始游戏,游戏结束以后,可以重新开始游戏,这需要重置小鸟和管子。游戏运行中的小鸟和管子,就是刷新显示小鸟和管子。
还需要定义一下游戏开始的按钮显示
#定义游戏开始键
#参数为显示的地方,颜色,面板的位置和大小 
    pygame.draw.rect(screen,GROUND,(300,300,200,100))#开始键的面板,
    #参数为显示的文字,是否显示,颜色
    text = arial18.render("Press space to play",True,SKY)#文字
    #文字的位置设置
    textX = text.get_rect().width
    textY = text.get_rect().height
    screen.blit(text,((400 - (textX / 2)),(350 - (textY / 2))))#字的填充位置
同样还要设置游戏结束的按钮,只是文案稍微加上gameover。
然后要考虑到整个页面的刷新,用pygame.display.flip方法。画面刷新时间控制由pygame.timeClock.tick控制。
以下是游戏运行的主要函数:
# -------- Main Program Loop -----------
#当游戏没结束
while not done:
    # --- Main event loop
    # pygame的event方法
    for event in pygame.event.get():
        if event.type == pygame.QUIT:  # 退出游戏
            done = True
        # 游戏键位设置
        if event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:  # 设置为空格键
                if gameState == 1:  # 游戏未开始状态为1
                    gameState = 2  # 游戏中状态为2
                elif gameState == 3:  # 游戏结束状态为3
                    bird.reset()  # 小鸟重置
                    # 管子list重置
                    pipes = []
                    pipes.append(Pipe())
                    # 游戏中
                    gameState = 2
                else:  # 没有管子的时候,小鸟飞行
                    bird.flap()
    screen.fill(SKY)  # 屏幕填色
    if gameState == 1: #游戏未开始时
        #定义游戏开始键
        pygame.draw.rect(screen,GROUND,(300,300,200,100))#开始键的面板,参数为xy轴位置,xy方向的大小
        text = arial18.render("Press space to play",True,SKY)#文字
        #文字的位置设置
        textX = text.get_rect().width
        textY = text.get_rect().height
        screen.blit(text,((400 - (textX / 2)),(350 - (textY / 2))))#字的填充位置
    # 当游戏运行中
    if gameState == 2:
        # 小鸟的飞行更新
        bird.update()
        bird.draw()
        # 管子的更新显示
        for pipe in pipes:
            pipe.update()
            pipe.draw()
    # 当游戏结束
    if gameState == 3:
        for pipe in pipes:
            pipe.draw()
        bird.draw()
        pygame.draw.rect(screen,GROUND,(300,300,250,100))#开始键的面板
        text = arial18.render("Game Over,Press space to play",True,SKY)#文字
        #文字的位置设置
        textX = text.get_rect().width
        textY = text.get_rect().height
        screen.blit(text,((420 - (textX / 2)),(350 - (textY / 2))))#字的填充位置
# 刷新页面
    pygame.display.flip()
# 画面更新时间,单位:秒
    clock.tick(50)
pygame.quit()

游戏的实现效果是这样的:用方块来代替小鸟。


以上就是这个小游戏的实现过程了,大家可以自己研究加上小鸟穿过管子后的计分功能,也可以把小鸟美化一下,或者给游戏设置由易到难的玩法,可以各种尝试。大家一起试试吧!
  • 【留下美好印记】
    赞赏支持
登录 后发表评论
+ 关注

热门文章

    最新讲堂

      • 推荐阅读
      • 换一换
          •   看看我写的软件测试面试时候的这些坑,你一定不能踩!!!  第一个坑--测试用例编写没有思路,想起一条写一条。  分析:  该题目一般检查候选人编写测试用例的思路、覆盖度、深度。如果想起一条写一条,可能说明用例编写经验不足。  避免雷区:  一般有经验的候选人,都会按照自己常用的结构来划分功能点、影响因素。  1. 按照常用结构划分:  比如:分别从功能性、界面ui、易用性、安全性、兼容性等方面来考虑测试用例。  2. 字迹清晰,条理分明。  第二个坑--自顾自答(回答跑题了)  面试官:“同学,请讲一下你在近期项目中做的事情吧?”  候选人:“我最近做的项目是xxx,是一款在线购物平台,主...
            0 0 991
            分享
          •   让 ChatGPT 如虎添翼!  ChatGPT 很好用,其核心是prompt的运用,其回答质量很大程度取决于你的提问质量。  我算是 ChatGPT 的高频用户了,几乎日活。半个月前我在星球写道:  冲了Plus之后,使用更加频繁,说几点ChatGPT近期感受:   1、它发挥多大效能取决于你的知识储备,它只能锦上添花,无法雪中送炭;  2、提问是门技术,无论是向他人求助,还是之前用搜索引擎,大部分人连提问都搞不定;  3、未来ChatGPT必然更加强大,会更好用,但依然无法解决上面俩个问题;  4、未来N年他会持续进化,国内做模型大概率邯郸学步;  5、真...
            0 0 112
            分享
          • 在互联网行业中,永无止境的讨论主题之一是:敏捷与DevOps。对于这两个概念来说,过程彼此不同;但是它们仍然有一些相似之处。敏捷敏捷方法论是一种实践,它促进整个项目的 SDLC(软件开发生命周期)的开发和测试的持续迭代。在敏捷方法中,开发和测试活动是同时进行的,这涉及到 SDLC 过程中开发和测试的持续迭代。敏捷宣言强调的敏捷软件开发的四个核心价值是:个体和互动高于流程和工具工作的软件高于详尽的文档客户合作高于合同谈判响应变化高于遵循计划敏捷是一个软件开发过程,它符合敏捷宣言的品质和标准。它建立在迭代开发的基础上,以跨职能团队的合作为中心,以获得所需的解决方案。敏捷开发过程将产品分解成小块并将...
            0 0 784
            分享
          •   OpenAI 表示,它希望采纳公众关于如何确保其未来人工智能模型"符合人类价值观"的意见。为此,这家人工智能初创公司今天宣布,正在组建一个由研究人员和工程师组成的新的"集体对齐"(Collective Alignment)团队,以创建一个系统,收集公众对其模型行为的意见,并将其"编码"到 OpenAI 的产品和服务中。  "我们将继续与外部顾问和资助团队合作,包括开展试点,将......原型纳入我们的模型指导中,"OpenAI 在一篇博文中写道。"我们正在招募......来自不同技术背景的研究工程师,...
            0 0 1000
            分享
          • 都说“工欲善其事,必先利其器”。做软件测试行业,怎么能缺少好用的软件测试工具呢?对于很多小伙伴,尤其是新手来说,刚入行时,由于接触的工具比较少,会的工具可能也就那么几个,如果工作中再涉及不到使用新工具,那么后期想要能力上、职位上有所提升,肯定会是一件非常难的事情。为了避免这种情况的发生,最好的办法就是提前了解其他工具,利用业余时间开始学习接触新工具,才能有自己的发展之地。那么,时下IT行业里,主流的软件测试工具有哪些呢?笔者以为,主要有以下10类。具体大类如下:白盒测试工具、web测试工具、持续集成工具、C/S自动化工具、app自动化工具、代码扫描工具、测试管理工具、接口测试工具、性能测试工具...
            0 0 1636
            分享
      • 51testing软件测试圈微信