Python 用Pygame写一个Flappy Bird经典小游戏

Pygame是Python用于开发游戏的外置库,可通过pip install pygame安装~

这篇文章,我们将用Pygame编写一个Flappy Bird小游戏,游戏效果如下:

Python 用Pygame写一个Flappy Bird经典小游戏

设计该游戏需要的照片如下,大家可以下载使用:

0.png

1.png

2.png

bg_day.png

现在开始写代码吧!

先导入模块,导入pygame,pygame的常量,random随机库,sys用于退出程序,copy用于深度克隆,避免不必要的错误

import pygame
from pygame.locals import *
import random as rd
import sys
import copy

定义常量,path是图片储存目录,后面两个分别是pygame事件中给用户用的接口,一个用于进入游戏时的倒计时事件,另一个则是创建新的管道的事件,后面我们会用到

path="resources/"
COUNTDOWN=USEREVENT+1
NEWTUBE=USEREVENT+2

我们使用类和对象的方法,定义game类,初始化函数中,先初始化pygame,定义self.W和self.H,表示窗口长宽,创建窗口self.screen,然后设置标题和图标,接下来导入背景图片,并用smoothscale功能缩放到窗口大小

接下来定义玩家self.player,Player()类在后面的代码中会讲到

self.tubes列表用于储存管道所在的坐标

定义管道的宽度

self.counter 搭配self.toUpdate使用

self.toUpdate 刷新管道位置的速率

self.tubeSpeed 管道移动的速度

self.countdown 倒计时

self.state 游戏的状态,初始是倒计时

self.score 分数,这个就不用说了吧。。

最后设置每1000毫秒(1秒)切换数字,也就是从3数到1就开始游戏,这里需要用set_timer方法

class Game:
    def __init__(self):
        pygame.init()
        self.W,self.H=800,800
        self.screen=pygame.display.set_mode((self.W,self.H))
        pygame.display.set_caption("FlappyBird Classic")
        pygame.display.set_icon(pygame.image.load(path+"0.png"))

        self.bg=pygame.transform.smoothscale(pygame.image.load(path+"bg_day.png"),(self.W,self.H))
        self.player=Player()
        self.tubes=[]
        self.tubeWidth=45
        self.counter=0
        self.toUpdate=2
        self.tubeSpeed=2
        self.state="countdown"
        self.countdown=3
        self.score=0
        pygame.time.set_timer(COUNTDOWN,1000)

接下来是listen函数(Game类方法),用于监听事件

先遍历pygame的事件,如果是关闭窗口操作(QUIT),则退出窗口

注意!这里退出窗口可以直接写exit(),就不用导入sys库了,但是如果要将python文件打包成exe的话,就必须使用sys库,否则程序找不到exit函数,就要使用sys里的exit进行退出操作!

接下来,如果是键盘事件(KEYDOWN),就再判断,是否按下空格,是的话就跳跃,jump类方法待会会讲

如果是COUNTDOWN事件,就进行倒计时操作

如果是NEWTUBE则创建管道,newTube函数待会会讲

    def listen(self):
        for event in pygame.event.get():
            if event.type==QUIT:
                sys.exit()
            if event.type==KEYDOWN:
                if event.key==K_SPACE and self.state=="play":
                    self.player.jump()
            if event.type==COUNTDOWN:
                self.countdown-=1
                if self.countdown

接下来,是绘制操作,先绘制背景,判断,如果输了,就直接在屏幕中显示分数

正在游戏,则更新player的位置,待会Player类会一起讲这个类方法

然后就是绘制玩家和管道,还有左上角的分数,倒计时的时候呢就直接显示倒计时的数字即可,这部分代码不做太详细的讲解

这里,self.tubes中的参数类型如下:

[x坐标,y坐标,管道高度]

    def draw(self):
        self.screen.blit(self.bg,(0,0))
        if self.state=="lose":
            t=self.print_text("simhei",128,str(self.score),(255,0,0))
            tr=t.get_rect()
            tr.center=self.W/2,self.H/2
            self.screen.blit(t,tr)
        if self.state=="play":
            self.player.update()
        self.screen.blit(self.player.image,self.player.rect)
        if self.state=="play":
            self.updateTube()
            for tube in self.tubes:
                x,y=tube[0],tube[1]
                height=tube[2]
                rect=pygame.draw.rect(self.screen,(0,255,0),(x,y,self.tubeWidth,height))
                if self.player.rect.colliderect(rect):
                    self.state="lose"
                    while self.player.rect.top

检查是否撞到管道

    def check(self):
        if self.player.rect.bottom>=self.H or self.player.rect.top

更新管道位置函数

    def updateTube(self):
        self.counter+=1
        if self.counter>=self.toUpdate:
            for i,tube in enumerate(self.tubes):
                tube[0]-=self.tubeSpeed
            self.counter=0
            for i,tube in enumerate(copy.copy(self.tubes)):
                if tube[0]+self.tubeWidth

主循环

    def run(self):
        while True:
            self.listen()
            self.draw()
            pygame.display.update()

将文字处理成Surface对象的静态方法

    @staticmethod
    def print_text(name,size,text,color):
        font=pygame.font.SysFont(name,size)
        image=font.render(text,True,color)
        return image

创建新管道的方法

    def newTube(self):
        spacing=200
        t1h=rd.randint(50,self.H-spacing)
        t2h=self.H-spacing-t1h
        self.tubes.append([self.W,0,t1h])
        self.tubes.append([self.W,t1h+spacing,t2h])

最后是Player类,update即更新Player位置,每被运行4次update进行一次掉落和改变图像的操作,这里有3张图片,连贯起来就像鸟儿在飞的动画一样

class Player:
    def __init__(self):
        self.images=[pygame.image.load(path+"0.png"),
                     pygame.image.load(path+"1.png"),
                     pygame.image.load(path+"2.png")]
        self.item=0
        self.image=self.images[self.item]
        self.rect=self.image.get_rect()
        try:
            self.rect.center=90,game.H/2
        except NameError:
            self.rect.center=90,800/2
        self.fallSpeed=0
        self.counter=0
        self.toUpdate=4

    def jump(self):
        self.fallSpeed=-10

    def fall(self):
        self.rect.y+=self.fallSpeed
        self.fallSpeed+=1

    def change(self):
        self.item+=1
        if self.item>2:
            self.item=0
        self.image=self.images[self.item]

    def update(self):
        self.counter+=1
        if self.counter>=self.toUpdate:
            self.fall()
            self.change()
            self.counter=0

接下来,创建game对象,并启动主循环


if __name__ == '__main__':
    game=Game()
    game.run()

这样就可以实现这个经典FlappyBird游戏啦!代码不长,但可能有些复杂,如果有不清楚的地方可以在评论中提出,或是私信问我,我看到了就会第一时间回复你们提出的问题哒~

这里附上最终的代码

import pygame
from pygame.locals import *
import random as rd
import sys
import copy

path="resources/"
COUNTDOWN=USEREVENT+1
NEWTUBE=USEREVENT+2

class Game:
    def __init__(self):
        pygame.init()
        self.W,self.H=800,800
        self.screen=pygame.display.set_mode((self.W,self.H))
        pygame.display.set_caption("FlappyBird Classic")
        pygame.display.set_icon(pygame.image.load(path+"0.png"))

        self.bg=pygame.transform.smoothscale(pygame.image.load(path+"bg_day.png"),(self.W,self.H))
        self.player=Player()
        self.tubes=[]
        self.tubeWidth=45
        self.counter=0
        self.toUpdate=2
        self.tubeSpeed=2
        self.state="countdown"
        self.countdown=3
        self.score=0
        pygame.time.set_timer(COUNTDOWN,1000)

    def listen(self):
        for event in pygame.event.get():
            if event.type==QUIT:
                sys.exit()
            if event.type==KEYDOWN:
                if event.key==K_SPACE and self.state=="play":
                    self.player.jump()
            if event.type==COUNTDOWN:
                self.countdown-=1
                if self.countdown=self.H or self.player.rect.top=self.toUpdate:
            for i,tube in enumerate(self.tubes):
                tube[0]-=self.tubeSpeed
            self.counter=0
            for i,tube in enumerate(copy.copy(self.tubes)):
                if tube[0]+self.tubeWidth2:
            self.item=0
        self.image=self.images[self.item]

    def update(self):
        self.counter+=1
        if self.counter>=self.toUpdate:
            self.fall()
            self.change()
            self.counter=0

if __name__ == '__main__':
    game=Game()
    game.run()

喜欢的话就点赞关注吧!

Original: https://blog.csdn.net/leleprogrammer/article/details/125617706
Author: Leleprogrammer
Title: Python 用Pygame写一个Flappy Bird经典小游戏

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/778881/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 读书方法

    旧书不厌百回读,熟读深知子自知。 要研究透彻本专业的经典。 读书要学会终身下苦功夫,知十而非真知,不如知一之真知也,读书不能一知半解。 读书决定了一个人的见识和思想的深刻,这些都是…

    Python 2023年10月28日
    057
  • 1.21212E+25

    啊哦~你想找的内容离你而去了哦 内容不存在,可能为如下原因导致: ① 内容还在审核中 ② 内容以前存在,但是由于不符合新 的规定而被删除 ③ 内容地址错误 ④ 作者删除了内容。 可…

    Python 2023年9月26日
    052
  • 用Python制作销售数据可视化看板,展示分析一步到位

    前言 在数据时代,销售数据分析的重要性已无需赘言。 只有对销售数据的准确分析我们才有可能找准数据变动(增长或下滑)的原因。 然后解决问题、发现新的增长点才会成为可能! 今天就给大家…

    Python 2023年11月2日
    036
  • 《HelloGitHub》第 77 期

    兴趣是最好的老师, HelloGitHub 让你对编程感兴趣! 简介 HelloGitHub 分享 GitHub 上有趣、入门级的开源项目。 https://github.com/…

    Python 2023年10月23日
    077
  • numpy.reshape及降低维度或升维的思考

    最近,由于程序最终需要涉及到保存数据,二维数据是可以直接可视化看到的。自己程序生成的是三维数据,需要保存成二维数据。 由此引发了对reshape的一些思考。 我的数据初始维度是(5…

    Python 2023年8月29日
    056
  • STP生成树协议的理解

    一 STP简介 1、单词: rstp快速生成树协议filter过滤protection保护 2、作用: 通过阻塞特定接口来防止二层交换环路,从而做到既可以提高网络可靠性的同时又能避…

    Python 2023年6月3日
    0125
  • python写的2048游戏,源代码,pygame

    代码全是自己写的注释 (怕以后自己再回头看自己写的 看不懂 ) 所有的逻辑基本都写在注释里了 代码肯定不是最简洁的,包含注释400行了 但是应该是相对来说很容易看懂的 毕竟自己作为…

    Python 2023年9月18日
    043
  • Redis——数据操作

    2022-09-20 Redis——select Redis数据库中的数据库的个数为: 16个,使用0号数据库开始的,到第15个数据库结束。 在ubantu中,进入Redis客户端…

    Python 2023年6月9日
    063
  • 深入浅出理解SVM支持向量机算法

    支持向量机是Vapnik等人于1995年首先提出的,它是基于VC维理论和结构风险最小化原则的学习机器。它在解决小样本、非线性和高维模式识别问题中表现出许多特有的优势,并在一定程度上…

    Python 2023年10月25日
    046
  • Linux命令全解

    strace 获取某个可执行文件执行过程中用到的所有系统调用 :strace -f g++ main.cpp &| vim 查看…

    Python 2023年10月20日
    072
  • pycharm安装scrapy时遇到的问题

    在 PyCharm_中 _安装 Scrapy,你可以按照以下步骤进行操作: 1. 打开 PyCharm,并确保你已经创建了一个Python项目。 2. 在 PyCharm_的顶部菜…

    Python 2023年10月3日
    045
  • 豆瓣Top250电影榜单,Python爬虫scrapy框架+selenium爬取数据并把电影图片下载到本地

    最近自己用一个python里面非常常用的爬虫框架scrapy爬取豆瓣Top250电影榜单的一些数据,具体过程如下:首先提前下载好一些库,最主要的是scrapy和selenium 开…

    Python 2023年10月2日
    039
  • python nums函数_Python中基础使用及Numpy、Scipy、Matplotlib 使用教程

    Python是本身是一个通用的编程语言,但其具有一些库(numpy,scipy,matplotlib)用于科学运算,原文的Python的版本是3.5。 本文先进行Python的基本…

    Python 2023年9月5日
    052
  • python 离线安装第三方库

    目的: 解决公司服务器、电脑不能上网,然而需安装python三方库问题。 解决客户安全问题导致不能连接外网,只能安装扫描文件的问题。 解决公司内网下载很快而自己未连内网下载很慢时,…

    Python 2023年9月1日
    043
  • 解决新创建的anaconda环境在C:Usersxxx.condaenvs,而不在anaconda安装目录下的envs中

    文章目录 问题描述 问题分析 解决方法 参考资料 问题描述 今天调试一个模型的代码时,需要新创建一个anaconda的环境,而新创建的环境之前都是在anaconda安装目录下的en…

    Python 2023年8月1日
    057
  • p2p开户银行审核模块功能实现

    审核模块简介 用户提交开户申请后要等待审核通过才能审核成功审核需要银行系统进行开户 使用flask框架搭建一个银行系统用户提交审核 银行进行开户,在返回p2p后台通过审核 flas…

    Python 2023年8月12日
    086
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球