python游戏之小鸟飞下水道(Flappy Bird)。
一、游戏简介
Flappy Bird 这款游戏中,玩家只需要一根手指来操控,单机触摸手机屏幕,小鸟就会往上飞,不断的单机屏幕,小鸟就会不断地往高处飞;放松手指,就会快速下降。玩家只要控制小鸟一直向前飞行,并且注意躲避高低不平的管子。如果小鸟碰到障碍物,游戏就会结束,每当小鸟飞过一组管道,玩家就会得到1分。
二、游戏分析
在游戏中,主要有2个对象:小鸟和管道。可以创建Bird类和Pineline类来分别表示这2个对象。小鸟可以通过上下来移动躲避管道,所以在Bird类中创建一个birdUpadate()方法,实现小鸟的上下移动。为了体现小鸟向前飞行的特征,可以让管道一直向左移动,这样在窗口中就好像小鸟在向前飞行。所以,在Pineline类中创建一个updatePipeline()方法,实现管道的向左移动。此外创建3个函数:createMap()函数用于绘制地图。checkDead()函数用于判断小鸟的生命状态;getResult()函数用于获取最终分数。最后在主逻辑中,实例化类并调用相关方法,实现相应功能。
三、搭建主框架
通过前面的分析,我们可以搭建起游戏的主框架。先创建2个类,具体的方法可以用pass语句来代替,然后在创建绘制地图函数createMap(),最后,在主逻辑绘制背景图片。关键代码如下:
import pygame, sys, random class Bird(): """小鸟类""" def __init__(self):#定义属性 pass """定义初始化方法""" def UpdateBird(self): pass class Pipeline(): """管道类""" def __init__(self): pass def UpdatePipeline(self): """水平移动""" pass def createMap(): """创建地图的方法""" screen.fill((255,255,255)) # 填充色 screen.blit(background, (0, 0)) # 填入到背景 pygame.display.update() # 更新显示 if __name__ == "__main__": pygame.init() # 初始化pygame size = width, height = 288, 512 # 设置窗口大小 screen = pygame.display.set_mode(size) # 显示窗口 clock = pygame.time.Clock() # 设置时钟 Pipeline = Pipeline() # 实例化管道 Bird = Bird() # 实例化小鸟 while True: clock.tick(60) # 每秒执行60次 for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() background = pygame.image.load("./sucai/beijing.png") createMap() # 绘制地图 # pygame.quit
游戏运行结果
四、创建小鸟类
该类需要初始化很多参数,所以定义一个__init__()方法,用来初始化各种参数,包括鸟飞行的集中状态、飞行的速度、跳跃的高度等,然后定义birdUpdate()方法。该方法用于实现小鸟的跳跃和坠落。接下来,主逻辑的轮询事件中添加键盘按下事件或者鼠标点击事件,如果按下鼠标,使小鸟上升等。最后在createMap()方法中,显示小鸟的图像。
X轴坐标:小鸟是上下移动,X轴是坐标是固定的
Y轴坐标:小鸟上下移动,会改变Y轴的坐标
生命状态:需要一直判断小鸟的生命状态,如果死亡了,游戏结束
是否跳跃:跳跃,Y轴减小。需要设置小鸟的上升下降速度。
import pygame, sys, random class Bird(): """小鸟类""" def __init__(self):#定义属性 """定义初始化方法""" self.birdStatus = [pygame.image.load(r"C:\Users\HZT\PycharmProjects\aotu\bird_game\fei.png"), pygame.image.load(r"C:\Users\HZT\PycharmProjects\aotu\bird_game\ting.png"), pygame.image.load(r"C:\Users\HZT\PycharmProjects\aotu\bird_game\si.png")] self.status = 0 #默认的飞行状态 self.birdX = 100 #默认小鸟在X轴的位置 self.birdY = 100 #默认小鸟在Y轴的位置 self.jump = False #默认情况小鸟自动降落 self.jumpSpeed = 10#小鸟上升的速度 self.gravity = 5 #降落的速度 self.dead = False #小鸟默认没有死亡 def birdUpdate(self):# """定义移动方法""" if self.jump:#小鸟是否跳跃 self.jumpSpeed -= 1 #如果跳跃,那小鸟上升的速度减小(阻力)并Y轴具体数值减小 self.birdX -= self.jumpSpeed #self.birdY = self.birdY - self.birdY - self.jumpSpeed#小鸟上升后Y轴的高度 else:#小鸟未跳跃那就坠落,坠落的速度会越来越快 self.gravity += 0.2#坠落速度变快 self.birdX += self.gravity #Y轴距离增加 #小鸟是否跳跃 class Pipeline(): """管道类""" def __init__(self): pass def UpdatePipeline(self): """水平移动""" pass def createMap(): """创建地图的方法""" # 填入到背景 if Bird.dead :#如果小鸟没有死亡 Bird.status = 2#对应小鸟类的图片索引 elif Bird.jump:#如果小鸟跳跃了 Bird.status = 1 # screen.fill((255,255,255)) # 填充色 background = pygame.image.load(r"C:\Users\HZT\PycharmProjects\aotu\bird_game\beijing.png") screen.blit(background, (0, 0)) screen.blit(Bird.birdStatus[Bird.status], (Bird.birdY, Bird.birdX)) # 把小鸟加载至窗口 pygame.display.update() # 更新显示 Bird.birdUpdate() # 更新小鸟的状态 if __name__ == "__main__": pygame.init() # 初始化pygame size = width, height = 288, 512 # 设置窗口大小 screen = pygame.display.set_mode(size) # 显示窗口 clock = pygame.time.Clock() # 设置时钟 Pipeline = Pipeline() # 实例化管道 Bird = Bird() # 实例化小鸟 while True: clock.tick(30) # 每秒执行60次 for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if (event.type == pygame.KEYDOWN or event.type == pygame.MOUSEBUTTONDOWN) and not Bird.dead: #如果按键盘的任意键或者鼠标点击,和小鸟没死的状态下, Bird.jump = True Bird.gravity = 5 Bird.jumpSpeed = 10 createMap() # 绘制地图 # pygame.quit
上述代码中Bird类中设置了birdStatus属性,该属性是一个鸟类的图片的列表,默认情况下,小鸟会一直下降,单机鼠标或者按下键盘,小鸟会跳跃,高度上升,运行效果如图所示。
五、创建管道类
在__ini__()方法中初始化各种参数,包括设置管道的坐标,加载上下管道图片等,在updatePipeline()方法中,定义管道向左移动的速度,并且管道移出屏幕时,重新绘制一下组管道,最后在createMap()函数中显示管道。
代码如下:
import pygame, sys, random class Bird(): """小鸟类""" def __init__(self): # 定义属性 """定义初始化方法""" self.birdStatus = [pygame.image.load(r"C:\Users\HZT\PycharmProjects\aotu\bird_game\fei.png"), pygame.image.load(r"C:\Users\HZT\PycharmProjects\aotu\bird_game\jiang1.png"), pygame.image.load(r"C:\Users\HZT\PycharmProjects\aotu\bird_game\si.png")] self.status = 0 # 默认的飞行状态 self.birdX = 100 # 默认小鸟在X轴的位置 self.birdY = 100 # 默认小鸟在Y轴的位置 self.jump = False # 默认情况小鸟自动降落 self.jumpSpeed = 10 # 小鸟上升的速度 self.gravity = 5 # 降落的速度 self.dead = False # 小鸟默认没有死亡 def birdUpdate(self): # """定义移动方法""" if self.jump: # 小鸟是否跳跃 self.jumpSpeed -= 1 # 如果跳跃,那小鸟上升的速度减小(阻力)并Y轴具体数值减小 self.birdX -= self.jumpSpeed # self.birdY = self.birdY - self.birdY - self.jumpSpeed#小鸟上升后Y轴的高度 else: # 小鸟未跳跃那就坠落,坠落的速度会越来越快 self.gravity += 0.2 # 坠落速度变快 self.birdX += self.gravity # Y轴距离增加 # 小鸟是否跳跃 class Pipeline(): """管道类""" def __init__(self): self.wallx = 280 # 滚到在X轴的位置 self.pinUp = pygame.image.load(r"C:\Users\HZT\PycharmProjects\aotu\bird_game\pipe_down.png") self.pinDown = pygame.image.load(r"C:\Users\HZT\PycharmProjects\aotu\bird_game\pipe_up.png") # 加载上管道下管道 def UpdatePipeline(self): """水平移动""" self.wallx -= 2 # 管道X轴坐标递减,既管道向左移动 if self.wallx < -40: self.wallx = 280 def createMap(): """创建地图的方法""" # 填入到背景 if Bird.dead: # 如果小鸟没有死亡 Bird.status = 2 # 对应小鸟类的图片索引 if Bird.jump: # 如果小鸟跳跃了 Bird.status = 1 # screen.fill((255,255,255)) # 填充色 # 显示小鸟 background = pygame.image.load(r"C:\Users\HZT\PycharmProjects\aotu\bird_game\beijing.png") screen.blit(background, (0, 0)) screen.blit(Bird.birdStatus[Bird.status], (Bird.birdY, Bird.birdX)) # 把小鸟加载至窗口 screen.blit(Pipeline.pinUp, (Pipeline.wallx, -180)) # 上管道坐标位置 screen.blit(Pipeline.pinDown, (Pipeline.wallx, 380)) # 下管道坐标位置 Bird.birdUpdate() # 更新小鸟的状态 Pipeline.UpdatePipeline() pygame.display.update() # 更新显示 if __name__ == "__main__": pygame.init() # 初始化pygame size = width, height = 288, 512 # 设置窗口大小 screen = pygame.display.set_mode(size) # 显示窗口 clock = pygame.time.Clock() # 设置时钟 # 实例化管道 Bird = Bird() # 实例化小鸟 Pipeline = Pipeline() while True: clock.tick(60) # 每秒执行60次 for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() if (event.type == pygame.KEYDOWN or event.type == pygame.MOUSEBUTTONDOWN) and not Bird.dead: # 如果按键盘的任意键或者鼠标点击,和小鸟没死的状态下, Bird.jump = True Bird.gravity = 5 Bird.jumpSpeed = 10 createMap() # 绘制地图 # pygame.quit