童年记忆第四弹!!! 如何用Python写一个胖鸟快飞

经典复刻—用python做童年玩过的小游戏

童年记忆第一弹——俄罗斯方块

童年记忆第二弹——植物大战僵尸

童年记忆第三弹——天天酷跑

前言

写到童年游戏第四弹了,突然想到以前玩过的一个很有意思的游戏,叫胖鸟快飞,就是一只鸟,通过不断的点击调整位置,通过钢管的游戏,今天我们就来写写这个游戏吧~

python游戏开发:(胖鸟快飞)

我们用第三方库pygame和python的基本语法来开发,此款游戏代码行数不超过100行,即使是初学者也可以轻松的了解。最重要的是,通过开发这个游戏不仅可以稳固python的基础知识,而且能让枯燥的代码变得鲜活生动,就像是做饭一样,自己做的永远比别人做的好吃。

DEB268C3115F07B212827C09A9093F14.png

pygame安装:pip install pygame;(有编译器的小伙伴可以在setting中进行导入)

第一步:了解游戏的基础框架;

游戏的形成就是运行界面的不停刷新,而死循环恰好就能实现此种功能,循环体内部就是游戏主体模块;

import pygame,time
from pygame.locals import *#导入库文件
img=pygame.image.load('图片url')#加载图片素材 

def GameOver():    
    pygame.quit()#游戏退出 

def main():
    pygame.init()#游戏初始化    
    windowSize=pygame.display.set_mode([480,640])#游戏窗口界面    
    pygame.display.set_caption('游戏名称')#游戏标题设置    
    pygame.display.update()#游戏界面刷新    
    while True: 
        '''游戏主体模块''' 
        '''事件响应'''
        for event in pygame.event.get(): 
           if event.type==QUIT: 
               pygame.quit()#游戏退出        
        windowsSize.fill(pygame.Color(R,G,B))#窗体背景颜色填充,默认为黑色
        pygame.display.update()#游戏界面刷新
        time.sleep('休眠时间')#一般是0.05-0.09 

if __name__=='__main__':
    main()#主函数

运行结果:(背景色为黑色的,大小为480*640的窗体)

6C044326CDA056A6AE7FDB3CF3EE669D.png

第二步:绘制简单图像并实现简单的按键响应;

首先我们要理解什么是面向对象的概念,并通过恰当的方式构造我们所需要的类,以方便我们的后序操作;

不了解的小伙伴们可以从这里学习相关知识:https://blog.csdn.net/weixin_44638960/article/details/95233484

class Bird:#胖鸟类    
position=[30,200]#鸟的初始位置    
birdColor=pygame.Color(255,255,0)#一只黄色的小鸟    
speed=1#小鸟的速度    
bird_score=0#小鸟得分

在定义完类之后我们可以通过此模板来实例化一个胖鸟对象:bird=Bird()

之后我们在构造自己的Draw方法,来实现简单的图形绘制;(pygame提供了draw来实现简单图像的绘制这里我们来绘制一个简单的矩形。)

python函数的定义与使用:https://blog.csdn.net/weixin_44638960/article/details/94551997

image
def DrawRect(windowsSize,bird):
    pygame.draw.rect(windowsSize,bird.birdColor,Rect(bird.position[0],bird.position[1],30,30))

运行结果:(在幕布上出现了一个黄色的矩形,也就是我们的胖鸟,后期我们会让它更加生动)

0701D54094BF1B2E81DDCC0786DA03E6.png

那么问题又来了,如何使这个小胖鸟通过按键响应来动起来呢。pygame提供了type属性来判断按键的状态以及key属性来判断哪一个按键被触发,根据不同的情况来响应不同的事件。

flag=0#这里我们加一个标志位,如果鸟想要飞就不会下降
for event in pygame.event.get():
            if event.type == QUIT:
                GameOver()  #游戏退出
            elif event.type==KEYDOWN:#按键响应
                if event.key==K_SPACE:
                    bird.position[1]=bird.position[1]-bird.speed*50*level
                    #根据等级胖鸟上升或下降
                    flag=1
if flag==0:#检测位
   bird.position[1]=bird.position[1]+bird.speed*10*level
flag=0

做到这里是不是开始觉得有点游戏的样子了,我们的小胖鸟可以根据我们按空格的频率上升或下降了(哈哈);

第三步:障碍物的制作与移动;

同构造鸟类一样,我们类似的构造一个管道类;

class PipeLine:#管道类
    pipe_x=300#记录管道横坐标位置
    pipe_y=[]#留给小鸟飞行的间隙
    pipeColor=pygame.Color(115,190,44)#管道的颜色

在使用管道之前我们要对其进行初始化Init,根据纵坐标的计算我们留出4个空位置给胖鸟,并在初始化中将这几个空位加以标注,方便我们后期绘制管道障碍物。下面是我们构造的PipeInit方法;

def PipeInit(pipe):#初始化管道
    start = random.randint(0, 10) * 30
    pipe.pipe_y.append(start)
    pipe.pipe_y.append(start + 30)
    pipe.pipe_y.append(start + 60)
    pipe.pipe_y.append(start + 90)

胖鸟是通过空格键进行上下的移动,而管道的移动则不受用户的控制且移动方向为水平从右向左依次运动,这里我们采用了随着循环的移动将管道横坐标位置依次减1的方式实现鸟儿与管道的相对运动,而这些操作都可以与管道的绘制同时进行。下面我们来构造绘制管道的方法:

def DrawPipeLine(windowSize,pipeList,bird):#绘制管道
    for pipe in pipeList:
        pipe.pipe_x=pipe.pipe_x - 10
        for i in range(0,20):
            if i*30 not in pipe.pipe_y:#not in实现空隙的留白
                     pygame.draw.rect(windowSize, pygame.Color(0,145,0), Rect(pipe.pipe_x, i*30, 60, 30))#绘制矩形管道
            if pipe.pipe_x<=-40:#判断管道是否移动出界
                 bird.g_score = bird.g_score + 1#游戏成绩增加
                 pipe.pipe_x=480
                 pipe.pipe_y=[]
                 PipeInit(pipe)
                 pipeList.pop()#弹出移出屏幕的管道
                 pipeList.append(pipe)#将新管道添加进入管道列表

第四步:游戏胜负结果的判断;

到此为止我们基本已经实现了该游戏的全部功能,但每个游戏都会结束,我们这个游戏目前只是实现了地图和精灵的移动,并没有实现能使游戏结束的功能;在这里我们使用一个Check方法来对游戏进行判断;

def CheckGame(bird,pipe):#游戏判断
    if bird.position[1]<0 or bird.position[1]>570:
        pygame.quit()#跑出上下界限
    if bird.position[0]+30>pipe[0].pipe_x and bird.position[0]<pipe[0].pipe_x+60:
        if bird.position[1]<pipe[0].pipe_y[0] or bird.position[1]+20>pipe[0].pipe_y[3]:
            pygame.quit()#游戏退出

有了此方法我最后一个主要功能也就到此结束了,下面我们来看一下此时游戏是不是与之前产生了区别,而且可玩性也有了质的飞跃(有些些许激动了吧,开始运行一下我们这个简单的demo吧)

6126FD9D46EDCAC78E66C61EC57BFBB7.png

第五步:游戏界面的优化与图片的导入;

怎么样是不是可以运行了,而且与我们预想的胖鸟是不是类似呢?但这是不是也有点太单调了,下面我们开始让着整个游戏界面更加的生动起来。之前我们提到的windowSize.fill()方法默认填充的是黑色我们只需修改填充背景的RGB颜色值即可将背景色改变成我们想要的颜色。

对于这只笨笨的黄色小胖鸟(长得确实挺方的),我们来对它进行一下整容,导入一个胖鸟图片并对原来绘制矩形的地方做出相应的修改即可让它脱胎换骨;

游戏精灵导入格式:flappyBird = pygame.image.load("Bird.png")#加载游戏图片;

image

对于游戏得分的提示信息,可以通过pygame中自带的font设置字体字号,将其添加到幕布中即可(在这里我们只给出得分提示信息的代码,你也可以根据需要填充其他的提示信息)。

font = pygame.font.SysFont('宋体', 24);
text = font.render("Game Score:" + str(bird.g_score), True, (255, 255, 255));
windowsSize.blit(text, Rect(360, 10, 200, 120));#text为所填充的文本内容,Rent(x,y,len,width)

FINALLY 圆满收官(MayBe 我或许会添加新的功能模块):

游戏完整代码:

import pygame,random,sys,time
from pygame.locals import *#导入库文件
flappyBird = pygame.image.load("Bird.png")#加载游戏图片
level=1#游戏等级
 
class Brid:#鸟类
    position = [10,200]#初始位置
    speed=1#移动速度
    g_score = 0  # 游戏得分
    BridColor=pygame.Color(255,255,0)#颜色黄色
 
class PipeLine:#管道类
    pipe_x=300
    pipe_y=[]
    pipeColor=pygame.Color(115,190,44)
 
def GameOver():
    pygame.quit()#游戏退出
 
def Leveling(count):#等级判定
    if count<=10:
        return 1
    else:
        return count/10 

def GameInit(windowSize,brid):#游戏初始化
    windowSize.blit(flappyBird,Rect(brid.position[0], brid.position[1], 30, 30))
    pygame.display.update()
 
def PipeInit(pipe):#初始化管道
    start = random.randint(0, 10) * 30
    pipe.pipe_y.append(start)
    pipe.pipe_y.append(start + 30)
    pipe.pipe_y.append(start + 60)
    pipe.pipe_y.append(start + 90) 

def DrawPipeLine(windowSize,pipeList,bird):#绘制管道
    for pipe in pipeList:
        pipe.pipe_x=pipe.pipe_x - 10
        for i in range(0,20):
            if i*30 not in pipe.pipe_y:
                     pygame.draw.rect(windowSize, pygame.Color(0,145,0), Rect(pipe.pipe_x, i*30, 60, 30))
            if pipe.pipe_x<=-40:
                 bird.g_score = bird.g_score + 1
                 pipe.pipe_x=480
                 pipe.pipe_y=[]
                 PipeInit(pipe)
                 pipeList.pop()
                 pipeList.append(pipe)  


def CheckGame(bird,pipe):#游戏判断
    if bird.position[1]<0 or bird.position[1]>570:
        pygame.quit()#跑出上下界限
    if bird.position[0]+30>pipe[0].pipe_x and bird.position[0]<pipe[0].pipe_x+60:
        if bird.position[1]<pipe[0].pipe_y[0] or bird.position[1]+20>pipe[0].pipe_y[3]:
            pygame.quit()#游戏退出 

def main():
    flag=0#标记位
    pygame.init()#游戏初始化
    windowsSize=pygame.display.set_mode([480,600])#设置窗口大小
    pygame.display.set_caption('FlappyBrid')  # 窗口标题
    font = pygame.font.SysFont('宋体', 24)
    bird=Brid()#创建鸟实例
    pipeList=[]#管道列表
    pipe1= PipeLine()
    pipe2= PipeLine()
    PipeInit(pipe1)
    pipe2=pipe1#对象的值拷贝
    pipe2.pipe_x=pipe2.pipe_x+80
    pipeList.append(pipe1)
    pipeList.append(pipe2)
    windowsSize.fill(pygame.Color(113,197,205))
    GameInit(windowsSize,bird)#游戏初始化
    DrawPipeLine(windowsSize,pipeList,bird)
    while True:#游戏主体
        level = Leveling(bird.g_score)
        text = font.render("Game Score:" + str(bird.g_score), True, (255, 255, 255))
        text1 = font.render("Level:" + str(level), True, (255, 255, 255))
        for event in pygame.event.get():
            if event.type == QUIT:
                GameOver()  #游戏退出
            elif event.type==KEYDOWN:#按键响应
                if event.key==K_SPACE:
                    bird.position[1]=bird.position[1]-bird.speed*50*level
                    flag=1
        if flag==0:#检测位
            bird.position[1]=bird.position[1]+bird.speed*10*level
        flag=0
        windowsSize.fill(pygame.Color(113,197,205))
        CheckGame(bird, pipeList)
        DrawPipeLine(windowsSize,pipeList,bird)
        windowsSize.blit(text, Rect(360, 10, 200, 120))
        windowsSize.blit(text1, Rect(360, 40, 200, 120))
        GameInit(windowsSize,bird)
        time.sleep(0.1-level/100) 
if __name__=='__main__':
    main()#主函数

游戏运行截图:

ECD6D548DDA22570E6926639F9B20FF0.png

总结

以上就是胖鸟快飞的源码过程,大家可以写一下玩一玩
我是白白,一个喜欢学习喜欢编程的年轻人
需要学习资料的请在评论区扣“1”
想学习python的可以关注私信我哦~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,014评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,796评论 3 386
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,484评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,830评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,946评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,114评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,182评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,927评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,369评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,678评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,832评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,533评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,166评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,885评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,128评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,659评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,738评论 2 351

推荐阅读更多精彩内容