资源简介 (共48张PPT)Python少儿编程第十一章 一起来创作——Flappy Bird目录1.1需求分析1.2模块设计1.2功能实现PART 01需求分析需求分析1小舞和小蓝在游戏城中参与了多个游戏,最后他们的账户中分别都有了7枚徽章。他们觉得这样获得徽章的速度太慢,于是找到游戏城的主人,想给他开发一个新游戏——Flappy Bird。主人非常乐意,并承诺如果游戏测试成功将给他们6枚徽章,这样他们就可以离开Python编程世界了。游戏功能如下。使用鼠标控制小鸟通过上下管道的间隙,如果小鸟碰到管道或窗口则游戏结束,实时显示得分(即小鸟通过的管道数),详细需求如下。(1)单击鼠标开始游戏和控制小鸟飞行。(2)随机生成管道位置,实现上下管道间隙的大小不同。(3)移动地面和管道模拟小鸟向前飞行。(4)小鸟和管道的碰撞检测。(5)小鸟飞行、碰撞和得分时添加音效。(6)显示游戏得分。PART 02模块设计模块设计2根据Flappy Bird游戏需求,可将程序分为5大模块,分别是资源文件夹模块、配置文件模块、类包模块、游戏包模块和主模块,如图11-1所示。图11-1 Flappy Bird程序模块设计模块设计2(1)资源文件夹模块用于保存图片、声音和字体等资源文件。(2)配置文件模块用于保存常量和资源路径。(3)类包模块包含管道类模块和小鸟类模块,实现管道和小鸟的初始化和更新等功能。(4)游戏包模块包含游戏开始模块、游戏进行模块和游戏结束模块,实现显示游戏开始界面、操作游戏和显示游戏结束界面等功能。(5)主模块实现初始化游戏、加载资源、显示得分和控制游戏流程等功能,然后循环控制游戏流程。PART 03功能实现创建资源文件夹3.1游戏需要加载图片、添加音效和显示得分,因此,须在当前工作目录的resources文件夹下创建3个文件夹保存相关资源文件。(1)创建名为images的文件夹保存图片,包括背景、开始游戏、结束游戏、管道、小鸟、地面等图片。其中,小鸟图片又包括翅膀处于上、中和下3种形态的图片,用于模拟小鸟的飞行。(2)创建名为audios的文件夹保存声音,包括小鸟飞行、死亡、碰撞管道和通过管道得分时的音效。(3)创建名为fonts的文件夹保存字体文件,用于显示得分。创建配置文件3.2创建配置文件cfg.py,保存常量和资源路径,实现代码如下。FPS = 60 #定义FPSSCREENWIDTH = 300 #定义窗口宽SCREENHEIGHT = 500 #定义窗口高PIPE_GAP_SIZE = 100 #定义上下管道间隙大小#定义字典,保存小鸟3种形态图片路径BIRD_IMAGE_PATHS = {'up': 'resources/images/bird_up.png','mid': 'resources/images/bird_mid.png','down': 'resources/images/bird_down.png'}创建配置文件3.2#定义背景图片路径BACKGROUND_IMAGE_PATHS = 'resources/images/background.png'#定义管道图片路径PIPE_IMAGE_PATHS = 'resources/images/pipe.png'#定义字典,保存游戏开始、游戏结束、地面图片路径OTHER_IMAGE_PATHS = {'gamestart': 'resources/images/gamestart.png','gameover': 'resources/images/gameover.png','base': 'resources/images/base.png'}创建配置文件3.2#定义字典,保存音效文件路径AUDIO_PATHS = {'die': 'resources/audios/die.wav','hit': 'resources/audios/hit.wav','point': 'resources/audios/point.wav','wing': 'resources/audios/wing.wav'}#定义字体文件路径FONT_PATHS = 'resources/fonts/simkai.ttf'创建类包3.3(1)定义管道类Piple继承pygame.sprite.Sprite类,在有参构造方法中调用父类的构造方法,然后使用传递的参数初始化图片和得分标志等相关变量,实现代码如下。1.创建管道类import randomimport pygame'''定义Pipe类,继承pygame.sprite.Sprite类'''class Pipe(pygame.sprite.Sprite):def __init__(self, image, position, **kwargs):pygame.sprite.Sprite.__init__(self) #调用父类构造方法self.image = image #初始化管道图片self.rect = self.image.get_rect() #获取图片的rect#将图片x和y坐标赋给图片的左侧和顶部位置self.rect.left, self.rect.top = positionself.used_for_score = False #得分标志赋为False创建类包3.3(2)在Pipe类中定义静态方法randomPipe()生成上下管道初始位置并返回,其中y方向位置随机生成,实现代码如下。1.创建管道类'''随机生成管道初始位置'''@staticmethoddef randomPipe(cfg, image):base_y = 0.79 * cfg.SCREENHEIGHT #定义基准位置#定义y方向位置取值范围的最大值up_y = int(base_y * 0.6 - cfg.PIPE_GAP_SIZE)#随机生成y方向位置y = int(base_y * 0.2) + random.randrange(0, up_y)#返回一组上下管道的位置,top表示上管道,bottom表示下管道return {'top': (cfg.SCREENWIDTH + 10, y - image.get_height()),'bottom': (cfg.SCREENWIDTH + 10, y + cfg.PIPE_GAP_SIZE)}创建类包3.3(1)定义小鸟类Bird继承pygame.sprite.Sprite类,在有参构造方法中调用父类构造方法,然后使用传递的参数初始化图片、y方向运动变量、切换小鸟形态变量等,实现代码如下。2.创建小鸟类import pygameimport itertools'''定义Bird类,继承pygame.sprite.Sprite类'''class Bird(pygame.sprite.Sprite):def __init__(self, images, id, position, **kwargs):pygame.sprite.Sprite.__init__(self) #调用父类构造方法self.images = images #初始化小鸟图片字典#将小鸟图片字典的值转换为列表,并获取索引为id的图片self.image = list(images.values())[id]self.rect = self.image.get_rect() #获取当前图片的rect创建类包3.32.创建小鸟类#将图片x和y坐标赋给图片的左侧和顶部位置self.rect.left, self.rect.top = position#定义y方向运动变量,包括飞行标志、上升速度和下落速度self.is_flapped = Falseself.up_speed = 9self.down_speed = 0#切换小鸟形态变量,包括图片索引及其迭代器、索引计数#迭代器包含一个小鸟飞行周期内图片索引取值self.bird_id = idself.bird_id_cycle = itertools.cycle([0, 1, 2, 1])self.bird_id_change_count = 0创建类包3.3(2)在Bird类中定义update()方法,更新小鸟位置和形态,参数为上下边界位置和时间间隔(时钟的间隔时间/1000,用于计算上升和下落速度),返回死亡状态。该方法实现判断小鸟飞行状态(上升或下落),是否碰撞上下边界而死亡,并模拟小鸟扇动翅膀。2.创建小鸟类'''更新小鸟位置和形态'''def update(self, boundary, time_passed):if self.is_flapped: #如果飞行标志为True即上升self.up_speed -= 60 * time_passed #计算上升速度self.rect.top -= self.up_speed #计算图片的顶部位置if self.up_speed <= 0: #如果上升速度小于0self.is_flapped = False #设置飞行标志为False即下落self.up_speed = 9 #设置上升速度为9self.down_speed = 0 #设置下落速度为0创建类包3.32.创建小鸟类else:self.down_speed += 40 * time_passed #计算下落速度self.rect.bottom += self.down_speed #计算图片底部位置'''判断小鸟是否碰撞上下边界'''is_dead = False #定义死亡标志,赋初值为False#如果图片底部位置大于下边界,死亡标志赋为True#图片底部值赋为下边界,保证小鸟停在下边界位置,不继续下落if self.rect.bottom > boundary[1]:is_dead = Trueself.rect.bottom = boundary[1]#如果图片顶部位置小于上边界,死亡标志赋为True#图片顶部值赋为上边界,保证小鸟停在上边界位置,不继续上升if self.rect.top < boundary[0]:is_dead = Trueself.rect.top = boundary[0]创建类包3.32.创建小鸟类'''切换小鸟形态模拟扇动翅膀'''self.bird_id_change_count += 1 #索引计数加1#如果图片索引计数是5的倍数,表示循环5次切换一次小鸟形态if self.bird_id_change_count % 5 == 0:#将迭代器的下一个值赋给图片索引self.bird_id = next(self.bird_id_cycle)#获取索引对应的图片self.image = list(self.images.values())[self.bird_id]self.bird_id_change_count = 0 #索引计数赋为0return is_dead #返回死亡标志创建类包3.3(3)在Bird类中定义setFlapped()方法设置小鸟的飞行模式,在游戏中单击鼠标时调用,实现代码如下。2.创建小鸟类'''设置为飞行模式'''def setFlapped(self):if self.is_flapped: #如果飞行标志为True,重新设置上升速度self.up_speed = max(12, self.up_speed+1)else: #如果飞行标志为False,则设置为Trueself.is_flapped = True(4)在Bird类中定义draw()方法绘制小鸟,实现代码如下。'''绘制小鸟'''def draw(self, screen):screen.blit(self.image, self.rect) #绘制图片创建游戏包3.41.创建游戏开始模块在game_package包中创建游戏开始模块start_game.py,在其中定义startGame()函数显示开始界面,包括背景、开始图片、向左移动的地面和在指定范围内飞行的小鸟,并实现单击开始游戏。首先计算地面图片和开始图片位置,定义小鸟相关变量,创建时钟对象,然后开始无限循环。循环中,首先,解析资源元组(即加载资源的返回值),将元素分别赋给对应的变量;其次,获取事件并遍历,如果为退出事件,则关闭窗口,如果为单击事件,则返回小鸟位置和索引、地面位置,并退出循环;接着,播放飞行音效,每循环5次通过iterator(迭代器)的next()方法切换小鸟图片,并模拟小鸟在指定范围内上下飞行;然后,重新计算小鸟和地面位置,并绘制背景、开始图片、地面和小鸟;最后,刷新绘图,以及设置时钟的时间间隔。实现代码如下。创建游戏包3.41.创建游戏开始模块import pygame, sysimport itertoolsimport cfg'''显示开始界面'''def startGame(screen, resource):'''将resource的元素分别赋给sounds、bird_images、other_images、backgroud_image'''sounds = resource[0]bird_images = resource[2]other_images = resource[3]backgroud_image = resource[4]base_pos = [0, cfg.SCREENHEIGHT*0.93] #计算地面位置创建游戏包3.41.创建游戏开始模块#计算地面和背景的宽度差base_diff_bg = (other_images['base'].get_width()- backgroud_image.get_width())#计算开始图片位置x = (cfg.SCREENWIDTH - other_images['gamestart'].get_width()) / 2y = cfg.SCREENHEIGHT * 0.12msg_pos = [x, y]bird_id = 0 #定义小鸟图片索引bird_id_change_count = 0 #定义切换小鸟形态计数#定义迭代器,包含一个小鸟飞行周期内图片索引取值bird_id_cycle = itertools.cycle([0, 1, 2, 1])创建游戏包3.41.创建游戏开始模块#计算小鸟位置x = cfg.SCREENWIDTH * 0.2y=(cfg.SCREENHEIGHT-list(bird_images.values())[0].get_height())/2bird_pos = [x, y]bird_y_shift_count = 0 #定义y坐标偏移计数bird_y_shift_max = 16 #定义y坐标最大偏移计数shift = 1 #定义y坐标偏移量clock = pygame.time.Clock() #创建时钟创建游戏包3.41.创建游戏开始模块while True: #无限循环for event in pygame.event.get(): #获取事件并遍历if event.type == pygame.QUIT: #如果为退出事件pygame.quit() #退出pygamesys.exit() #退出系统#如果为单击事件elif event.type == pygame.MOUSEBUTTONDOWN:#返回小鸟位置、地面位置和小鸟图片索引return {'bird_pos':bird_pos,'base_pos':base_pos,'bird_id': bird_id}sounds['wing'].play() #播放小鸟飞行音效bird_id_change_count += 1 #切换形态计数加1创建游戏包3.41.创建游戏开始模块#如果切换形态计数是5的倍数,切换小鸟图片if bird_id_change_count % 5 == 0:bird_id = next(bird_id_cycle)bird_y_shift_count += 1 #y坐标偏移计数加1#如果y坐标偏移计数等于最大值if bird_y_shift_count == bird_y_shift_max:shift = -1 * shift #y坐标偏移取反bird_y_shift_count = 0 #y坐标偏移计数赋0#计算地面x坐标,左移4像素#除以base_diff_bg求余为了保证地面图片的连续base_pos[0] = -((-base_pos[0] + 4) % base_diff_bg)bird_pos[1] = bird_pos[1] + shift #计算小鸟y坐标screen.blit(backgroud_image, (0, 0)) #绘制背景图片创建游戏包3.41.创建游戏开始模块#绘制小鸟图片screen.blit(list(bird_images.values())[bird_id], bird_pos)#绘制开始图片screen.blit(other_images['gamestart'], msg_pos)#绘制地面图片screen.blit(other_images['base'], base_pos)pygame.display.update() #刷新绘图clock.tick(cfg.FPS) #设置时钟的时间间隔创建游戏包3.42.创建游戏进行模块在game_package包中创建游戏进行模块run_game.py,在其中定义runGame()函数实现游戏中的操作。首先,创建管道精灵组,循环两次,计算每组上下管道的初始位置,并添加到组中,以及创建小鸟精灵;然后,进入循环,循环标志为True;最后,调用函数显示结束界面。循环中执行如下操作。(1)解析资源元组,将元素分别赋给对应的变量。(2)获取事件并遍历,如果为退出事件,则关闭窗口;如果为单击事件,则调用Bird的setFlapped()方法,并播放飞行音效。(3)将小鸟精灵和管道精灵组进行碰撞检测,如果碰撞,则设置循环标志为False,并播放碰撞音效。创建游戏包3.42.创建游戏进行模块(4)更新小鸟,判断小鸟是否碰撞上下界限而死亡,如果死亡,则设置循环标志为False,并播放碰撞音效。(5)向左移动管道和地面模拟小鸟向前飞(确保两者移动速度一致),如果管道右侧位置小于小鸟右侧位置,且得分标志为False,得分加0.5(由于管道分为上、下两个管道,通过一组管道会判断两次,所以两次得分相加为1),并将得分标志设为True;如果管道左侧位置小于5大于0,且添加管道标志为True,则在管道精灵组中添加一个管道;如果管道右侧位置小于0,则从管道精灵组中移除管道。(6)绘制图形,刷新绘图,设置时钟的时间间隔。创建游戏包3.42.创建游戏进行模块#导入模块from class_package.pipe import Pipefrom class_package.bird import Birdimport cfgimport pygame, sys'''进入游戏'''def runGame(screen, resource, game_start_info, showScore):'''将resource的元素分别赋给sounds、pipe_images、bird_images、other_images、backgroud_image'''sounds = resource[0]pipe_images = resource[1]bird_images = resource[2]other_images = resource[3]backgroud_image = resource[4]score = 0 #定义得分,初值赋为0创建游戏包3.42.创建游戏进行模块#获取游戏开始界面的信息,包括小鸟位置、地面位置和小鸟图片索引bird_pos,base_pos,bird_id=list(game_start_info.values())base_diff_bg = (other_images['base'].get_width()- backgroud_image.get_width())clock = pygame.time.Clock() #创建时钟pipe_sprites = pygame.sprite.Group() #创建管道精灵组for i in range(2): #循环两次pipe_pos = Pipe.randomPipe(cfg, pipe_images.get('top')) #随机生成管道位置#计算上管道位置,并将管道对象添加到精灵组中pipe_pos_top = (cfg.SCREENWIDTH + i * cfg.SCREENWIDTH / 2,pipe_pos.get('top')[1])pipe_sprites.add(Pipe(pipe_images.get('top'),pipe_pos_top))#计算下管道位置,并将管道对象添加到精灵组中pipe_pos_bottom=(cfg.SCREENWIDTH + i * cfg.SCREENWIDTH / 2,pipe_pos.get('bottom')[1])pipe_sprites.add(Pipe(pipe_images.get('bottom'),pipe_pos_bottom))创建游戏包3.42.创建游戏进行模块#创建小鸟精灵bird = Bird(bird_images, bird_id, bird_pos)is_add_pipe = True #定义添加管道标志,赋初值为Trueis_game_running = True #定义游戏进行标志,赋初值为Truewhile is_game_running: #循环,直到游戏标志为Falsefor event in pygame.event.get(): #获取事件并遍历if event.type == pygame.QUIT: #如果为退出事件pygame.quit() #退出pygamesys.exit() #退出系统#如果为单击事件elif event.type == pygame.MOUSEBUTTONDOWN:bird.setFlapped() #调用Bird的setFlapped()方法sounds['wing'].play() #播放飞行音效创建游戏包3.42.创建游戏进行模块'''碰撞检测'''for pipe in pipe_sprites: #遍历管道精灵组#如果小鸟精灵和管道精灵组的任一精灵碰撞if pygame.sprite.collide_mask(bird, pipe):is_game_running = False #游戏进行标志设为Falsesounds['hit'].play() #播放碰撞音效return score, bird, pipe_sprites, base_pos'''更新小鸟,判断小鸟是否死亡'''boundary = [0, base_pos[1]] #定义上下界限#更新小鸟位置和状态,返回死亡标志is_dead=bird.update(boundary,float(clock.tick(cfg.FPS))/1000)if is_dead: #如果小鸟死亡is_game_running = False #游戏进行标志设为Falsesounds['hit'].play() #播放碰撞音效return score, bird, pipe_sprites, base_pos创建游戏包3.42.创建游戏进行模块#计算地面x坐标base_pos[0] = -((-base_pos[0] + 4) % base_diff_bg)'''移动管道,模拟小鸟向前飞,并判断是否从管道精灵组添加和移除管道、以及计算得分'''for pipe in pipe_sprites:pipe.rect.left -= 4 #管道左移4像素#如果管道右侧位置小于小鸟右侧位置(穿过管道),且得分标志为Falseif (pipe.rect.right < bird.rect.rightand not pipe.used_for_score):pipe.used_for_score = True #得分标志设为Truescore += 0.5 #统计得分sounds['point'].play() #播放得分音效创建游戏包3.42.创建游戏进行模块#如果管道左侧位置小于5大于0,且添加管道标志为Trueif (pipe.rect.left < 5 and pipe.rect.left > 0and is_add_pipe):#随机生成管道位置,且将上下管道添加到精灵组中pipe_pos = Pipe.randomPipe(cfg, pipe_images.get('top'))pipe_sprites.add(Pipe(pipe_images.get('top'),pipe_pos.get('top')))pipe_sprites.add(Pipe(pipe_images.get('bottom'),pipe_pos.get('bottom')))is_add_pipe = False #添加管道标志设为Falseelif pipe.rect.right < 0: #如果管道右侧位置小于0pipe_sprites.remove(pipe) #从管道精灵组中移除管道is_add_pipe = True #添加管道标志设为True创建游戏包3.42.创建游戏进行模块screen.blit(backgroud_image, (0, 0)) #绘制背景pipe_sprites.draw(screen) #绘制管道screen.blit(other_images['base'], base_pos) #绘制地面showScore(screen, score) #显示得分bird.draw(screen) #绘制小鸟pygame.display.update() #刷新绘图clock.tick(cfg.FPS) #设置时钟的时间间隔创建游戏包3.43.创建游戏结束模块在game_package包中创建游戏结束模块end_game.py,在其中定义endGame()函数显示结束界面,包括背景、结束图片、地面和下落到地面的小鸟,并实现单击返回开始界面。首先播放死亡音效和创建时钟对象,然后开始循环。在循环中,首先,解析资源元组,将元素分别赋给对应的变量;其次,获取事件并遍历,如果为退出事件,则关闭窗口,如果为单击事件,则退出循环;然后,重新绘制背景、地面、管道,调用showScore()方法显示得分,并设置小鸟飞行的上下界限,调用Bird类的update()和draw()方法更新和绘制小鸟;最后,刷新绘图,以及设置时钟的时间间隔。实现代码如下。创建游戏包3.43.创建游戏结束模块import pygame, sysimport cfg'''显示游戏结束界面'''def endGame(screen,resource,showScore,score,bird,pipe_sprites,base_pos):'''将resource的元素分别赋给sounds、other_images、backgroud_image'''sounds = resource[0]other_images = resource[3]backgroud_image = resource[4]sounds['die'].play() #播放死亡音效clock = pygame.time.Clock() #创建时钟创建游戏包3.43.创建游戏结束模块while True:for event in pygame.event.get(): #获取事件并遍历if event.type == pygame.QUIT: #如果为退出事件pygame.quit() #退出pygamesys.exit() #退出系统#如果为单击事件elif event.type == pygame.MOUSEBUTTONDOWN:return #返回None,退出循环screen.blit(backgroud_image, (0, 0)) #绘制背景pipe_sprites.draw(screen) #绘制管道screen.blit(other_images['base'], base_pos) #绘制地面创建游戏包3.43.创建游戏结束模块#计算结束图片位置x=(cfg.SCREENWIDTH-other_images['gamestart'].get_width())/2y = cfg.SCREENHEIGHT * 0.4msg_pos = [x, y]#绘制结束图片screen.blit(other_images['gameover'], msg_pos)showScore(screen, score) #显示得分boundary = [0, base_pos[1]] #定义上下界限#更新小鸟bird.update(boundary,float(clock.tick(cfg.FPS))/1000)bird.draw(screen) #绘制小鸟pygame.display.update() #刷新绘图clock.tick(cfg.FPS) #设置时钟的时间间隔创建主模块3.51.导入模块主模块中会调用其他模块中的类和函数,因此,须首先导入相关模块。#导入模块from game_package.run_game import *from game_package.start_game import *from game_package.end_game import *import pygame创建主模块3.52.定义初始化游戏函数定义initGame()函数初始化pygame和pygame.mixer,设置窗口大小和标题,并返回窗口对象,实现代码如下。'''游戏初始化'''def initGame():pygame.init() #初始化pygamepygame.mixer.init() #初始化pygame.mixer#设置窗口大小screen=pygame.display.set_mode((cfg.SCREENWIDTH,cfg.SCREENHEIGHT))pygame.display.set_caption('Flappy Bird') #设置窗口标题return screen #返回screen创建主模块3.53.定义加载资源函数定义loadResource()函数加载图片和声音资源,将声音、管道、小鸟和其他图片保存在字典中,背景图片保存在变量中,并返回字典和变量,实现代码如下。'''加载游戏资源'''def loadResource():sounds = dict() #定义声音字典#遍历声音路径字典,加载声音,并保存在声音字典中for key, value in cfg.AUDIO_PATHS.items():sounds[key] = pygame.mixer.Sound(value)pipe_images = dict() #定义管道图片字典#加载下管道图片并添加到字典中pipe_images['bottom'] = pygame.image.load(cfg.PIPE_IMAGE_PATHS)创建主模块3.53.定义加载资源函数#将下管道图片旋转180度作为上管道图片,并添加到字典中pipe_images['top'] = pygame.transform.rotate(pipe_images['bottom'], 180)bird_images = dict() #定义小鸟图片字典#遍历小鸟图片路径字典,加载小鸟图片,并保存在小鸟图片字典中for key, value in cfg.BIRD_IMAGE_PATHS.items():bird_images[key] = pygame.image.load(value)#加载背景图片,并保存到变量中backgroud_image = pygame.image.load(cfg.BACKGROUND_IMAGE_PATHS)other_images = dict() #定义其他图片字典,保存开始、结束、地面图片#遍历其他图片路径字典,加载其他图片,并保存在其他图片字典中for key, value in cfg.OTHER_IMAGE_PATHS.items():other_images[key] = pygame.image.load(value)#返回字典和变量return sounds,pipe_images,bird_images,other_images,backgroud_image创建主模块3.54.定义显示得分函数定义showScore()函数显示得分,在该函数中首先加载字体文件,然后配置显示的文字,最后获取文字对象的rect,并设置对象的中心坐标后,绘制文字,实现代码如下。'''显示得分'''def showScore(screen, score):#通过字体文件获得字体对象font = pygame.font.Font(cfg.FONT_PATHS, 25)#配置显示的文字textSurface=font.render('得分:{}'.format(int(score)),True,(255,0,0))textRect = textSurface.get_rect() #获取文字对象的rect#设置文字对象的中心坐标textRect.center = (screen.get_width()/2, 20)screen.blit(textSurface, textRect) #绘制文字创建主模块3.55.定义主函数定义main()函数,在其中调用初始化游戏、加载资源、显示开始界面、进行游戏和显示结束界面等函数,完成一次游戏,实现代码如下。'''主函数'''def main():screen = initGame() #初始化游戏#加载游戏资源,并将返回值赋给resourceresource = loadResource()#显示游戏开始界面game_start_info = startGame(screen, resource)#进行游戏score, bird, pipe_sprites, base_pos = runGame(screen, resource, game_start_info, showScore)#显示游戏结束界面endGame(screen, resource, showScore, score, bird, pipe_sprites, base_pos)创建主模块3.56.运行程序循环调用主函数运行程序,实现代码如下。while True:main()游戏开始界面、运行界面和结束界面如图11-2所示。图11-2 Flappy Bird游戏界面感谢观看 展开更多...... 收起↑ 资源预览