童年记忆第四弹!!! 怎么用Python写一个胖鸟快
###前言
写到童年游戏第四弹了,突然想到以前玩过的一个很有意思的游戏,叫胖鸟快飞,就是一只鸟,通过不断的点击调整位置,通过钢管的游戏,今天我们就来写写这个游戏吧~
我们用第三方库pygame和python的基本语法来开发,此款游戏代码行数不超过100行,即使是初学者也可以轻松的了解。最重要的是,通过开发这个游戏不仅可以稳固python的基础知识,而且能让枯燥的代码变得鲜活生动,就像是做饭一样,自己做的永远比别人做的好吃。
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()#游戏初始化
indoSize=pygame.display.set_mode([480,640])#游戏窗口界面
pygame.display.set_caption('游戏名称')#游戏标题设置
pygame.display.update()#游戏界面刷新
hile True:
'''游戏主体模块'''
'''事件响应'''
for event in pygame.event.get():
if event.type==QUIT:
pygame.quit()#游戏退出
indosSize.fill(pygame.Color(R,G,B))#窗体背景颜色填充,默认为黑色
pygame.display.update()#游戏界面刷新
time.sleep('休眠时间')#一般是0.05-0.09
if __name__=='__main__':
main()#主函数
运行结果(背景色为黑色的,大小为480640的窗体)
第二步绘制简单图像并实现简单的按键响应;我们要理解什么是面向对象的概念,并通过恰当的方式构造我们所需要的类,以方便我们的后序操作;
class Bird:#胖鸟类
position=[30,200]#鸟的初始位置
birdColor=pygame.Color(255,255,0)#一只黄色的小鸟
speed=1#小鸟的速度
bird_score=0#小鸟得分
在定义完类之后我们可以通过此模板来实例化一个胖鸟对象bird=Bird();
之后我们在构造自己的Dra方法,来实现简单的图形绘制;(pygame提供了dra来实现简单图像的绘制这里我们来绘制一个简单的矩形。)
def DraRect(indosSize,bird):
pygame.dra.rect(indosSize,bird.birdColor,Rect(bird.position[0],bird.position[1],30,30))
运行结果(在幕布上出现了一个黄色的矩形,也就是我们的胖鸟,后期我们会让它更加生动)
那么问题又来了,如何使这个小胖鸟通过按键响应来动起来呢。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.speed50level
#根据等级胖鸟上升或下降
flag=1
if flag==0:#检测位
bird.position[1]=bird.position[1]+bird.speed10level
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 DraPipeLine(indoSize,pipeList,bird):#绘制管道
for pipe in pipeList:
pipe.pipe_x=pipe.pipe_x - 10
for i in range(0,20):
if i30 not in pipe.pipe_y:#not in实现空隙的留白
pygame.dra.rect(indoSize, pygame.Color(0,145,0), Rect(pipe.pipe_x, i30, 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_y[3]:
pygame.quit()#游戏退出
有了此方法我一个主要功能也就到此结束了,下面我们来看一下此时游戏是不是与之前产生了区别,而且可玩性也有了质的飞跃(有些些许激动了吧,开始运行一下我们这个简单的demo吧)
第五步游戏界面的优化与图片的导入;怎么样是不是可以运行了,而且与我们预想的胖鸟是不是类似呢?但这是不是也有点太单调了,下面我们开始让着整个游戏界面更加的生动起来。之前我们提到的indoSize.fill()方法默认填充的是黑色我们只需修改填充背景的RGB颜色值即可将背景色改变成我们想要的颜色。
对于这只笨笨的黄色小胖鸟(长得确实挺方的),我们来对它进行一下整容,导入一个胖鸟图片并对原来绘制矩形的地方做出相应的修改即可让它脱胎换骨;
游戏精灵导入格式flappyBird = pygame.image.load(“Bird.png”)#加载游戏图片;
对于游戏得分的提示信息,可以通过pygame中自带的font设置字体字号,将其添加到幕布中即可(在这里我们只给出得分提示信息的代码,你也可以根据需要填充其他的提示信息)。
font = pygame.font.SysFont(‘宋体’, 24);
text = font.render(“Game Score:” + str(bird.g_score), True, (255, 255, 255));
indosSize.blit(text, Rect(360, 10, 200, 120));#text为所填充的文本内容,Rent(x,y,len,idth)
游戏完整代码
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(indoSize,brid):#游戏初始化
indoSize.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 DraPipeLine(indoSize,pipeList,bird):#绘制管道
for pipe in pipeList:
pipe.pipe_x=pipe.pipe_x - 10
for i in range(0,20):
if i30 not in pipe.pipe_y:
pygame.dra.rect(indoSize, pygame.Color(0,145,0), Rect(pipe.pipe_x, i30, 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_y[3]:
pygame.quit()#游戏退出
def main():
flag=0#标记位
pygame.init()#游戏初始化
indosSize=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)
indosSize.fill(pygame.Color(113,197,205))
GameInit(indosSize,bird)#游戏初始化
DraPipeLine(indosSize,pipeList,bird)
hile 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.speed50level
flag=1
if flag==0:#检测位
bird.position[1]=bird.position[1]+bird.speed10level
flag=0
indosSize.fill(pygame.Color(113,197,205))
CheckGame(bird, pipeList)
DraPipeLine(indosSize,pipeList,bird)
indosSize.blit(text, Rect(360, 10, 200, 120))
indosSize.blit(text1, Rect(360, 40, 200, 120))
GameInit(indosSize,bird)
time.sleep(0.1-level/100)
if __name__=='__main__':
main()#主函数
游戏运行截图
#