基于Python制作flappybird游戲的詳細(xì)步驟
導(dǎo)語
因?yàn)橐咔闊o奈只能在家宅了好多天,隨手玩了下自己以前做的一些小游戲,說真的,有幾個(gè)游戲做的是真的劣質(zhì),譬如 flappybird 真的讓我難以忍受,于是重做了一波分享給大家~
開發(fā)工具
**Python****版本:**3.6.4
相關(guān)模塊:
pygame 模塊;
以及一些 python 自帶的模塊
環(huán)境搭建
安裝 Python 并添加到環(huán)境變量,pip 安裝需要的相關(guān)模塊即可。
先睹為快
在 cmd 窗口運(yùn)行如下命令即可:
python Game6.py

原理簡(jiǎn)介
因?yàn)槭侵貙懙模跃椭匦陆榻B一下實(shí)現(xiàn)原理唄。
首先,我們來寫個(gè)開始界面,讓他看起來更像個(gè)游戲一些。效果大概是這樣的:

原理也簡(jiǎn)單,關(guān)鍵點(diǎn)有三個(gè):(1)下方深綠淺綠交替的地板不斷往左移動(dòng)來制造小鳥向前飛行的假象;(2)每過幾幀切換一下小鳥的圖片來實(shí)現(xiàn)小鳥翅膀扇動(dòng)的效果:

(3)有規(guī)律地改變小鳥豎直方向上的位置來實(shí)現(xiàn)上下移動(dòng)的效果。
具體而言,代碼實(shí)現(xiàn)如下:
'''顯示開始界面'''
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)行了必要的初始化工作之后,在游戲開始界面中實(shí)現(xiàn)的內(nèi)容的基礎(chǔ)上,主要還需要實(shí)現(xiàn)的內(nèi)容有以下幾個(gè)部分:
(1) 管道和深綠淺綠交替的地板不斷往左移來實(shí)現(xiàn)小鳥向前飛行的效果;
(2) 按鍵檢測(cè),當(dāng)玩家點(diǎn)擊空格鍵或者 ↑ 鍵時(shí),小鳥向上做加速度向下的均減速直線運(yùn)動(dòng)直至向上的速度衰減為 0,否則小鳥做自由落體運(yùn)動(dòng)(實(shí)現(xiàn)時(shí)為了方便,可以認(rèn)為在極短的時(shí)間段內(nèi)小鳥的運(yùn)動(dòng)方式為勻速直線運(yùn)動(dòng));
(3) 碰撞檢測(cè),當(dāng)小鳥與管道/游戲邊界碰撞到時(shí),游戲失敗并進(jìn)入游戲結(jié)束界面。注意,為了碰撞檢測(cè)更精確,我們使用:
pygame.sprite.collide_mask
來代替之前的:
pygame.sprite.collide_rect
(4) 進(jìn)入游戲后,隨機(jī)產(chǎn)生兩對(duì)管道,并不斷左移,當(dāng)最左邊的管道快要因?yàn)榈竭_(dá)游戲界面的左邊界而消失時(shí),重新生成一對(duì)管道(注意不要重復(fù)生成);
(5) 當(dāng)小鳥穿越一個(gè)上下管道之間的缺口時(shí),游戲得分加一(注意不要重復(fù)記分)。
這里簡(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
# --更新小鳥
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)小鳥往前飛的效果
base_pos[0] = -((-base_pos[0] + 4) % base_diff_bg)
# --移動(dòng)pipe實(shí)現(xiàn)小鳥往前飛的效果
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é)束后,進(jìn)入游戲界面。沒找到對(duì)應(yīng)的游戲素材,所以只是讓游戲界面靜止了,然后小鳥做自由落體運(yùn)行直到掉到地面上。代碼實(shí)現(xiàn)如下:
'''游戲結(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)再點(diǎn)擊一下空格鍵或者 ↑ 鍵即可重新開始游戲。
All done 完整源代碼詳見相關(guān)文件
se_pos) showScore(screen, score, number_images) bird.draw(screen) pygame.display.update() clock.tick(cfg.FPS)
再點(diǎn)擊一下空格鍵或者 ↑ 鍵即可重新開始游戲。
總結(jié)
到此這篇關(guān)于基于Python制作flappybird游戲的文章就介紹到這了,更多相關(guān)Python制作flappybird游戲內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
tensorflow模型的save與restore,及checkpoint中讀取變量方式
這篇文章主要介紹了tensorflow模型的save與restore,及checkpoint中讀取變量方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-05-05
微信公眾號(hào)腳本-獲取熱搜自動(dòng)新建草稿并發(fā)布文章
本來想寫一個(gè)自動(dòng)化發(fā)布微信公眾號(hào)的小綠書的腳本,但是微信公眾號(hào)官網(wǎng)沒有小綠書的接口,那就寫一個(gè)獲取熱搜微信普通文章的腳本吧,這篇文章主要介紹了微信公眾號(hào)腳本-獲取熱搜自動(dòng)新建草稿并發(fā)布文章2025-04-04
PyCharm MySQL可視化Database配置過程圖解
這篇文章主要介紹了PyCharm MySQL可視化Database配置過程圖解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
python在命令行中使用?pdb?實(shí)現(xiàn)斷點(diǎn)調(diào)試功能
在命令行中設(shè)置斷點(diǎn)通常需要使用調(diào)試工具來實(shí)現(xiàn),下面以 Python 為例介紹如何在命令行中使用pdb實(shí)現(xiàn)斷點(diǎn)調(diào)試,這篇文章主要介紹了python在命令行中使用pdb實(shí)現(xiàn)斷點(diǎn)調(diào)試,需要的朋友可以參考下2023-06-06
Pytorch DataLoader 變長(zhǎng)數(shù)據(jù)處理方式
今天小編就為大家分享一篇Pytorch DataLoader 變長(zhǎng)數(shù)據(jù)處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-01-01
Python使用PIL庫將PNG圖片轉(zhuǎn)換為ICO圖標(biāo)的示例代碼
在軟件開發(fā)和網(wǎng)站設(shè)計(jì)中,ICO圖標(biāo)是一種常用的圖像格式,特別適用于應(yīng)用程序圖標(biāo)、網(wǎng)頁收藏夾圖標(biāo)等場(chǎng)景,本文將介紹如何使用Python的PIL庫將PNG圖片轉(zhuǎn)換為ICO格式的圖標(biāo)文件,需要的朋友可以參考下2025-03-03

