python?flappy?bird小游戲分步實(shí)現(xiàn)流程
導(dǎo)語(yǔ):
哈嘍,哈嘍~今天小編又來(lái)分享小游戲了——flappy bird(飛揚(yáng)的小鳥(niǎo)),這個(gè)游戲非常的經(jīng)典,游戲中玩家必須控制一只小鳥(niǎo),跨越由各種不同長(zhǎng)度水管所組成的障礙。這個(gè)游戲能對(duì)于小編來(lái)說(shuō)還是有點(diǎn)難度的。
開(kāi)發(fā)工具:
Python版本:3.6.4
相關(guān)模塊:
pygame模塊;
以及一些python自帶的模塊。
環(huán)境搭建
安裝Python并添加到環(huán)境變量,pip安裝需要的相關(guān)模塊即可。
運(yùn)行視頻:
播放鏈接:https://live.csdn.net/v/embed/184490
正文:
首先,我們來(lái)寫(xiě)個(gè)開(kāi)始界面,讓他看起來(lái)更像個(gè)游戲一些。效果大概是這樣的:
原理也簡(jiǎn)單,關(guān)鍵點(diǎn)有三個(gè):
(1)下方深綠淺綠交替的地板不斷往左移動(dòng)來(lái)制造小鳥(niǎo)向前飛行的假象;
(2)每過(guò)幾幀切換一下小鳥(niǎo)的圖片來(lái)實(shí)現(xiàn)小鳥(niǎo)翅膀扇動(dòng)的效果:
(3)有規(guī)律地改變小鳥(niǎo)豎直方向上的位置來(lái)實(shí)現(xiàn)上下移動(dòng)的效果。
具體而言,代碼實(shí)現(xiàn)如下:
'''顯示開(kāi)始界面''' def startGame(screen, sounds, bird_images, other_images, backgroud_image, cfg): base_pos = [0, cfg.SCREENHEIGHT*0.79] base_diff_bg = other_images['base'].get_width() - backgroud_image.get_width() msg_pos = [(cfg.SCREENWIDTH-other_images['message'].get_width())/2, cfg.SCREENHEIGHT*0.12] bird_idx = 0 bird_idx_change_count = 0 bird_idx_cycle = itertools.cycle([0, 1, 2, 1]) bird_pos = [cfg.SCREENWIDTH*0.2, (cfg.SCREENHEIGHT-list(bird_images.values())[0].get_height())/2] bird_y_shift_count = 0 bird_y_shift_max = 9 shift = 1 clock = pygame.time.Clock() while True: for event in pygame.event.get(): if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE): pygame.quit() sys.exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE or event.key == pygame.K_UP: return {'bird_pos': bird_pos, 'base_pos': base_pos, 'bird_idx': bird_idx} sounds['wing'].play() bird_idx_change_count += 1 if bird_idx_change_count % 5 == 0: bird_idx = next(bird_idx_cycle) bird_idx_change_count = 0 base_pos[0] = -((-base_pos[0] + 4) % base_diff_bg) bird_y_shift_count += 1 if bird_y_shift_count == bird_y_shift_max: bird_y_shift_max = 16 shift = -1 * shift bird_y_shift_count = 0 bird_pos[-1] = bird_pos[-1] + shift screen.blit(backgroud_image, (0, 0)) screen.blit(list(bird_images.values())[bird_idx], bird_pos) screen.blit(other_images['message'], msg_pos) screen.blit(other_images['base'], base_pos) pygame.display.update() clock.tick(cfg.FPS)
點(diǎn)擊空格鍵或者↑鍵進(jìn)入主程序。對(duì)于主程序,在進(jìn)行了必要的初始化工作之后,在游戲開(kāi)始界面中實(shí)現(xiàn)的內(nèi)容的基礎(chǔ)上,主要還需要實(shí)現(xiàn)的內(nèi)容有以下幾個(gè)部分:
(1) 管道和深綠淺綠交替的地板不斷往左移來(lái)實(shí)現(xiàn)小鳥(niǎo)向前飛行的效果;
(2) 按鍵檢測(cè),當(dāng)玩家點(diǎn)擊空格鍵或者↑鍵時(shí),小鳥(niǎo)向上做加速度向下的均減速直線運(yùn)動(dòng)直至向上的速度衰減為0,否則小鳥(niǎo)做自由落體運(yùn)動(dòng)(實(shí)現(xiàn)時(shí)為了方便,可以認(rèn)為在極短的時(shí)間段內(nèi)小鳥(niǎo)的運(yùn)動(dòng)方式為勻速直線運(yùn)動(dòng));
(3) 碰撞檢測(cè),當(dāng)小鳥(niǎo)與管道/游戲邊界碰撞到時(shí),游戲失敗并進(jìn)入游戲結(jié)束界面。注意,為了碰撞檢測(cè)更精確,我們使用:
pygame.sprite.collide_mask
管道:
(4) 進(jìn)入游戲后,隨機(jī)產(chǎn)生兩對(duì)管道,并不斷左移,當(dāng)最左邊的管道快要因?yàn)榈竭_(dá)游戲界面的左邊界而消失時(shí),重新生成一對(duì)管道(注意不要重復(fù)生成);
(5) 當(dāng)小鳥(niǎo)穿越一個(gè)上下管道之間的缺口時(shí),游戲得分加一(注意不要重復(fù)記分)。
計(jì)分表
這里簡(jiǎn)單貼下主程序的源代碼吧:
# 進(jìn)入主游戲 score = 0 bird_pos, base_pos, bird_idx = 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_sprites.add(Pipe(image=pipe_images.get('top'), position=(cfg.SCREENWIDTH+200+i*cfg.SCREENWIDTH/2, pipe_pos.get('top')[-1]))) pipe_sprites.add(Pipe(image=pipe_images.get('bottom'), position=(cfg.SCREENWIDTH+200+i*cfg.SCREENWIDTH/2, pipe_pos.get('bottom')[-1]))) # --bird類 bird = Bird(images=bird_images, idx=bird_idx, position=bird_pos) # --是否增加pipe is_add_pipe = True # --游戲是否進(jìn)行中 is_game_running = True while is_game_running: for event in pygame.event.get(): if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE): pygame.quit() sys.exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE or event.key == pygame.K_UP: bird.setFlapped() sounds['wing'].play() # --碰撞檢測(cè) for pipe in pipe_sprites: if pygame.sprite.collide_mask(bird, pipe): sounds['hit'].play() is_game_running = False # --更新小鳥(niǎo) boundary_values = [0, base_pos[-1]] is_dead = bird.update(boundary_values, float(clock.tick(cfg.FPS))/1000.) if is_dead: sounds['hit'].play() is_game_running = False # --移動(dòng)base實(shí)現(xiàn)小鳥(niǎo)往前飛的效果 base_pos[0] = -((-base_pos[0] + 4) % base_diff_bg) # --移動(dòng)pipe實(shí)現(xiàn)小鳥(niǎo)往前飛的效果 flag = False for pipe in pipe_sprites: pipe.rect.left -= 4 if pipe.rect.centerx < bird.rect.centerx and not pipe.used_for_score: pipe.used_for_score = True score += 0.5 if '.5' in str(score): sounds['point'].play() if pipe.rect.left < 5 and pipe.rect.left > 0 and is_add_pipe: pipe_pos = Pipe.randomPipe(cfg, pipe_images.get('top')) pipe_sprites.add(Pipe(image=pipe_images.get('top'), position=pipe_pos.get('top'))) pipe_sprites.add(Pipe(image=pipe_images.get('bottom'), position=pipe_pos.get('bottom'))) is_add_pipe = False elif pipe.rect.right < 0: pipe_sprites.remove(pipe) flag = True if flag: is_add_pipe = True # --綁定必要的元素在屏幕上 screen.blit(backgroud_image, (0, 0)) pipe_sprites.draw(screen) screen.blit(other_images['base'], base_pos) showScore(screen, score, number_images) bird.draw(screen) pygame.display.update() clock.tick(cfg.FPS)
游戲結(jié)束
假如我們的主角真的一個(gè)不小心如我們所料的撞死在了鋼管上(往上翻,就在游戲開(kāi)始那里),那就表示gameOver();
'''游戲結(jié)束界面''' def endGame(screen, sounds, showScore, score, number_images, bird, pipe_sprites, backgroud_image, other_images, base_pos, cfg): sounds['die'].play() clock = pygame.time.Clock() while True: for event in pygame.event.get(): if event.type == pygame.QUIT or (event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE): pygame.quit() sys.exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE or event.key == pygame.K_UP: return boundary_values = [0, base_pos[-1]] bird.update(boundary_values, float(clock.tick(cfg.FPS))/1000.) screen.blit(backgroud_image, (0, 0)) pipe_sprites.draw(screen) screen.blit(other_images['base'], base_pos) showScore(screen, score, number_images) bird.draw(screen) pygame.display.update() clock.tick(cfg.FPS)
結(jié)尾:
這期游戲分享就到這結(jié)束啦喜歡的友友們動(dòng)手試試看哦!家人們的支持是小編更新最大的動(dòng)力
到此這篇關(guān)于python flappy bird小游戲分布實(shí)現(xiàn)流程的文章就介紹到這了,更多相關(guān)python flappy bird內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用Python將Mysql的查詢數(shù)據(jù)導(dǎo)出到文件的方法
今天小編就為大家分享一篇關(guān)于使用Python將Mysql的查詢數(shù)據(jù)導(dǎo)出到文件的方法,小編覺(jué)得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來(lái)看看吧2019-02-02python利用百度云接口實(shí)現(xiàn)車牌識(shí)別的示例
這篇文章主要介紹了python利用百度云接口實(shí)現(xiàn)車牌識(shí)別的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-02-02Python實(shí)現(xiàn)刪除排序數(shù)組中重復(fù)項(xiàng)的兩種方法示例
這篇文章主要介紹了Python實(shí)現(xiàn)刪除排序數(shù)組中重復(fù)項(xiàng)的兩種方法,涉及Python數(shù)組元素的遍歷、判斷、刪除等相關(guān)操作技巧,需要的朋友可以參考下2019-01-01詳解使用Python寫(xiě)一個(gè)向數(shù)據(jù)庫(kù)填充數(shù)據(jù)的小工具(推薦)
這篇文章主要介紹了用Python寫(xiě)一個(gè)向數(shù)據(jù)庫(kù)填充數(shù)據(jù)的小工具,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09Python數(shù)據(jù)結(jié)構(gòu)與算法中的隊(duì)列詳解(2)
這篇文章主要為大家詳細(xì)介紹了Python中的隊(duì)列,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來(lái)幫助2022-03-03一個(gè)Python優(yōu)雅的數(shù)據(jù)分塊方法詳解
在做需求過(guò)程中有一個(gè)對(duì)大量數(shù)據(jù)分塊處理的場(chǎng)景,具體來(lái)說(shuō)就是幾十萬(wàn)量級(jí)的數(shù)據(jù),分批處理,每次處理100個(gè)。這時(shí)就需要一個(gè)分塊功能的代碼。本文為大家分享了一個(gè)Python中優(yōu)雅的數(shù)據(jù)分塊方法,需要的可以參考一下2022-05-05Python try-except-else-finally的具體使用
本文主要介紹了Python try-except-else-finally的具體使用,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-08-08